From 4dadcbb91136a3e7d39e4b419aa12e21a37e4918 Mon Sep 17 00:00:00 2001 From: Dzmitry Lemechko Date: Wed, 2 Aug 2023 12:59:23 +0200 Subject: [PATCH] [performance] enable journeys on serverless - part 1 (#162902) ## Summary This PR is the Step 1 to enable performance journeys run for serverless projects. The focus is to re-design journeys to be compatible both for stateful & serverless Kibana. I created `KibanaPage` class to have some shared UI actions across different journeys. `ProjectPage` extends `KibanaPage` and allows us to override actions, that are different (or have different locators) in Kibana Project UI (generic project at the moment) `kibanaPage` is available in Step context and based on TEST_SERVERLESS env var appropriate class instance is used. ```typescript .step('Go to Discover Page', async ({ page, kbnUrl, kibanaPage }) => { await page.goto(kbnUrl.get(`/app/discover`)); await kibanaPage.waitForHeader(); await page.waitForSelector('[data-test-subj="discoverDocTable"][data-render-complete="true"]'); await page.waitForSelector(subj('globalLoadingIndicator-hidden')); }) ``` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-journeys/journey/journey.ts | 3 + .../journey/journey_ftr_config.ts | 6 +- .../journey/journey_ftr_harness.ts | 12 +-- packages/kbn-journeys/services/auth.ts | 4 + packages/kbn-journeys/services/page/index.ts | 16 ++++ .../kbn-journeys/services/page/kibana_page.ts | 75 +++++++++++++++++++ .../services/page/project_page.ts | 22 ++++++ packages/kbn-journeys/tsconfig.json | 1 + .../journeys/apm_service_inventory.ts | 20 ++--- .../journeys/cloud_security_dashboard.ts | 3 +- .../journeys/dashboard_listing_page.ts | 31 ++++---- .../journeys/data_stress_test_lens.ts | 5 +- .../journeys/ecommerce_dashboard.ts | 5 +- .../journeys/ecommerce_dashboard_map_only.ts | 2 +- .../ecommerce_dashboard_saved_search_only.ts | 5 +- .../ecommerce_dashboard_tsvb_gauge_only.ts | 5 +- .../performance/journeys/flight_dashboard.ts | 5 +- x-pack/performance/journeys/login.ts | 5 +- .../journeys/many_fields_discover.ts | 5 +- .../journeys/many_fields_transform.ts | 5 +- .../journeys/promotion_tracking_dashboard.ts | 5 +- .../journeys/web_logs_dashboard.ts | 5 +- x-pack/performance/utils.ts | 32 -------- 23 files changed, 182 insertions(+), 95 deletions(-) create mode 100644 packages/kbn-journeys/services/page/index.ts create mode 100644 packages/kbn-journeys/services/page/kibana_page.ts create mode 100644 packages/kbn-journeys/services/page/project_page.ts delete mode 100644 x-pack/performance/utils.ts diff --git a/packages/kbn-journeys/journey/journey.ts b/packages/kbn-journeys/journey/journey.ts index e6778dc0fc088..7952b8ee7408d 100644 --- a/packages/kbn-journeys/journey/journey.ts +++ b/packages/kbn-journeys/journey/journey.ts @@ -26,8 +26,11 @@ import { KibanaUrl } from '../services/kibana_url'; import { JourneyFtrHarness } from './journey_ftr_harness'; import { makeFtrConfigProvider } from './journey_ftr_config'; import { JourneyConfig, JourneyConfigOptions } from './journey_config'; +import { KibanaPage } from '../services/page/kibana_page'; +import { ProjectPage } from '../services/page/project_page'; export interface BaseStepCtx { + kibanaPage: KibanaPage | ProjectPage; page: Page; log: ToolingLog; inputDelays: InputDelays; diff --git a/packages/kbn-journeys/journey/journey_ftr_config.ts b/packages/kbn-journeys/journey/journey_ftr_config.ts index 2d855ab8fb22c..7223dc8ab0f5c 100644 --- a/packages/kbn-journeys/journey/journey_ftr_config.ts +++ b/packages/kbn-journeys/journey/journey_ftr_config.ts @@ -22,7 +22,11 @@ export function makeFtrConfigProvider( steps: AnyStep[] ): FtrConfigProvider { return async ({ readConfigFile }: FtrConfigProviderContext) => { - const configPath = config.getFtrConfigPath(); + const isServerless = !!process.env.TEST_SERVERLESS; + // Use the same serverless FTR config for all journeys + const configPath = isServerless + ? 'x-pack/test_serverless/shared/config.base.ts' + : config.getFtrConfigPath(); const defaultConfigPath = config.isXpack() ? 'x-pack/test/functional/config.base.js' : 'test/functional/config.base.js'; diff --git a/packages/kbn-journeys/journey/journey_ftr_harness.ts b/packages/kbn-journeys/journey/journey_ftr_harness.ts index 1a227db49f11e..f6607081d6144 100644 --- a/packages/kbn-journeys/journey/journey_ftr_harness.ts +++ b/packages/kbn-journeys/journey/journey_ftr_harness.ts @@ -25,6 +25,7 @@ import { KibanaUrl } from '../services/kibana_url'; import type { Step, AnyStep } from './journey'; import type { JourneyConfig } from './journey_config'; import { JourneyScreenshots } from './journey_screenshots'; +import { getNewPageObject } from '../services/page'; export class JourneyFtrHarness { private readonly screenshots: JourneyScreenshots; @@ -357,7 +358,11 @@ export class JourneyFtrHarness { throw new Error('performance service is not properly initialized'); } + const isServerlessProject = !!this.config.get('serverless'); + const kibanaPage = getNewPageObject(isServerlessProject, page, this.log); + this.#_ctx = this.journeyConfig.getExtendedStepCtx({ + kibanaPage, page, log: this.log, inputDelays: getInputDelays(), @@ -414,11 +419,8 @@ export class JourneyFtrHarness { ? args.map((arg) => (typeof arg === 'string' ? arg : inspect(arg, false, null))).join(' ') : message.text(); - if ( - url.includes('kbn-ui-shared-deps-npm.dll.js') && - text.includes('moment construction falls') - ) { - // ignore errors from moment about constructing dates with invalid formats + if (url.includes('kbn-ui-shared-deps-npm.dll.js')) { + // ignore errors/warning from kbn-ui-shared-deps-npm.dll.js return; } diff --git a/packages/kbn-journeys/services/auth.ts b/packages/kbn-journeys/services/auth.ts index b14a99d317578..2a2a9719bd49b 100644 --- a/packages/kbn-journeys/services/auth.ts +++ b/packages/kbn-journeys/services/auth.ts @@ -102,4 +102,8 @@ export class Auth { public isCloud() { return this.config.get('servers.kibana.hostname') !== 'localhost'; } + + public isServerless() { + return !!this.config.get('serverless'); + } } diff --git a/packages/kbn-journeys/services/page/index.ts b/packages/kbn-journeys/services/page/index.ts new file mode 100644 index 0000000000000..6a809eb7480f6 --- /dev/null +++ b/packages/kbn-journeys/services/page/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ToolingLog } from '@kbn/tooling-log'; +import { Page } from 'playwright'; +import { KibanaPage } from './kibana_page'; +import { ProjectPage } from './project_page'; + +export function getNewPageObject(isServerless: boolean, page: Page, log: ToolingLog) { + return isServerless ? new ProjectPage(page, log) : new KibanaPage(page, log); +} diff --git a/packages/kbn-journeys/services/page/kibana_page.ts b/packages/kbn-journeys/services/page/kibana_page.ts new file mode 100644 index 0000000000000..b53a5f91a9e45 --- /dev/null +++ b/packages/kbn-journeys/services/page/kibana_page.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { subj } from '@kbn/test-subj-selector'; +import { ToolingLog } from '@kbn/tooling-log'; +import { Page } from 'playwright'; + +interface WaitForRenderArgs { + expectedItemsCount: number; + itemLocator: string; + checkAttribute: string; +} + +export class KibanaPage { + readonly page: Page; + readonly log: ToolingLog; + + constructor(page: Page, log: ToolingLog) { + this.page = page; + this.log = log; + } + + async waitForHeader() { + return this.page.waitForSelector('.headerGlobalNav', { + state: 'attached', + }); + } + + async backToDashboardListing() { + await this.page.click(subj('breadcrumb dashboardListingBreadcrumb first')); + } + + async waitForRender({ expectedItemsCount, itemLocator, checkAttribute }: WaitForRenderArgs) { + try { + await this.page.waitForFunction( + function renderCompleted(args: WaitForRenderArgs) { + const renderingItems = Array.from(document.querySelectorAll(args.itemLocator)); + const allItemsLoaded = renderingItems.length === args.expectedItemsCount; + return allItemsLoaded + ? renderingItems.every((e) => e.getAttribute(args.checkAttribute) === 'true') + : false; + }, + { expectedItemsCount, itemLocator, checkAttribute } + ); + } catch (err) { + const loaded = await this.page.$$(itemLocator); + const rendered = await this.page.$$(`${itemLocator}[${checkAttribute}="true"]`); + this.log.error( + `'waitForRendering' failed: loaded - ${loaded.length}, rendered - ${rendered.length}, expected count - ${expectedItemsCount}` + ); + throw err; + } + } + + async waitForVisualizations(count: number) { + await this.waitForRender({ + expectedItemsCount: count, + itemLocator: '[data-rendering-count]', + checkAttribute: 'data-render-complete', + }); + } + + async waitForCharts(count: number) { + await this.waitForRender({ + expectedItemsCount: count, + itemLocator: '.echChartStatus', + checkAttribute: 'data-ech-render-complete', + }); + } +} diff --git a/packages/kbn-journeys/services/page/project_page.ts b/packages/kbn-journeys/services/page/project_page.ts new file mode 100644 index 0000000000000..5df04a80aa4d3 --- /dev/null +++ b/packages/kbn-journeys/services/page/project_page.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { subj } from '@kbn/test-subj-selector'; +import { KibanaPage } from './kibana_page'; + +export class ProjectPage extends KibanaPage { + async waitForHeader() { + return this.page.waitForSelector(subj('kibanaProjectHeader'), { + state: 'attached', + }); + } + + async backToDashboardListing() { + await this.page.click(subj('nav-item-search_project_nav.explore.dashboards')); + } +} diff --git a/packages/kbn-journeys/tsconfig.json b/packages/kbn-journeys/tsconfig.json index 461260f7364b0..d52e0f32586af 100644 --- a/packages/kbn-journeys/tsconfig.json +++ b/packages/kbn-journeys/tsconfig.json @@ -17,6 +17,7 @@ "@kbn/tooling-log", "@kbn/repo-info", "@kbn/std", + "@kbn/test-subj-selector", ], "exclude": [ "target/**/*", diff --git a/x-pack/performance/journeys/apm_service_inventory.ts b/x-pack/performance/journeys/apm_service_inventory.ts index 30787b6b16277..cbef53858eea6 100644 --- a/x-pack/performance/journeys/apm_service_inventory.ts +++ b/x-pack/performance/journeys/apm_service_inventory.ts @@ -6,10 +6,10 @@ */ import { Journey } from '@kbn/journeys'; +import { subj } from '@kbn/test-subj-selector'; import { SynthtraceClient } from '../services/synthtrace'; import { generateData } from '../synthtrace_data/apm_data'; -// FLAKY: https://github.com/elastic/kibana/issues/162813 export const journey = new Journey({ beforeSteps: async ({ kbnUrl, log, auth, es }) => { // Install APM Package @@ -40,15 +40,15 @@ export const journey = new Journey({ await page.goto(kbnUrl.get(`app/apm/services`)); await page.waitForSelector(`[data-test-subj="serviceLink_nodejs"]`); }) - .step('Navigate to Service Overview Page', async ({ page, kbnUrl }) => { - await page.click(`[data-test-subj="serviceLink_nodejs"]`); - await page.waitForSelector(`[data-test-subj="apmMainTemplateHeaderServiceName"]`); + .step('Navigate to Service Overview Page', async ({ page }) => { + await page.click(subj('serviceLink_nodejs')); + await page.waitForSelector(subj('apmMainTemplateHeaderServiceName')); }) - .step('Navigate to Transactions tabs', async ({ page, kbnUrl }) => { - await page.click(`[data-test-subj="transactionsTab"]`); - await page.waitForSelector(`[data-test-subj="apmTransactionDetailLinkLink"]`); + .step('Navigate to Transactions tabs', async ({ page }) => { + await page.click(subj('transactionsTab')); + await page.waitForSelector(subj('apmTransactionDetailLinkLink')); }) - .step('Wait for Trace Waterfall on the page to load', async ({ page, kbnUrl }) => { - await page.click(`[data-test-subj="apmTransactionDetailLinkLink"]`); - await page.waitForSelector(`[data-test-subj="apmWaterfallButton"]`); + .step('Wait for Trace Waterfall on the page to load', async ({ page }) => { + await page.click(subj('apmTransactionDetailLinkLink')); + await page.waitForSelector(subj('apmWaterfallButton')); }); diff --git a/x-pack/performance/journeys/cloud_security_dashboard.ts b/x-pack/performance/journeys/cloud_security_dashboard.ts index a7256f44717f2..ce5224e9b14b0 100644 --- a/x-pack/performance/journeys/cloud_security_dashboard.ts +++ b/x-pack/performance/journeys/cloud_security_dashboard.ts @@ -7,6 +7,7 @@ import { Journey } from '@kbn/journeys'; import expect from '@kbn/expect'; +import { subj } from '@kbn/test-subj-selector'; export const journey = new Journey({ beforeSteps: async ({ kibanaServer, retry }) => { @@ -47,5 +48,5 @@ export const journey = new Journey({ }, }).step('Go to cloud security dashboards Page', async ({ page, kbnUrl }) => { await page.goto(kbnUrl.get(`/app/security/cloud_security_posture/dashboard`)); - await page.waitForSelector(`[data-test-subj="csp:dashboard-sections-table-header-score"]`); + await page.waitForSelector(subj('csp:dashboard-sections-table-header-score')); }); diff --git a/x-pack/performance/journeys/dashboard_listing_page.ts b/x-pack/performance/journeys/dashboard_listing_page.ts index d3fdd63dd55d8..b0afacf2cafd3 100644 --- a/x-pack/performance/journeys/dashboard_listing_page.ts +++ b/x-pack/performance/journeys/dashboard_listing_page.ts @@ -6,6 +6,7 @@ */ import { Journey } from '@kbn/journeys'; +import { subj } from '@kbn/test-subj-selector'; import { v4 as uuidv4 } from 'uuid'; export const journey = new Journey({ @@ -17,30 +18,30 @@ export const journey = new Journey({ }) .step('Go to Dashboards Page', async ({ page, kbnUrl }) => { await page.goto(kbnUrl.get(`/app/dashboards`)); - await page.waitForSelector(`[data-test-subj="table-is-ready"]`); + await page.waitForSelector(subj('table-is-ready')); }) .step('Search dashboards', async ({ page, inputDelays }) => { - await page.type('[data-test-subj="tableListSearchBox"]', 'Web', { + await page.type(subj('tableListSearchBox'), 'Web', { delay: inputDelays.TYPING, }); - await page.waitForSelector(`[data-test-subj="table-is-ready"]`); + await page.waitForSelector(subj('table-is-ready')); }) .step('Delete dashboard', async ({ page }) => { - await page.click('[data-test-subj="checkboxSelectRow-edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b"]'); - await page.click('[data-test-subj="deleteSelectedItems"]'); - await page.click('[data-test-subj="confirmModalConfirmButton"]'); - await page.waitForSelector(`[data-test-subj="table-is-ready"]`); + await page.click(subj('checkboxSelectRow-edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b')); + await page.click(subj('deleteSelectedItems')); + await page.click(subj('confirmModalConfirmButton')); + await page.waitForSelector(subj('table-is-ready')); }) .step('Add dashboard', async ({ page, inputDelays }) => { - await page.click('[data-test-subj="newItemButton"]'); - await page.click('[data-test-subj="dashboardSaveMenuItem"]'); - await page.type('[data-test-subj="savedObjectTitle"]', `foobar dashboard ${uuidv4()}`, { + await page.click(subj('newItemButton')); + await page.click(subj('dashboardSaveMenuItem')); + await page.type(subj('savedObjectTitle'), `foobar dashboard ${uuidv4()}`, { delay: inputDelays.TYPING, }); - await page.click('[data-test-subj="confirmSaveSavedObjectButton"]'); - await page.locator('[data-test-subj="saveDashboardSuccess"]'); + await page.click(subj('confirmSaveSavedObjectButton')); + await page.waitForSelector(subj('saveDashboardSuccess')); }) - .step('Return to dashboard list', async ({ page }) => { - await page.click('[data-test-subj="breadcrumb dashboardListingBreadcrumb first"]'); - await page.waitForSelector(`[data-test-subj="table-is-ready"]`); + .step('Return to dashboard list', async ({ kibanaPage, page }) => { + kibanaPage.backToDashboardListing(); + await page.waitForSelector(subj('table-is-ready')); }); diff --git a/x-pack/performance/journeys/data_stress_test_lens.ts b/x-pack/performance/journeys/data_stress_test_lens.ts index cf9a4c44e930b..a765ca414e48e 100644 --- a/x-pack/performance/journeys/data_stress_test_lens.ts +++ b/x-pack/performance/journeys/data_stress_test_lens.ts @@ -6,13 +6,12 @@ */ import { Journey } from '@kbn/journeys'; -import { waitForVisualizations } from '../utils'; export const journey = new Journey({ kbnArchives: ['test/functional/fixtures/kbn_archiver/stress_test'], esArchives: ['test/functional/fixtures/es_archiver/stress_test'], -}).step('Go to dashboard', async ({ page, kbnUrl, kibanaServer, log }) => { +}).step('Go to dashboard', async ({ page, kbnUrl, kibanaServer, kibanaPage }) => { await kibanaServer.uiSettings.update({ 'histogram:maxBars': 100 }); await page.goto(kbnUrl.get(`/app/dashboards#/view/92b143a0-2e9c-11ed-b1b6-a504560b392c`)); - await waitForVisualizations(page, log, 1); + await kibanaPage.waitForVisualizations(1); }); diff --git a/x-pack/performance/journeys/ecommerce_dashboard.ts b/x-pack/performance/journeys/ecommerce_dashboard.ts index 45a54fffd7620..d51169f8195ac 100644 --- a/x-pack/performance/journeys/ecommerce_dashboard.ts +++ b/x-pack/performance/journeys/ecommerce_dashboard.ts @@ -7,7 +7,6 @@ import { Journey } from '@kbn/journeys'; import { subj } from '@kbn/test-subj-selector'; -import { waitForVisualizations } from '../utils'; export const journey = new Journey({ esArchives: ['x-pack/performance/es_archives/sample_data_ecommerce'], @@ -19,7 +18,7 @@ export const journey = new Journey({ await page.waitForSelector('#dashboardListingHeading'); }) - .step('Go to Ecommerce Dashboard', async ({ page, log }) => { + .step('Go to Ecommerce Dashboard', async ({ page, kibanaPage }) => { await page.click(subj('dashboardListingTitleLink-[eCommerce]-Revenue-Dashboard')); - await waitForVisualizations(page, log, 13); + await kibanaPage.waitForVisualizations(13); }); diff --git a/x-pack/performance/journeys/ecommerce_dashboard_map_only.ts b/x-pack/performance/journeys/ecommerce_dashboard_map_only.ts index 883642be161e4..1aeb20312505f 100644 --- a/x-pack/performance/journeys/ecommerce_dashboard_map_only.ts +++ b/x-pack/performance/journeys/ecommerce_dashboard_map_only.ts @@ -18,7 +18,7 @@ export const journey = new Journey({ await page.waitForSelector('#dashboardListingHeading'); }) - .step('Go to Ecommerce No Map Dashboard', async ({ page, kbnUrl }) => { + .step('Go to Ecommerce No Map Dashboard', async ({ page }) => { await page.click(subj('dashboardListingTitleLink-[eCommerce]-Map-Only')); await page.waitForSelector( 'div[data-title="[eCommerce] Orders by Country"][data-render-complete="true"]' diff --git a/x-pack/performance/journeys/ecommerce_dashboard_saved_search_only.ts b/x-pack/performance/journeys/ecommerce_dashboard_saved_search_only.ts index c63f239c5a491..838c326d09e71 100644 --- a/x-pack/performance/journeys/ecommerce_dashboard_saved_search_only.ts +++ b/x-pack/performance/journeys/ecommerce_dashboard_saved_search_only.ts @@ -7,7 +7,6 @@ import { Journey } from '@kbn/journeys'; import { subj } from '@kbn/test-subj-selector'; -import { waitForVisualizations } from '../utils'; export const journey = new Journey({ esArchives: ['x-pack/performance/es_archives/sample_data_ecommerce'], @@ -19,7 +18,7 @@ export const journey = new Journey({ await page.waitForSelector('#dashboardListingHeading'); }) - .step('Go to Ecommerce Dashboard with Saved Search only', async ({ page, log }) => { + .step('Go to Ecommerce Dashboard with Saved Search only', async ({ page, kibanaPage }) => { await page.click(subj('dashboardListingTitleLink-[eCommerce]-Saved-Search-Dashboard')); - await waitForVisualizations(page, log, 1); + await kibanaPage.waitForVisualizations(1); }); diff --git a/x-pack/performance/journeys/ecommerce_dashboard_tsvb_gauge_only.ts b/x-pack/performance/journeys/ecommerce_dashboard_tsvb_gauge_only.ts index ad252cfb16e88..6bd72126e7ad4 100644 --- a/x-pack/performance/journeys/ecommerce_dashboard_tsvb_gauge_only.ts +++ b/x-pack/performance/journeys/ecommerce_dashboard_tsvb_gauge_only.ts @@ -7,7 +7,6 @@ import { Journey } from '@kbn/journeys'; import { subj } from '@kbn/test-subj-selector'; -import { waitForVisualizations } from '../utils'; export const journey = new Journey({ esArchives: ['x-pack/performance/es_archives/sample_data_ecommerce'], @@ -19,7 +18,7 @@ export const journey = new Journey({ await page.waitForSelector('#dashboardListingHeading'); }) - .step('Go to Ecommerce Dashboard with TSVB Gauge only', async ({ page, log }) => { + .step('Go to Ecommerce Dashboard with TSVB Gauge only', async ({ page, kibanaPage }) => { await page.click(subj('dashboardListingTitleLink-[eCommerce]-TSVB-Gauge-Only-Dashboard')); - await waitForVisualizations(page, log, 1); + await kibanaPage.waitForVisualizations(1); }); diff --git a/x-pack/performance/journeys/flight_dashboard.ts b/x-pack/performance/journeys/flight_dashboard.ts index d6cfa0d8acdeb..4696c267e5100 100644 --- a/x-pack/performance/journeys/flight_dashboard.ts +++ b/x-pack/performance/journeys/flight_dashboard.ts @@ -7,7 +7,6 @@ import { Journey } from '@kbn/journeys'; import { subj } from '@kbn/test-subj-selector'; -import { waitForVisualizations } from '../utils'; export const journey = new Journey({ esArchives: ['x-pack/performance/es_archives/sample_data_flights'], @@ -19,7 +18,7 @@ export const journey = new Journey({ await page.waitForSelector('#dashboardListingHeading'); }) - .step('Go to Flights Dashboard', async ({ page, log }) => { + .step('Go to Flights Dashboard', async ({ page, kibanaPage }) => { await page.click(subj('dashboardListingTitleLink-[Flights]-Global-Flight-Dashboard')); - await waitForVisualizations(page, log, 14); + await kibanaPage.waitForVisualizations(14); }); diff --git a/x-pack/performance/journeys/login.ts b/x-pack/performance/journeys/login.ts index 62e30a3968a33..5cf705dec2ef9 100644 --- a/x-pack/performance/journeys/login.ts +++ b/x-pack/performance/journeys/login.ts @@ -7,7 +7,6 @@ import { Journey } from '@kbn/journeys'; import { subj } from '@kbn/test-subj-selector'; -import { waitForChrome } from '../utils'; export const journey = new Journey({ skipAutoLogin: true, @@ -34,7 +33,7 @@ export const journey = new Journey({ ], maxDuration: '10m', }, -}).step('Login', async ({ page, kbnUrl, inputDelays, auth }) => { +}).step('Login', async ({ page, kbnUrl, inputDelays, auth, kibanaPage }) => { await page.goto(kbnUrl.get()); if (auth.isCloud()) { await page.click(subj('loginCard-basic/cloud-basic'), { delay: inputDelays.MOUSE_CLICK }); @@ -44,5 +43,5 @@ export const journey = new Journey({ await page.type(subj('loginPassword'), auth.getPassword(), { delay: inputDelays.TYPING }); await page.click(subj('loginSubmit'), { delay: inputDelays.MOUSE_CLICK }); - await waitForChrome(page); + await kibanaPage.waitForHeader(); }); diff --git a/x-pack/performance/journeys/many_fields_discover.ts b/x-pack/performance/journeys/many_fields_discover.ts index c4634cb89b048..a37207f6e092d 100644 --- a/x-pack/performance/journeys/many_fields_discover.ts +++ b/x-pack/performance/journeys/many_fields_discover.ts @@ -7,15 +7,14 @@ import { Journey } from '@kbn/journeys'; import { subj } from '@kbn/test-subj-selector'; -import { waitForChrome } from '../utils'; export const journey = new Journey({ kbnArchives: ['test/functional/fixtures/kbn_archiver/many_fields_data_view'], esArchives: ['test/functional/fixtures/es_archiver/many_fields'], }) - .step('Go to Discover Page', async ({ page, kbnUrl }) => { + .step('Go to Discover Page', async ({ page, kbnUrl, kibanaPage }) => { await page.goto(kbnUrl.get(`/app/discover`)); - await waitForChrome(page); + await kibanaPage.waitForHeader(); await page.waitForSelector('[data-test-subj="discoverDocTable"][data-render-complete="true"]'); await page.waitForSelector(subj('globalLoadingIndicator-hidden')); }) diff --git a/x-pack/performance/journeys/many_fields_transform.ts b/x-pack/performance/journeys/many_fields_transform.ts index 24659d3cbfca8..6fe945914c358 100644 --- a/x-pack/performance/journeys/many_fields_transform.ts +++ b/x-pack/performance/journeys/many_fields_transform.ts @@ -7,15 +7,14 @@ import { Journey } from '@kbn/journeys'; import { subj } from '@kbn/test-subj-selector'; -import { waitForChrome } from '../utils'; export const journey = new Journey({ kbnArchives: ['test/functional/fixtures/kbn_archiver/many_fields_data_view'], esArchives: ['test/functional/fixtures/es_archiver/many_fields'], }) - .step('Go to Transforms', async ({ page, kbnUrl }) => { + .step('Go to Transforms', async ({ page, kbnUrl, kibanaPage }) => { await page.goto(kbnUrl.get(`app/management/data/transform`)); - await waitForChrome(page); + await kibanaPage.waitForHeader(); await page.waitForSelector(subj('transformCreateFirstButton')); await page.waitForSelector(subj('globalLoadingIndicator-hidden')); }) diff --git a/x-pack/performance/journeys/promotion_tracking_dashboard.ts b/x-pack/performance/journeys/promotion_tracking_dashboard.ts index 792a4dab88176..aa2373e402b0f 100644 --- a/x-pack/performance/journeys/promotion_tracking_dashboard.ts +++ b/x-pack/performance/journeys/promotion_tracking_dashboard.ts @@ -7,7 +7,6 @@ import { Journey } from '@kbn/journeys'; import { subj } from '@kbn/test-subj-selector'; -import { waitForVisualizations } from '../utils'; export const journey = new Journey({ kbnArchives: ['x-pack/performance/kbn_archives/promotion_tracking_dashboard'], @@ -50,6 +49,6 @@ export const journey = new Journey({ await page.click(subj('superDatePickerCommonlyUsed_Last_30 days')); }) - .step('Wait for visualization animations to finish', async ({ page, log }) => { - await waitForVisualizations(page, log, 1); + .step('Wait for visualization animations to finish', async ({ kibanaPage }) => { + await kibanaPage.waitForVisualizations(1); }); diff --git a/x-pack/performance/journeys/web_logs_dashboard.ts b/x-pack/performance/journeys/web_logs_dashboard.ts index e4d4c66d272f6..89ca26f195d08 100644 --- a/x-pack/performance/journeys/web_logs_dashboard.ts +++ b/x-pack/performance/journeys/web_logs_dashboard.ts @@ -7,7 +7,6 @@ import { Journey } from '@kbn/journeys'; import { subj } from '@kbn/test-subj-selector'; -import { waitForVisualizations } from '../utils'; export const journey = new Journey({ esArchives: ['x-pack/performance/es_archives/sample_data_logs'], @@ -19,7 +18,7 @@ export const journey = new Journey({ await page.waitForSelector('#dashboardListingHeading'); }) - .step('Go to Web Logs Dashboard', async ({ page, log }) => { + .step('Go to Web Logs Dashboard', async ({ page, kibanaPage }) => { await page.click(subj('dashboardListingTitleLink-[Logs]-Web-Traffic')); - await waitForVisualizations(page, log, 11); + await kibanaPage.waitForVisualizations(11); }); diff --git a/x-pack/performance/utils.ts b/x-pack/performance/utils.ts deleted file mode 100644 index 16c997c2166fa..0000000000000 --- a/x-pack/performance/utils.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ToolingLog } from '@kbn/tooling-log'; -import { Page } from 'playwright'; - -export async function waitForChrome(page: Page) { - return page.waitForSelector('.headerGlobalNav', { state: 'attached' }); -} - -export async function waitForVisualizations(page: Page, log: ToolingLog, visCount: number) { - try { - await page.waitForFunction(function renderCompleted(cnt) { - const visualizations = Array.from(document.querySelectorAll('[data-rendering-count]')); - const allVisLoaded = visualizations.length === cnt; - return allVisLoaded - ? visualizations.every((e) => e.getAttribute('data-render-complete') === 'true') - : false; - }, visCount); - } catch (err) { - const loadedVis = await page.$$('[data-rendering-count]'); - const renderedVis = await page.$$('[data-rendering-count][data-render-complete="true"]'); - log.error( - `'waitForVisualizations' failed: loaded - ${loadedVis.length}, rendered - ${renderedVis.length}, expected - ${visCount}` - ); - throw err; - } -}