mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[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>
This commit is contained in:
parent
2fd6af9063
commit
4dadcbb911
23 changed files with 182 additions and 95 deletions
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,4 +102,8 @@ export class Auth {
|
|||
public isCloud() {
|
||||
return this.config.get('servers.kibana.hostname') !== 'localhost';
|
||||
}
|
||||
|
||||
public isServerless() {
|
||||
return !!this.config.get('serverless');
|
||||
}
|
||||
}
|
||||
|
|
16
packages/kbn-journeys/services/page/index.ts
Normal file
16
packages/kbn-journeys/services/page/index.ts
Normal file
|
@ -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);
|
||||
}
|
75
packages/kbn-journeys/services/page/kibana_page.ts
Normal file
75
packages/kbn-journeys/services/page/kibana_page.ts
Normal file
|
@ -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',
|
||||
});
|
||||
}
|
||||
}
|
22
packages/kbn-journeys/services/page/project_page.ts
Normal file
22
packages/kbn-journeys/services/page/project_page.ts
Normal file
|
@ -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'));
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
"@kbn/tooling-log",
|
||||
"@kbn/repo-info",
|
||||
"@kbn/std",
|
||||
"@kbn/test-subj-selector",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -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'));
|
||||
});
|
||||
|
|
|
@ -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'));
|
||||
});
|
||||
|
|
|
@ -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'));
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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"]'
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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'));
|
||||
})
|
||||
|
|
|
@ -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'));
|
||||
})
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue