diff --git a/test/functional/page_objects/common_page.ts b/test/functional/page_objects/common_page.ts index a92cd19405378..d40e19e2526a9 100644 --- a/test/functional/page_objects/common_page.ts +++ b/test/functional/page_objects/common_page.ts @@ -467,7 +467,7 @@ export class CommonPageObject extends FtrService { async waitForSaveModalToClose() { this.log.debug('Waiting for save modal to close'); await this.retry.try(async () => { - if (await this.testSubjects.exists('savedObjectSaveModal')) { + if (await this.testSubjects.exists('savedObjectSaveModal', { timeout: 5000 })) { throw new Error('save modal still open'); } }); diff --git a/test/functional/services/listing_table.ts b/test/functional/services/listing_table.ts index 8db68883715e2..ce210be9d222e 100644 --- a/test/functional/services/listing_table.ts +++ b/test/functional/services/listing_table.ts @@ -51,6 +51,16 @@ export class ListingTableService extends FtrService { return visualizationNames; } + private async getAllSelectableItemsNamesOnCurrentPage(): Promise { + const visualizationNames = []; + const links = await this.find.allByCssSelector('.euiTableRow-isSelectable .euiLink'); + for (let i = 0; i < links.length; i++) { + visualizationNames.push(await links[i].getVisibleText()); + } + this.log.debug(`Found ${visualizationNames.length} selectable visualizations on current page`); + return visualizationNames; + } + public async waitUntilTableIsLoaded() { return this.retry.try(async () => { const isLoaded = await this.find.existsByDisplayedByCssSelector( @@ -65,6 +75,29 @@ export class ListingTableService extends FtrService { }); } + /** + * Navigates through all pages on Landing page and returns array of items names that are selectable + * Added for visualize_integration saved object tagging tests + */ + public async getAllSelectableItemsNames(): Promise { + this.log.debug('ListingTable.getAllItemsNames'); + let morePages = true; + let visualizationNames: string[] = []; + while (morePages) { + visualizationNames = visualizationNames.concat( + await this.getAllSelectableItemsNamesOnCurrentPage() + ); + morePages = !( + (await this.testSubjects.getAttribute('pagination-button-next', 'disabled')) === 'true' + ); + if (morePages) { + await this.testSubjects.click('pagerNextButton'); + await this.header.waitUntilLoadingHasFinished(); + } + } + return visualizationNames; + } + /** * Navigates through all pages on Landing page and returns array of items names */ diff --git a/x-pack/test/saved_object_tagging/common/fixtures/es_archiver/visualize/data.json b/x-pack/test/saved_object_tagging/common/fixtures/es_archiver/visualize/data.json index f00485e25581f..24f68ba32f047 100644 --- a/x-pack/test/saved_object_tagging/common/fixtures/es_archiver/visualize/data.json +++ b/x-pack/test/saved_object_tagging/common/fixtures/es_archiver/visualize/data.json @@ -1,4 +1,4 @@ -{ +[{ "id": "tag-1", "type": "tag", "attributes": { @@ -8,8 +8,7 @@ }, "references": [], "updated_at": "2021-06-17T18:57:58.076Z" -} - +}, { "id": "tag-2", "type": "tag", @@ -20,8 +19,7 @@ }, "references": [], "updated_at": "2021-06-17T18:57:58.076Z" -} - +}, { "id": "tag-3", "type": "tag", @@ -32,8 +30,18 @@ }, "references": [], "updated_at": "2021-06-17T18:57:58.076Z" -} - +}, +{ + "id": "myextratag", + "type": "tag", + "attributes": { + "name": "myextratag", + "description": "We need one more", + "color": "#000000" + }, + "references": [], + "updated_at": "2021-06-17T18:57:58.076Z" +}, { "id": "logstash-*", "type": "index-pattern", @@ -45,8 +53,7 @@ }, "references": [], "updated_at": "2021-06-17T18:57:58.076Z" -} - +}, { "id": "vis-area-1", "type": "visualization", @@ -67,8 +74,7 @@ } ], "updated_at": "2021-06-17T18:57:58.076Z" -} - +}, { "id": "vis-area-2", "type": "visualization", @@ -89,8 +95,7 @@ } ], "updated_at": "2021-06-17T18:57:58.076Z" -} - +}, { "id": "vis-area-3", "type": "visualization", @@ -115,4 +120,4 @@ } ], "updated_at": "2021-06-17T18:57:58.076Z" -} +}] diff --git a/x-pack/test/saved_object_tagging/functional/tests/visualize_integration.ts b/x-pack/test/saved_object_tagging/functional/tests/visualize_integration.ts index 445b748987c1a..31daa97f534cb 100644 --- a/x-pack/test/saved_object_tagging/functional/tests/visualize_integration.ts +++ b/x-pack/test/saved_object_tagging/functional/tests/visualize_integration.ts @@ -16,7 +16,14 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const listingTable = getService('listingTable'); const testSubjects = getService('testSubjects'); const find = getService('find'); - const PageObjects = getPageObjects(['visualize', 'tagManagement', 'visEditor', 'common']); + const retry = getService('retry'); + const PageObjects = getPageObjects([ + 'visualize', + 'tagManagement', + 'visEditor', + 'common', + 'header', + ]); /** * Select tags in the searchbar's tag filter. @@ -47,10 +54,40 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { } await testSubjects.click('savedObjectTitle'); }; + // creates a simple markdown vis with a tag provided. + const createSimpleMarkdownVis = async (opts: Record) => { + const { visName, visText, tagName } = opts; + await PageObjects.visualize.navigateToNewVisualization(); + + await PageObjects.visualize.clickMarkdownWidget(); + await PageObjects.visEditor.setMarkdownTxt(visText); + await PageObjects.visEditor.clickGo(); + + await PageObjects.visualize.ensureSavePanelOpen(); + await PageObjects.visualize.setSaveModalValues(visName, { + saveAsNew: false, + redirectToOrigin: true, + }); + if (tagName) { + await selectSavedObjectTags(tagName); + } - // Failing: See https://github.com/elastic/kibana/issues/89958 - describe.skip('visualize integration', () => { + await testSubjects.click('confirmSaveSavedObjectButton'); + await retry.waitForWithTimeout('Save modal to disappear', 5000, () => + testSubjects + .missingOrFail('confirmSaveSavedObjectButton') + .then(() => true) + .catch(() => false) + ); + + await PageObjects.header.waitUntilLoadingHasFinished(); + }; + + describe('visualize integration', () => { before(async () => { + // clean up any left-over visualizations and tags from tests that didn't clean up after themselves + await kibanaServer.savedObjects.clean({ types: ['tag', 'visualization'] }); + await kibanaServer.importExport.load( 'x-pack/test/saved_object_tagging/common/fixtures/es_archiver/visualize/data.json' ); @@ -62,7 +99,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await kibanaServer.importExport.unload( 'x-pack/test/saved_object_tagging/common/fixtures/es_archiver/visualize/data.json' ); - await kibanaServer.savedObjects.clean({ types: ['tag'] }); + // clean up after test suite + await kibanaServer.savedObjects.clean({ types: ['tag', 'visualization'] }); await esArchiver.unload( 'x-pack/test/saved_object_tagging/common/fixtures/es_archiver/logstash_functional' ); @@ -77,7 +115,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('allows to manually type tag filter query', async () => { await listingTable.searchForItemWithName('tag:(tag-1)', { escape: false }); await listingTable.expectItemsCount('visualize', 2); - const itemNames = await listingTable.getAllItemsNames(); + const itemNames = await listingTable.getAllSelectableItemsNames(); expect(itemNames).to.eql(['Visualization 1 (tag-1)', 'Visualization 3 (tag-1 + tag-3)']); }); @@ -85,7 +123,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await selectFilterTags('tag-1'); await listingTable.expectItemsCount('visualize', 2); - const itemNames = await listingTable.getAllItemsNames(); + const itemNames = await listingTable.getAllSelectableItemsNames(); expect(itemNames).to.eql(['Visualization 1 (tag-1)', 'Visualization 3 (tag-1 + tag-3)']); }); @@ -93,32 +131,30 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await selectFilterTags('tag-2', 'tag-3'); await listingTable.expectItemsCount('visualize', 2); - const itemNames = await listingTable.getAllItemsNames(); + const itemNames = await listingTable.getAllSelectableItemsNames(); expect(itemNames).to.eql(['Visualization 2 (tag-2)', 'Visualization 3 (tag-1 + tag-3)']); }); }); describe('creating', () => { + before(async () => { + await PageObjects.visualize.gotoVisualizationLandingPage(); + // delete all visualizations to create new ones explicitly + await PageObjects.visualize.deleteAllVisualizations(); + }); it('allows to assign tags to the new visualization', async () => { await PageObjects.visualize.navigateToNewVisualization(); - - await PageObjects.visualize.clickMarkdownWidget(); - await PageObjects.visEditor.setMarkdownTxt('Just some markdown'); - await PageObjects.visEditor.clickGo(); - - await PageObjects.visualize.ensureSavePanelOpen(); - await PageObjects.visualize.setSaveModalValues('My new markdown viz'); - - await selectSavedObjectTags('tag-1'); - - await testSubjects.click('confirmSaveSavedObjectButton'); - await PageObjects.common.waitForSaveModalToClose(); + await createSimpleMarkdownVis({ + visText: 'Just some markdown', + visName: 'My new markdown viz', + tagName: 'myextratag', + }); await PageObjects.visualize.gotoVisualizationLandingPage(); await listingTable.waitUntilTableIsLoaded(); - await selectFilterTags('tag-1'); - const itemNames = await listingTable.getAllItemsNames(); + await selectFilterTags('myextratag'); + const itemNames = await listingTable.getAllSelectableItemsNames(); expect(itemNames).to.contain('My new markdown viz'); }); @@ -132,7 +168,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await PageObjects.visEditor.clickGo(); await PageObjects.visualize.ensureSavePanelOpen(); - await PageObjects.visualize.setSaveModalValues('vis-with-new-tag'); + await PageObjects.visualize.setSaveModalValues('vis-with-new-tag', { + saveAsNew: false, + redirectToOrigin: true, + }); await testSubjects.click('savedObjectTagSelector'); await testSubjects.click(`tagSelectorOption-action__create`); @@ -159,33 +198,43 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await listingTable.waitUntilTableIsLoaded(); await selectFilterTags('my-new-tag'); - const itemNames = await listingTable.getAllItemsNames(); + const itemNames = await listingTable.getAllSelectableItemsNames(); expect(itemNames).to.contain('vis-with-new-tag'); }); }); - // FLAKY: https://github.com/elastic/kibana/issues/88639 - describe.skip('editing', () => { - beforeEach(async () => { + describe('editing', () => { + before(async () => { await PageObjects.visualize.gotoVisualizationLandingPage(); - await listingTable.waitUntilTableIsLoaded(); + await PageObjects.visualize.deleteAllVisualizations(); + // create a vis to add a tag to during edit + await PageObjects.visualize.navigateToNewVisualization(); + await createSimpleMarkdownVis({ + visText: 'Edit me!', + visName: 'MarkdownViz', + }); }); it('allows to assign tags to an existing visualization', async () => { - await listingTable.clickItemLink('visualize', 'Visualization 1 (tag-1)'); - + await PageObjects.visualize.gotoVisualizationLandingPage(); + await listingTable.waitUntilTableIsLoaded(); + await listingTable.clickItemLink('visualize', 'MarkdownViz'); await PageObjects.visualize.ensureSavePanelOpen(); - await selectSavedObjectTags('tag-2'); - + await selectSavedObjectTags(...['myextratag']); await testSubjects.click('confirmSaveSavedObjectButton'); - await PageObjects.common.waitForSaveModalToClose(); + await retry.waitForWithTimeout('Save modal to disappear', 5000, () => + testSubjects + .missingOrFail('confirmSaveSavedObjectButton') + .then(() => true) + .catch(() => false) + ); await PageObjects.visualize.gotoVisualizationLandingPage(); await listingTable.waitUntilTableIsLoaded(); - await selectFilterTags('tag-2'); - const itemNames = await listingTable.getAllItemsNames(); - expect(itemNames).to.contain('Visualization 1 (tag-1)'); + await selectFilterTags('myextratag'); + const itemNames = await listingTable.getAllSelectableItemsNames(); + expect(itemNames).to.contain('MarkdownViz'); }); }); });