Chore/React18: Remove enzyme slate tests and replace with e2e tests (#57095)

fix-alerting-relref
kay delaney 3 years ago committed by GitHub
parent c96b6a6ab0
commit ed71b7b884
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      .betterer.results
  2. 106
      e2e/various-suite/slate.spec.ts
  3. 58
      packages/grafana-ui/src/slate-plugins/braces.test.tsx
  4. 44
      packages/grafana-ui/src/slate-plugins/clear.test.tsx
  5. 25
      packages/grafana-ui/src/slate-plugins/runner.test.tsx
  6. 159
      packages/grafana-ui/src/slate-plugins/suggestions.test.tsx

@ -8,18 +8,6 @@ exports[`no enzyme tests`] = {
"packages/grafana-ui/src/components/QueryField/QueryField.test.tsx:2976628669": [
[0, 26, 13, "RegExp match", "2409514259"]
],
"packages/grafana-ui/src/slate-plugins/braces.test.tsx:823049948": [
[0, 19, 13, "RegExp match", "2409514259"]
],
"packages/grafana-ui/src/slate-plugins/clear.test.tsx:3927593033": [
[0, 19, 13, "RegExp match", "2409514259"]
],
"packages/grafana-ui/src/slate-plugins/runner.test.tsx:1123710822": [
[0, 19, 13, "RegExp match", "2409514259"]
],
"packages/grafana-ui/src/slate-plugins/suggestions.test.tsx:2682912140": [
[0, 18, 13, "RegExp match", "2409514259"]
],
"packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js:1676554632": [
[14, 19, 13, "RegExp match", "2409514259"]
],
@ -1688,27 +1676,10 @@ exports[`better eslint`] = {
"packages/grafana-ui/src/options/builder/stacking.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-ui/src/slate-plugins/braces.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"]
],
"packages/grafana-ui/src/slate-plugins/braces.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"packages/grafana-ui/src/slate-plugins/clear.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"packages/grafana-ui/src/slate-plugins/runner.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-ui/src/slate-plugins/slate-prism/index.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@ -1719,14 +1690,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"packages/grafana-ui/src/slate-plugins/suggestions.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
],
"packages/grafana-ui/src/slate-plugins/suggestions.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],

@ -0,0 +1,106 @@
import { e2e } from '@grafana/e2e';
const dataSourceName = 'LokiSlate';
const addDataSource = () => {
e2e.flows.addDataSource({
type: 'Loki',
expectedAlertMessage:
'Unable to fetch labels from Loki (Failed to call resource), please check the server logs for more details',
name: dataSourceName,
form: () => {
e2e.components.DataSource.DataSourceHttpSettings.urlInput().type('http://loki-url:3100');
},
});
};
describe('Loki slate editor', () => {
beforeEach(() => {
e2e.flows.login('admin', 'admin');
e2e()
.request({ url: `${e2e.env('BASE_URL')}/api/datasources/name/${dataSourceName}`, failOnStatusCode: false })
.then((response) => {
if (response.isOkStatusCode) {
return;
}
addDataSource();
});
});
it('Braces plugin should insert closing brace', () => {
e2e().intercept(/labels?/, (req) => {
req.reply({ status: 'success', data: ['instance', 'job', 'source'] });
});
e2e().intercept(/series?/, (req) => {
req.reply({ status: 'success', data: [{ instance: 'instance1' }] });
});
// Go to Explore and choose Loki data source
e2e.pages.Explore.visit();
e2e.components.DataSourcePicker.container().should('be.visible').click();
e2e().contains(dataSourceName).scrollIntoView().should('be.visible').click();
// adds closing braces around empty value
e2e().contains('Code').click();
const queryField = e2e().get('.slate-query-field');
queryField.type('time(');
queryField.then(($el) => {
expect($el.text().replace(/\uFEFF/g, '')).to.eq('time()');
});
// removes closing brace when opening brace is removed
queryField.type('{backspace}');
queryField.then(($el) => {
expect($el.text().replace(/\uFEFF/g, '')).to.eq('time');
});
// keeps closing brace when opening brace is removed and inner values exist
queryField.type(`{selectall}{backspace}time(test{leftArrow}{leftArrow}{leftArrow}{leftArrow}{backspace}`);
queryField.then(($el) => {
expect($el.text().replace(/\uFEFF/g, '')).to.eq('timetest)');
});
// overrides an automatically inserted brace
queryField.type(`{selectall}{backspace}time()`);
queryField.then(($el) => {
expect($el.text().replace(/\uFEFF/g, '')).to.eq('time()');
});
// does not override manually inserted braces
queryField.type(`{selectall}{backspace}))`);
queryField.then(($el) => {
expect($el.text().replace(/\uFEFF/g, '')).to.eq('))');
});
/** Clear Plugin */
//does not change the empty value
queryField.type(`{selectall}{backspace}{ctrl+k}`);
queryField.then(($el) => {
expect($el.text().replace(/\uFEFF/g, '')).to.match(/Enter a Loki query/);
});
// clears to the end of the line
queryField.type(`{selectall}{backspace}foo{leftArrow}{leftArrow}{leftArrow}{ctrl+k}`);
queryField.then(($el) => {
expect($el.text().replace(/\uFEFF/g, '')).to.match(/Enter a Loki query/);
});
// clears from the middle to the end of the line
queryField.type(`{selectall}{backspace}foo bar{leftArrow}{leftArrow}{leftArrow}{leftArrow}{ctrl+k}`);
queryField.then(($el) => {
expect($el.text().replace(/\uFEFF/g, '')).to.eq('foo');
});
/** Runner plugin */
//should execute query when enter with shift is pressed
queryField.type(`{selectall}{backspace}{shift+enter}`);
e2e().get('[data-testid="explore-no-data"]').should('be.visible');
/** Suggestions plugin */
e2e().get('.slate-query-field').type(`{selectall}av`);
e2e().get('.slate-typeahead').should('be.visible').contains('avg_over_time');
});
});

@ -1,58 +0,0 @@
import { shallow } from 'enzyme';
import React from 'react';
import Plain from 'slate-plain-serializer';
import { Editor } from 'slate-react';
import { BracesPlugin } from './braces';
describe('braces', () => {
const handler = BracesPlugin().onKeyDown!;
const nextMock = () => {};
it('adds closing braces around empty value', () => {
const value = Plain.deserialize('');
const editor = shallow<Editor>(<Editor value={value} />);
const event = new window.KeyboardEvent('keydown', { key: '(' });
expect(handler(event as any, editor.instance(), nextMock)).toBeTruthy();
expect(Plain.serialize(editor.instance().value)).toEqual('()');
});
it('removes closing brace when opening brace is removed', () => {
const value = Plain.deserialize('time()');
const editor = shallow<Editor>(<Editor value={value} />);
const event = new window.KeyboardEvent('keydown', { key: 'Backspace' });
editor.instance().moveForward(5);
handler(event as any, editor.instance(), nextMock);
expect(Plain.serialize(editor.instance().value)).toEqual('time');
});
it('keeps closing brace when opening brace is removed and inner values exist', () => {
const value = Plain.deserialize('time(value)');
const editor = shallow<Editor>(<Editor value={value} />);
const event = new window.KeyboardEvent('keydown', { key: 'Backspace' });
editor.instance().moveForward(5);
const handled = handler(event as any, editor.instance(), nextMock);
expect(handled).toBeFalsy();
});
it('overrides an automatically inserted brace', () => {
const value = Plain.deserialize('');
const editor = shallow<Editor>(<Editor value={value} />);
const opening = new window.KeyboardEvent('keydown', { key: '(' });
expect(handler(opening as any, editor.instance(), nextMock)).toBeTruthy();
const closing = new window.KeyboardEvent('keydown', { key: ')' });
expect(handler(closing as any, editor.instance(), nextMock)).toBeTruthy();
expect(Plain.serialize(editor.instance().value)).toEqual('()');
});
it.skip('does not override manually inserted braces', () => {
const value = Plain.deserialize('');
const editor = shallow<Editor>(<Editor value={value} />);
const event1 = new window.KeyboardEvent('keydown', { key: ')' });
expect(handler(event1 as any, editor.instance(), nextMock)).toBeFalsy();
const event2 = new window.KeyboardEvent('keydown', { key: ')' });
editor.instance().moveBackward(1);
expect(handler(event2 as any, editor.instance(), nextMock)).toBeFalsy();
expect(Plain.serialize(editor.instance().value)).toEqual('))');
});
});

@ -1,44 +0,0 @@
import { shallow } from 'enzyme';
import React from 'react';
import Plain from 'slate-plain-serializer';
import { Editor } from 'slate-react';
import { ClearPlugin } from './clear';
describe('clear', () => {
const handler = ClearPlugin().onKeyDown!;
it('does not change the empty value', () => {
const value = Plain.deserialize('');
const editor = shallow<Editor>(<Editor value={value} />);
const event = new window.KeyboardEvent('keydown', {
key: 'k',
ctrlKey: true,
});
handler(event as any, editor.instance(), () => {});
expect(Plain.serialize(editor.instance().value)).toEqual('');
});
it('clears to the end of the line', () => {
const value = Plain.deserialize('foo');
const editor = shallow<Editor>(<Editor value={value} />);
const event = new window.KeyboardEvent('keydown', {
key: 'k',
ctrlKey: true,
});
handler(event as any, editor.instance(), () => {});
expect(Plain.serialize(editor.instance().value)).toEqual('');
});
it('clears from the middle to the end of the line', () => {
const value = Plain.deserialize('foo bar');
const editor = shallow<Editor>(<Editor value={value} />);
const event = new window.KeyboardEvent('keydown', {
key: 'k',
ctrlKey: true,
});
editor.instance().moveForward(4);
handler(event as any, editor.instance(), () => {});
expect(Plain.serialize(editor.instance().value)).toEqual('foo ');
});
});

@ -1,25 +0,0 @@
import { shallow } from 'enzyme';
import React from 'react';
import Plain from 'slate-plain-serializer';
import { Editor } from 'slate-react';
import { RunnerPlugin } from './runner';
describe('runner', () => {
const mockHandler = jest.fn();
const handler = RunnerPlugin({ handler: mockHandler }).onKeyDown!;
it('should execute query when enter with shift is pressed', () => {
const value = Plain.deserialize('');
const editor = shallow(<Editor value={value} />);
handler(
new window.KeyboardEvent('keydown', {
key: 'Enter',
shiftKey: true,
}) as any,
editor.instance() as Editor,
() => {}
);
expect(mockHandler).toBeCalled();
});
});

@ -1,159 +0,0 @@
import { render } from 'enzyme';
import _ from 'lodash'; // eslint-disable-line lodash/import-scope
import { Plugin as SlatePlugin } from 'slate-react';
import { CompletionItemGroup, SuggestionsState } from '../types';
import { SearchFunctionType } from '../utils';
import { SearchFunctionMap } from '../utils/searchFunctions';
import { SuggestionsPlugin } from './suggestions';
jest.spyOn(_, 'debounce').mockImplementation((func: (...args: any) => any) => {
return Object.assign(func, { cancel: jest.fn(), flush: jest.fn() });
});
jest.mock('../utils/searchFunctions', () => ({
// @ts-ignore
...jest.requireActual('../utils/searchFunctions'),
SearchFunctionMap: {
Prefix: jest.fn((items) => items),
Word: jest.fn((items) => items),
Fuzzy: jest.fn((items) => items),
},
}));
const TypeaheadMock = jest.fn(() => '');
jest.mock('../components/Typeahead/Typeahead', () => {
return {
Typeahead: (state: Partial<SuggestionsState>) => {
// @ts-ignore
TypeaheadMock(state);
return '';
},
};
});
describe('SuggestionsPlugin', () => {
let plugin: SlatePlugin, nextMock: any, suggestions: CompletionItemGroup[], editorMock: any, eventMock: any;
beforeEach(() => {
let onTypeahead = async () => {
return {
suggestions: suggestions,
};
};
(SearchFunctionMap.Prefix as jest.Mock).mockClear();
(SearchFunctionMap.Word as jest.Mock).mockClear();
(SearchFunctionMap.Fuzzy as jest.Mock).mockClear();
plugin = SuggestionsPlugin({ portalOrigin: '', onTypeahead });
nextMock = () => {};
editorMock = createEditorMock('foo');
eventMock = new window.KeyboardEvent('keydown', { key: 'a' });
});
async function triggerAutocomplete() {
await plugin.onKeyDown!(eventMock, editorMock, nextMock);
render(plugin.renderEditor!({} as any, editorMock, nextMock));
}
it('is backward compatible with prefixMatch and sortText', async () => {
suggestions = [
{
label: 'group',
prefixMatch: true,
items: [
{ label: 'foobar', sortText: '3' },
{ label: 'foobar', sortText: '1' },
{ label: 'foobar', sortText: '2' },
],
},
];
await triggerAutocomplete();
expect(SearchFunctionMap.Word).not.toBeCalled();
expect(SearchFunctionMap.Fuzzy).not.toBeCalled();
expect(SearchFunctionMap.Prefix).toBeCalled();
expect(TypeaheadMock).toBeCalledWith(
expect.objectContaining({
groupedItems: [
{
label: 'group',
prefixMatch: true,
items: [
{ label: 'foobar', sortText: '1' },
{ label: 'foobar', sortText: '2' },
{ label: 'foobar', sortText: '3' },
],
},
],
})
);
});
it('uses searchFunction to create autocomplete list and sortValue if defined', async () => {
suggestions = [
{
label: 'group',
searchFunctionType: SearchFunctionType.Fuzzy,
items: [
{ label: 'foobar', sortValue: 3 },
{ label: 'foobar', sortValue: 1 },
{ label: 'foobar', sortValue: 2 },
],
},
];
await triggerAutocomplete();
expect(SearchFunctionMap.Word).not.toBeCalled();
expect(SearchFunctionMap.Prefix).not.toBeCalled();
expect(SearchFunctionMap.Fuzzy).toBeCalled();
expect(TypeaheadMock).toBeCalledWith(
expect.objectContaining({
groupedItems: [
{
label: 'group',
searchFunctionType: SearchFunctionType.Fuzzy,
items: [
{ label: 'foobar', sortValue: 1 },
{ label: 'foobar', sortValue: 2 },
{ label: 'foobar', sortValue: 3 },
],
},
],
})
);
});
});
function createEditorMock(currentText: string) {
return {
blur: jest.fn().mockReturnThis(),
focus: jest.fn().mockReturnThis(),
value: {
selection: {
start: {
offset: 0,
},
end: {
offset: 0,
},
focus: {
offset: currentText.length,
},
},
document: {
getClosestBlock: () => {},
},
focusText: {
text: currentText,
},
focusBlock: {},
},
};
}
Loading…
Cancel
Save