diff --git a/test/functional/apps/visualize/_gauge_chart.js b/test/functional/apps/visualize/_gauge_chart.js index aa94e596319c2..0f870b1fb545f 100644 --- a/test/functional/apps/visualize/_gauge_chart.js +++ b/test/functional/apps/visualize/_gauge_chart.js @@ -26,7 +26,6 @@ export default function ({ getService, getPageObjects }) { const testSubjects = getService('testSubjects'); const PageObjects = getPageObjects(['visualize', 'visEditor', 'visChart', 'timePicker']); - // FLAKY: https://github.com/elastic/kibana/issues/45089 describe('gauge chart', function indexPatternCreation() { async function initGaugeVis() { log.debug('navigateToApp visualize'); diff --git a/test/functional/apps/visualize/_vega_chart.js b/test/functional/apps/visualize/_vega_chart.ts similarity index 59% rename from test/functional/apps/visualize/_vega_chart.js rename to test/functional/apps/visualize/_vega_chart.ts index c530c6f823133..6c0b77411ae99 100644 --- a/test/functional/apps/visualize/_vega_chart.js +++ b/test/functional/apps/visualize/_vega_chart.ts @@ -18,9 +18,17 @@ */ import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; -export default function ({ getService, getPageObjects }) { - const PageObjects = getPageObjects(['timePicker', 'visualize', 'visChart', 'vegaChart']); +// eslint-disable-next-line import/no-default-export +export default function ({ getPageObjects, getService }: FtrProviderContext) { + const PageObjects = getPageObjects([ + 'timePicker', + 'visualize', + 'visChart', + 'visEditor', + 'vegaChart', + ]); const filterBar = getService('filterBar'); const log = getService('log'); @@ -30,13 +38,15 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.navigateToNewVisualization(); log.debug('clickVega'); await PageObjects.visualize.clickVega(); + await PageObjects.visChart.waitForVisualizationRenderingStabilized(); }); describe('vega chart', () => { describe('initial render', () => { - it.skip('should have some initial vega spec text', async function () { + it('should have some initial vega spec text', async function () { const vegaSpec = await PageObjects.vegaChart.getSpec(); - expect(vegaSpec).to.contain('{').and.to.contain('data'); + expect(vegaSpec).to.contain('{'); + expect(vegaSpec).to.contain('data'); expect(vegaSpec.length).to.be.above(500); }); @@ -44,7 +54,8 @@ export default function ({ getService, getPageObjects }) { const view = await PageObjects.vegaChart.getViewContainer(); expect(view).to.be.ok(); const size = await view.getSize(); - expect(size).to.have.property('width').and.to.have.property('height'); + expect(size).to.have.property('width'); + expect(size).to.have.property('height'); expect(size.width).to.be.above(0); expect(size.height).to.be.above(0); @@ -63,10 +74,18 @@ export default function ({ getService, getPageObjects }) { await filterBar.removeAllFilters(); }); - it.skip('should render different data in response to filter change', async function () { - await PageObjects.vegaChart.expectVisToMatchScreenshot('vega_chart'); + it('should render different data in response to filter change', async function () { + await PageObjects.vegaChart.typeInSpec('"config": { "kibana": {"renderer": "svg"} },'); + await PageObjects.visEditor.clickGo(); + await PageObjects.visChart.waitForVisualizationRenderingStabilized(); + const fullDataLabels = await PageObjects.vegaChart.getYAxisLabels(); + expect(fullDataLabels[0]).to.eql('0'); + expect(fullDataLabels[fullDataLabels.length - 1]).to.eql('1,600'); await filterBar.addFilter('@tags.raw', 'is', 'error'); - await PageObjects.vegaChart.expectVisToMatchScreenshot('vega_chart_filtered'); + await PageObjects.visChart.waitForVisualizationRenderingStabilized(); + const filteredDataLabels = await PageObjects.vegaChart.getYAxisLabels(); + expect(filteredDataLabels[0]).to.eql('0'); + expect(filteredDataLabels[filteredDataLabels.length - 1]).to.eql('90'); }); }); }); diff --git a/test/functional/page_objects/vega_chart_page.ts b/test/functional/page_objects/vega_chart_page.ts index 488f4cfd0d0ce..b9906911b00f1 100644 --- a/test/functional/page_objects/vega_chart_page.ts +++ b/test/functional/page_objects/vega_chart_page.ts @@ -17,20 +17,17 @@ * under the License. */ -import expect from '@kbn/expect'; +import { Key } from 'selenium-webdriver'; import { FtrProviderContext } from '../ftr_provider_context'; export function VegaChartPageProvider({ getService, getPageObjects, - updateBaselines, }: FtrProviderContext & { updateBaselines: boolean }) { const find = getService('find'); const testSubjects = getService('testSubjects'); const browser = getService('browser'); - const screenshot = getService('screenshots'); - const log = getService('log'); - const { visEditor, visChart } = getPageObjects(['visEditor', 'visChart']); + const { common } = getPageObjects(['common']); class VegaChartPage { public async getSpec() { @@ -45,6 +42,19 @@ export function VegaChartPageProvider({ return linesText.join('\n'); } + public async typeInSpec(text: string) { + const editor = await testSubjects.find('vega-editor'); + const textarea = await editor.findByClassName('ace_content'); + await textarea.click(); + let repeats = 20; + while (--repeats > 0) { + await browser.pressKeys(Key.ARROW_UP); + await common.sleep(50); + } + await browser.pressKeys(Key.ARROW_RIGHT); + await browser.pressKeys(text); + } + public async getViewContainer() { return await find.byCssSelector('div.vgaVis__view'); } @@ -53,37 +63,16 @@ export function VegaChartPageProvider({ return await find.byCssSelector('div.vgaVis__controls'); } - /** - * Removes chrome and takes a small screenshot of a vis to compare against a baseline. - * @param {string} name The name of the baseline image. - * @param {object} opts Options object. - * @param {number} opts.threshold Threshold for allowed variance when comparing images. - */ - public async expectVisToMatchScreenshot(name: string, opts = { threshold: 0.05 }) { - log.debug(`expectVisToMatchScreenshot(${name})`); - - // Collapse sidebar and inject some CSS to hide the nav so we have a focused screenshot - await visEditor.clickEditorSidebarCollapse(); - await visChart.waitForVisualizationRenderingStabilized(); - await browser.execute(` - var el = document.createElement('style'); - el.id = '__data-test-style'; - el.innerHTML = '[data-test-subj="headerGlobalNav"] { display: none; } '; - el.innerHTML += '[data-test-subj="top-nav"] { display: none; } '; - el.innerHTML += '[data-test-subj="experimentalVisInfo"] { display: none; } '; - document.body.appendChild(el); - `); - - const percentDifference = await screenshot.compareAgainstBaseline(name, updateBaselines); - - // Reset the chart to its original state - await browser.execute(` - var el = document.getElementById('__data-test-style'); - document.body.removeChild(el); - `); - await visEditor.clickEditorSidebarCollapse(); - await visChart.waitForVisualizationRenderingStabilized(); - expect(percentDifference).to.be.lessThan(opts.threshold); + public async getYAxisLabels() { + const chart = await testSubjects.find('visualizationLoader'); + const yAxis = await chart.findByCssSelector('[aria-label^="Y-axis"]'); + const tickGroup = await yAxis.findByClassName('role-axis-label'); + const labels = await tickGroup.findAllByCssSelector('text'); + const labelTexts: string[] = []; + for (const label of labels) { + labelTexts.push(await label.getVisibleText()); + } + return labelTexts; } } diff --git a/test/functional/screenshots/baseline/vega_chart.png b/test/functional/screenshots/baseline/vega_chart.png deleted file mode 100644 index 5288bd9c7b924..0000000000000 Binary files a/test/functional/screenshots/baseline/vega_chart.png and /dev/null differ diff --git a/test/functional/screenshots/baseline/vega_chart_filtered.png b/test/functional/screenshots/baseline/vega_chart_filtered.png deleted file mode 100644 index 974ede74095d2..0000000000000 Binary files a/test/functional/screenshots/baseline/vega_chart_filtered.png and /dev/null differ diff --git a/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts b/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts index 3a21f622cec17..f32a755515a95 100644 --- a/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts +++ b/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts @@ -33,8 +33,7 @@ function errorAttempts(task: TaskInstance): Err { +describe('Bulk Operation Buffer', () => { describe('createBuffer()', () => { test('batches up multiple Operation calls', async () => { const bulkUpdate: jest.Mocked> = jest.fn( @@ -67,8 +66,6 @@ describe.skip('Bulk Operation Buffer', () => { const task2 = createTask(); const task3 = createTask(); const task4 = createTask(); - const task5 = createTask(); - const task6 = createTask(); return new Promise((resolve) => { Promise.all([bufferedUpdate(task1), bufferedUpdate(task2)]).then((_) => { @@ -79,22 +76,18 @@ describe.skip('Bulk Operation Buffer', () => { setTimeout(() => { // on next tick - setTimeout(() => { - // on next tick - expect(bulkUpdate).toHaveBeenCalledTimes(2); - Promise.all([bufferedUpdate(task5), bufferedUpdate(task6)]).then((_) => { - expect(bulkUpdate).toHaveBeenCalledTimes(3); - expect(bulkUpdate).toHaveBeenCalledWith([task5, task6]); - resolve(); - }); - }, bufferMaxDuration + 1); - expect(bulkUpdate).toHaveBeenCalledTimes(1); Promise.all([bufferedUpdate(task3), bufferedUpdate(task4)]).then((_) => { expect(bulkUpdate).toHaveBeenCalledTimes(2); expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); }); - }, bufferMaxDuration + 1); + + setTimeout(() => { + // on next tick + expect(bulkUpdate).toHaveBeenCalledTimes(2); + resolve(); + }, bufferMaxDuration * 1.1); + }, bufferMaxDuration * 1.1); }); }); @@ -103,8 +96,9 @@ describe.skip('Bulk Operation Buffer', () => { return Promise.resolve(tasks.map(incrementAttempts)); }); + const bufferMaxDuration = 1000; const bufferedUpdate = createBuffer(bulkUpdate, { - bufferMaxDuration: 100, + bufferMaxDuration, bufferMaxOperations: 2, }); @@ -114,26 +108,19 @@ describe.skip('Bulk Operation Buffer', () => { const task4 = createTask(); const task5 = createTask(); - return new Promise((resolve) => { - bufferedUpdate(task1); - bufferedUpdate(task2); - bufferedUpdate(task3); - bufferedUpdate(task4); - - setTimeout(() => { - expect(bulkUpdate).toHaveBeenCalledTimes(2); - expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); - expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); - - setTimeout(() => { - expect(bulkUpdate).toHaveBeenCalledTimes(2); - bufferedUpdate(task5).then((_) => { - expect(bulkUpdate).toHaveBeenCalledTimes(3); - expect(bulkUpdate).toHaveBeenCalledWith([task5]); - resolve(); - }); - }, 50); - }, 50); + return Promise.all([ + bufferedUpdate(task1), + bufferedUpdate(task2), + bufferedUpdate(task3), + bufferedUpdate(task4), + ]).then(() => { + expect(bulkUpdate).toHaveBeenCalledTimes(2); + expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); + expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); + return bufferedUpdate(task5).then((_) => { + expect(bulkUpdate).toHaveBeenCalledTimes(3); + expect(bulkUpdate).toHaveBeenCalledWith([task5]); + }); }); }); @@ -153,29 +140,26 @@ describe.skip('Bulk Operation Buffer', () => { const task3 = createTask(); const task4 = createTask(); - return new Promise((resolve) => { - bufferedUpdate(task1); - bufferedUpdate(task2); - - setTimeout(() => { - expect(bulkUpdate).toHaveBeenCalledTimes(1); - expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); + return Promise.all([bufferedUpdate(task1), bufferedUpdate(task2)]).then(() => { + expect(bulkUpdate).toHaveBeenCalledTimes(1); + expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); - bufferedUpdate(task3); - bufferedUpdate(task4); + return new Promise((resolve) => { + const futureUpdates = Promise.all([bufferedUpdate(task3), bufferedUpdate(task4)]); setTimeout(() => { expect(bulkUpdate).toHaveBeenCalledTimes(1); - setTimeout(() => { + futureUpdates.then(() => { expect(bulkUpdate).toHaveBeenCalledTimes(2); expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); resolve(); - }, bufferMaxDuration / 2); + }); }, bufferMaxDuration / 2); - }, bufferMaxDuration + 1); + }); }); }); + test('handles both resolutions and rejections at individual task level', async (done) => { const bulkUpdate: jest.Mocked> = jest.fn( ([task1, task2, task3]) => { diff --git a/x-pack/test/functional/apps/graph/graph.ts b/x-pack/test/functional/apps/graph/graph.ts index 803e5e8f80d70..c2500dca78444 100644 --- a/x-pack/test/functional/apps/graph/graph.ts +++ b/x-pack/test/functional/apps/graph/graph.ts @@ -13,8 +13,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const browser = getService('browser'); - // FLAKY: https://github.com/elastic/kibana/issues/53749 - describe.skip('graph', function () { + describe('graph', function () { before(async () => { await browser.setWindowSize(1600, 1000); log.debug('load graph/secrepo data'); @@ -132,14 +131,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await buildGraph(); const { edges } = await PageObjects.graph.getGraphObjects(); - const blogAdminBlogEdge = edges.find( + await PageObjects.graph.isolateEdge('test', '/test/wp-admin/'); + + await PageObjects.graph.stopLayout(); + await PageObjects.common.sleep(1000); + const testTestWpAdminBlogEdge = edges.find( ({ sourceNode, targetNode }) => - sourceNode.label === '/blog/wp-admin/' && targetNode.label === 'blog' + targetNode.label === '/test/wp-admin/' && sourceNode.label === 'test' )!; - - await PageObjects.graph.isolateEdge(blogAdminBlogEdge); - - await PageObjects.graph.clickEdge(blogAdminBlogEdge); + await testTestWpAdminBlogEdge.element.click(); + await PageObjects.common.sleep(1000); + await PageObjects.graph.startLayout(); const vennTerm1 = await PageObjects.graph.getVennTerm1(); log.debug('vennTerm1 = ' + vennTerm1); @@ -156,11 +158,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const smallVennTerm2 = await PageObjects.graph.getSmallVennTerm2(); log.debug('smallVennTerm2 = ' + smallVennTerm2); - expect(vennTerm1).to.be('/blog/wp-admin/'); - expect(vennTerm2).to.be('blog'); - expect(smallVennTerm1).to.be('5'); - expect(smallVennTerm12).to.be(' (5) '); - expect(smallVennTerm2).to.be('8'); + expect(vennTerm1).to.be('/test/wp-admin/'); + expect(vennTerm2).to.be('test'); + expect(smallVennTerm1).to.be('4'); + expect(smallVennTerm12).to.be(' (4) '); + expect(smallVennTerm2).to.be('4'); }); it('should delete graph', async function () { diff --git a/x-pack/test/functional/page_objects/graph_page.ts b/x-pack/test/functional/page_objects/graph_page.ts index 0d3e2c10579f5..fe049327fe38b 100644 --- a/x-pack/test/functional/page_objects/graph_page.ts +++ b/x-pack/test/functional/page_objects/graph_page.ts @@ -83,10 +83,7 @@ export function GraphPageProvider({ getService, getPageObjects }: FtrProviderCon return [this.getPositionAsString(x1, y1), this.getPositionAsString(x2, y2)]; } - async isolateEdge(edge: Edge) { - const from = edge.sourceNode.label; - const to = edge.targetNode.label; - + async isolateEdge(from: string, to: string) { // select all nodes await testSubjects.click('graphSelectAll'); @@ -109,13 +106,6 @@ export function GraphPageProvider({ getService, getPageObjects }: FtrProviderCon await testSubjects.click('graphRemoveSelection'); } - async clickEdge(edge: Edge) { - await this.stopLayout(); - await PageObjects.common.sleep(1000); - await edge.element.click(); - await this.startLayout(); - } - async stopLayout() { if (await testSubjects.exists('graphPauseLayout')) { await testSubjects.click('graphPauseLayout');