[Canvas] Adds functional test for Canvas custom elements (#52920)
* Adds functional test for Canvas custom elements feedback cleanup * Opening up Canvas app first * Add skip firefox tag to custom element test
This commit is contained in:
parent
f2615c29ad
commit
60f647572e
|
@ -118,6 +118,7 @@ Array [
|
|||
<input
|
||||
aria-describedby="generated-id-help"
|
||||
className="euiFieldText canvasCustomElementForm__name"
|
||||
data-test-subj="canvasCustomElementForm-name"
|
||||
id="generated-id"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
|
@ -156,6 +157,7 @@ Array [
|
|||
<textarea
|
||||
aria-describedby="generated-id-help"
|
||||
className="euiTextArea euiTextArea--resizeVertical"
|
||||
data-test-subj="canvasCustomElementForm-description"
|
||||
id="generated-id"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
|
@ -324,6 +326,7 @@ Array [
|
|||
>
|
||||
<button
|
||||
className="euiButton euiButton--primary euiButton--fill"
|
||||
data-test-subj="canvasCustomElementForm-submit"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
|
@ -479,6 +482,7 @@ Array [
|
|||
<input
|
||||
aria-describedby="generated-id-help"
|
||||
className="euiFieldText canvasCustomElementForm__name"
|
||||
data-test-subj="canvasCustomElementForm-name"
|
||||
id="generated-id"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
|
@ -517,6 +521,7 @@ Array [
|
|||
<textarea
|
||||
aria-describedby="generated-id-help"
|
||||
className="euiTextArea euiTextArea--resizeVertical"
|
||||
data-test-subj="canvasCustomElementForm-description"
|
||||
id="generated-id"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
|
@ -679,6 +684,7 @@ Array [
|
|||
>
|
||||
<button
|
||||
className="euiButton euiButton--primary euiButton--fill"
|
||||
data-test-subj="canvasCustomElementForm-submit"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
|
@ -835,6 +841,7 @@ Array [
|
|||
<input
|
||||
aria-describedby="generated-id-help"
|
||||
className="euiFieldText canvasCustomElementForm__name"
|
||||
data-test-subj="canvasCustomElementForm-name"
|
||||
id="generated-id"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
|
@ -873,6 +880,7 @@ Array [
|
|||
<textarea
|
||||
aria-describedby="generated-id-help"
|
||||
className="euiTextArea euiTextArea--resizeVertical"
|
||||
data-test-subj="canvasCustomElementForm-description"
|
||||
id="generated-id"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
|
@ -1041,6 +1049,7 @@ Array [
|
|||
>
|
||||
<button
|
||||
className="euiButton euiButton--primary euiButton--fill"
|
||||
data-test-subj="canvasCustomElementForm-submit"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
|
@ -1195,6 +1204,7 @@ Array [
|
|||
<input
|
||||
aria-describedby="generated-id-help"
|
||||
className="euiFieldText canvasCustomElementForm__name"
|
||||
data-test-subj="canvasCustomElementForm-name"
|
||||
id="generated-id"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
|
@ -1233,6 +1243,7 @@ Array [
|
|||
<textarea
|
||||
aria-describedby="generated-id-help"
|
||||
className="euiTextArea euiTextArea--resizeVertical"
|
||||
data-test-subj="canvasCustomElementForm-description"
|
||||
id="generated-id"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
|
@ -1401,6 +1412,7 @@ Array [
|
|||
>
|
||||
<button
|
||||
className="euiButton euiButton--primary euiButton--fill"
|
||||
data-test-subj="canvasCustomElementForm-submit"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
|
|
|
@ -141,6 +141,7 @@ export class CustomElementModal extends PureComponent<Props, State> {
|
|||
this._handleChange('name', e.target.value)
|
||||
}
|
||||
required
|
||||
data-test-subj="canvasCustomElementForm-name"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow
|
||||
|
@ -156,6 +157,7 @@ export class CustomElementModal extends PureComponent<Props, State> {
|
|||
e.target.value.length <= MAX_DESCRIPTION_LENGTH &&
|
||||
this._handleChange('description', e.target.value)
|
||||
}
|
||||
data-test-subj="canvasCustomElementForm-description"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow
|
||||
|
@ -197,6 +199,7 @@ export class CustomElementModal extends PureComponent<Props, State> {
|
|||
onClick={() => {
|
||||
onSave(name, description, image);
|
||||
}}
|
||||
data-test-subj="canvasCustomElementForm-submit"
|
||||
>
|
||||
{strings.getSaveButtonLabel()}
|
||||
</EuiButton>
|
||||
|
|
|
@ -87,7 +87,10 @@ export const basicHandlerCreators = {
|
|||
.create(customElement)
|
||||
.then(() =>
|
||||
notify.success(
|
||||
`Custom element '${customElement.displayName || customElement.id}' was saved`
|
||||
`Custom element '${customElement.displayName || customElement.id}' was saved`,
|
||||
{
|
||||
'data-test-subj': 'canvasCustomElementCreate-success',
|
||||
}
|
||||
)
|
||||
)
|
||||
.catch((result: Http2ServerResponse) =>
|
||||
|
|
164
x-pack/test/functional/apps/canvas/custom_elements.ts
Normal file
164
x-pack/test/functional/apps/canvas/custom_elements.ts
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function canvasCustomElementTest({
|
||||
getService,
|
||||
getPageObjects,
|
||||
}: FtrProviderContext) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const browser = getService('browser');
|
||||
const retry = getService('retry');
|
||||
const PageObjects = getPageObjects(['canvas', 'common']);
|
||||
const find = getService('find');
|
||||
|
||||
describe('custom elements', function() {
|
||||
this.tags('skipFirefox');
|
||||
|
||||
before(async () => {
|
||||
// init data
|
||||
await esArchiver.loadIfNeeded('logstash_functional');
|
||||
await esArchiver.load('canvas/default');
|
||||
|
||||
// open canvas home
|
||||
await PageObjects.common.navigateToApp('canvas');
|
||||
|
||||
// load test workpad
|
||||
await PageObjects.common.navigateToApp('canvas', {
|
||||
hash: '/workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31/page/1',
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a custom element from an element when prompted', async () => {
|
||||
// find the first workpad element (a markdown element) and click it to select it
|
||||
await testSubjects.click('canvasWorkpadPage > canvasWorkpadPageElementContent', 20000);
|
||||
|
||||
// click the "Save as new element" button
|
||||
await find.clickByCssSelector('[aria-label="Save as new element"]', 20000);
|
||||
|
||||
// fill out the custom element form and submit it
|
||||
await PageObjects.canvas.fillOutCustomElementForm(
|
||||
'My New Element',
|
||||
'An excellent new element'
|
||||
);
|
||||
|
||||
// wait for the custom element success toast notif
|
||||
await testSubjects.exists('canvasCustomElementCreate-success', {
|
||||
timeout: 30000,
|
||||
});
|
||||
});
|
||||
|
||||
it('adds the custom element to the workpad when prompted', async () => {
|
||||
await PageObjects.canvas.openAddElementModal();
|
||||
|
||||
// open the custom elements tab
|
||||
await find.clickByCssSelector('#customElements', 20000);
|
||||
|
||||
// ensure the custom element is the one expected and click it to add to the workpad
|
||||
const customElement = await find.byCssSelector(
|
||||
'[aria-labelledby="customElements"] .canvasElementCard__wrapper'
|
||||
);
|
||||
const elementName = await customElement.findByCssSelector('.euiCard__title');
|
||||
expect(await elementName.getVisibleText()).to.contain('My New Element');
|
||||
customElement.click();
|
||||
|
||||
await retry.try(async () => {
|
||||
// ensure the new element is on the workpad
|
||||
const elements = await testSubjects.findAll(
|
||||
'canvasWorkpadPage > canvasWorkpadPageElementContent'
|
||||
);
|
||||
expect(elements).to.have.length(5);
|
||||
|
||||
// ensure the new element has the expected content
|
||||
const newElem = elements[4];
|
||||
const md = await newElem.findByCssSelector('.canvasMarkdown');
|
||||
expect(await md.getVisibleText()).to.contain('Welcome to Canvas');
|
||||
|
||||
// delete the element off the workpad
|
||||
await newElem.click();
|
||||
await browser.pressKeys(browser.keys.DELETE);
|
||||
|
||||
// ensure the new element has been removed
|
||||
const elementsAgain = await testSubjects.findAll(
|
||||
'canvasWorkpadPage > canvasWorkpadPageElementContent'
|
||||
);
|
||||
expect(elementsAgain).to.have.length(4);
|
||||
});
|
||||
});
|
||||
|
||||
it('saves custom element modifications', async () => {
|
||||
await PageObjects.canvas.openAddElementModal();
|
||||
|
||||
// open the custom elements tab
|
||||
await find.clickByCssSelector('#customElements', 20000);
|
||||
|
||||
// ensure the correct amount of custom elements exist
|
||||
const container = await find.byCssSelector('[aria-labelledby="customElements"]');
|
||||
const customElements = await container.findAllByCssSelector('.canvasElementCard__wrapper');
|
||||
expect(customElements).to.have.length(1);
|
||||
|
||||
// hover over the custom element to bring up the edit and delete icons
|
||||
const customElement = customElements[0];
|
||||
await customElement.moveMouseTo();
|
||||
|
||||
// click the edit element button
|
||||
const editBtn = await customElement.findByCssSelector('[aria-label="Edit element"]');
|
||||
await editBtn.click();
|
||||
|
||||
// fill out the custom element form and submit it
|
||||
await PageObjects.canvas.fillOutCustomElementForm(
|
||||
'My Edited New Element',
|
||||
'An excellent edited element'
|
||||
);
|
||||
|
||||
// ensure the custom element in the modal shows the updated text
|
||||
await retry.try(async () => {
|
||||
const elementName = await find.byCssSelector(
|
||||
'[aria-labelledby="customElements"] .canvasElementCard__wrapper .euiCard__title'
|
||||
);
|
||||
|
||||
expect(await elementName.getVisibleText()).to.contain('My Edited New Element');
|
||||
});
|
||||
});
|
||||
|
||||
it('deletes custom element when prompted', async () => {
|
||||
// open the custom elements tab
|
||||
await find.clickByCssSelector('#customElements', 20000);
|
||||
|
||||
// ensure the correct amount of custom elements exist
|
||||
const customElements = await find.allByCssSelector(
|
||||
'[aria-labelledby="customElements"] .canvasElementCard__wrapper'
|
||||
);
|
||||
expect(customElements).to.have.length(1);
|
||||
|
||||
// hover over the custom element to bring up the edit and delete icons
|
||||
const customElement = customElements[0];
|
||||
await customElement.moveMouseTo();
|
||||
|
||||
// click the delete element button
|
||||
const editBtn = await customElement.findByCssSelector('[aria-label="Delete element"]');
|
||||
await editBtn.click();
|
||||
|
||||
await testSubjects.click('confirmModalConfirmButton');
|
||||
|
||||
// ensure the custom element was deleted
|
||||
await retry.try(async () => {
|
||||
const containerAgain = await find.byCssSelector('[aria-labelledby="customElements"]');
|
||||
const customElementsAgain = await containerAgain.findAllByCssSelector(
|
||||
'.canvasElementCard__wrapper'
|
||||
);
|
||||
expect(customElementsAgain).to.have.length(0);
|
||||
});
|
||||
|
||||
// Close the modal
|
||||
await browser.pressKeys(browser.keys.ESCAPE);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -9,6 +9,7 @@ export default function canvasApp({ loadTestFile }) {
|
|||
this.tags('ciGroup2'); // CI requires tags ヽ(゜Q。)ノ?
|
||||
loadTestFile(require.resolve('./smoke_test'));
|
||||
loadTestFile(require.resolve('./expression'));
|
||||
loadTestFile(require.resolve('./custom_elements'));
|
||||
loadTestFile(require.resolve('./feature_controls/canvas_security'));
|
||||
loadTestFile(require.resolve('./feature_controls/canvas_spaces'));
|
||||
});
|
||||
|
|
|
@ -31,6 +31,14 @@ export function CanvasPageProvider({ getService }: FtrProviderContext) {
|
|||
await testSubjects.findAll('canvasWorkpadPage > canvasWorkpadPageElementContent');
|
||||
},
|
||||
|
||||
async fillOutCustomElementForm(name: string, description: string) {
|
||||
// Fill out the custom element form and submit it
|
||||
await testSubjects.setValue('canvasCustomElementForm-name', name);
|
||||
await testSubjects.setValue('canvasCustomElementForm-description', description);
|
||||
|
||||
await testSubjects.click('canvasCustomElementForm-submit');
|
||||
},
|
||||
|
||||
async expectCreateWorkpadButtonEnabled() {
|
||||
const button = await testSubjects.find('create-workpad-button', 20000);
|
||||
const disabledAttr = await button.getAttribute('disabled');
|
||||
|
@ -43,6 +51,10 @@ export function CanvasPageProvider({ getService }: FtrProviderContext) {
|
|||
expect(disabledAttr).to.be('true');
|
||||
},
|
||||
|
||||
async openAddElementModal() {
|
||||
await testSubjects.click('add-element-button');
|
||||
},
|
||||
|
||||
async expectAddElementButton() {
|
||||
await testSubjects.existOrFail('add-element-button');
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue