mirror of https://github.com/grafana/grafana
Chore/React18: Remove enzyme slate tests and replace with e2e tests (#57095)
parent
c96b6a6ab0
commit
ed71b7b884
@ -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…
Reference in new issue