Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scout: run tests in parallel (with spaces) #207253

Merged
merged 32 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a42bd35
initial POC
dmlemeshko Jan 15, 2025
98b1b68
Merge remote-tracking branch 'upstream/main' into scout/parallel-run
dmlemeshko Jan 15, 2025
7187ec8
remove demo tests
dmlemeshko Jan 16, 2025
630cf03
update tests
dmlemeshko Jan 20, 2025
e895499
Merge remote-tracking branch 'upstream/main' into scout/parallel-run
dmlemeshko Jan 20, 2025
b99065e
update pipeline
dmlemeshko Jan 20, 2025
c8b1795
fix type errors
dmlemeshko Jan 20, 2025
15175ea
change config name
dmlemeshko Jan 21, 2025
2b00f4f
delete SO test file
dmlemeshko Jan 21, 2025
265bf5d
change structure
dmlemeshko Jan 21, 2025
a53bae4
Merge branch 'main' into scout/parallel-run
dmlemeshko Jan 21, 2025
3e5a82a
improve logging
dmlemeshko Jan 21, 2025
146f213
Merge branch 'scout/parallel-run' of github.com:dmlemeshko/kibana int…
dmlemeshko Jan 21, 2025
17111c3
[kbn-test] cache cookie per space
dmlemeshko Jan 21, 2025
78d0673
fix regexp for ftr config checker
dmlemeshko Jan 21, 2025
cf91301
fix lint error
dmlemeshko Jan 21, 2025
502e276
revert exported interfaces to avoid breaking change
dmlemeshko Jan 21, 2025
9dbe440
add 3x tests
dmlemeshko Jan 21, 2025
6159e8e
Revert "add 3x tests"
dmlemeshko Jan 21, 2025
28c59cb
delete duplicated tests
dmlemeshko Jan 21, 2025
db1c6cb
refactor and improve logging
dmlemeshko Jan 22, 2025
460cad7
Update scout_ui_tests.sh
dmlemeshko Jan 22, 2025
181e491
update tests
dmlemeshko Jan 22, 2025
46a9b78
add perf tracking
dmlemeshko Jan 22, 2025
35aea26
Merge branch 'scout/parallel-run' of github.com:dmlemeshko/kibana int…
dmlemeshko Jan 22, 2025
9fdb46b
adjust perf tracking for all calls in scoutSpace
dmlemeshko Jan 22, 2025
fa6cbfb
Merge branch 'main' into scout/parallel-run
dmlemeshko Jan 22, 2025
36c24a4
Merge branch 'main' into scout/parallel-run
dmlemeshko Jan 22, 2025
736707a
Merge branch 'main' into scout/parallel-run
dmlemeshko Jan 23, 2025
63ebf59
update ci script
dmlemeshko Jan 23, 2025
b07a636
rename types/vars
dmlemeshko Jan 23, 2025
ef081b2
Merge branch 'main' into scout/parallel-run
dmlemeshko Jan 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .buildkite/scripts/steps/functional/scout_ui_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ EXIT_CODE=0

# Discovery Enhanced
for run_mode in "--stateful" "--serverless=es" "--serverless=oblt" "--serverless=security"; do
run_tests "Discovery Enhanced: Parallel Workers" "x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel.playwright.config.ts" "$run_mode"
run_tests "Discovery Enhanced" "x-pack/platform/plugins/private/discover_enhanced/ui_tests/playwright.config.ts" "$run_mode"
done

Expand Down
15 changes: 12 additions & 3 deletions packages/kbn-scout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,24 @@
*/

export * as cli from './src/cli';
export { expect, test, tags, createPlaywrightConfig, createLazyPageObject } from './src/playwright';
export {
expect,
test,
spaceTest,
tags,
createPlaywrightConfig,
createLazyPageObject,
ingestTestDataHook,
} from './src/playwright';
export type {
ScoutPage,
ScoutPlaywrightOptions,
ScoutTestOptions,
ScoutPage,
PageObjects,
ScoutTestFixtures,
ScoutWorkerFixtures,
EsArchiverFixture,
ScoutParallelTestFixtures,
ScoutParallelWorkerFixtures,
} from './src/playwright';

export type { Client, KbnClient, KibanaUrl, SamlSessionManager, ToolingLog } from './src/types';
5 changes: 3 additions & 2 deletions packages/kbn-scout/src/common/services/kibana_url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ export class KibanaUrl {
* @param appName name of the app to get the URL for
* @param options optional modifications to apply to the URL
*/
app(appName: string, options?: PathOptions) {
return this.get(`/app/${appName}`, options);
app(appName: string, options?: { space?: string; pathOptions?: PathOptions }) {
const relPath = options?.space ? `s/${options.space}/app/${appName}` : `/app/${appName}`;
return this.get(relPath, options?.pathOptions);
}

toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function createPlaywrightConfig(options: ScoutPlaywrightOptions): Playwri

return defineConfig<ScoutTestOptions>({
testDir: options.testDir,
globalSetup: options.globalSetup,
/* Run tests in files in parallel */
fullyParallel: false,
/* Fail the build on CI if you accidentally left test.only in the source code. */
Expand Down
19 changes: 2 additions & 17 deletions packages/kbn-scout/src/playwright/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,5 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { mergeTests } from '@playwright/test';

import { scoutWorkerFixtures } from './worker';
import { scoutTestFixtures } from './test';

export const scoutCoreFixtures = mergeTests(scoutWorkerFixtures, scoutTestFixtures);

export type {
EsArchiverFixture,
ScoutTestFixtures,
ScoutWorkerFixtures,
ScoutPage,
Client,
KbnClient,
KibanaUrl,
ToolingLog,
} from './types';
export * from './single_thread_fixtures';
export * from './parallel_run_fixtures';
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { mergeTests } from 'playwright/test';
import { coreWorkerFixtures, scoutSpaceParallelFixture } from './worker';
import type {
EsClient,
KbnClient,
KibanaUrl,
ScoutSpaceParallelFixture,
ScoutTestConfig,
ToolingLog,
} from './worker';
import {
scoutPageParallelFixture,
browserAuthParallelFixture,
pageObjectsParallelFixture,
validateTagsFixture,
} from './test';
import type { BrowserAuthFixture, ScoutPage, PageObjects } from './test';

export const scoutParallelFixtures = mergeTests(
// worker scope fixtures
coreWorkerFixtures,
scoutSpaceParallelFixture,
// test scope fixtures
browserAuthParallelFixture,
scoutPageParallelFixture,
pageObjectsParallelFixture,
validateTagsFixture
);

export interface ScoutParallelTestFixtures {
browserAuth: BrowserAuthFixture;
page: ScoutPage;
pageObjects: PageObjects;
}

export interface ScoutParallelWorkerFixtures {
log: ToolingLog;
config: ScoutTestConfig;
kbnUrl: KibanaUrl;
kbnClient: KbnClient;
esClient: EsClient;
scoutSpace: ScoutSpaceParallelFixture;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { mergeTests } from 'playwright/test';
import { coreWorkerFixtures, esArchiverFixture, uiSettingsFixture } from './worker';
import type {
EsArchiverFixture,
EsClient,
KbnClient,
KibanaUrl,
ScoutTestConfig,
ToolingLog,
UiSettingsFixture,
} from './worker';
import {
scoutPageFixture,
browserAuthFixture,
pageObjectsFixture,
validateTagsFixture,
BrowserAuthFixture,
ScoutPage,
PageObjects,
} from './test';
export type { PageObjects, ScoutPage } from './test';

export const scoutFixtures = mergeTests(
// worker scope fixtures
coreWorkerFixtures,
esArchiverFixture,
uiSettingsFixture,
// test scope fixtures
browserAuthFixture,
scoutPageFixture,
pageObjectsFixture,
validateTagsFixture
);

export interface ScoutTestFixtures {
browserAuth: BrowserAuthFixture;
page: ScoutPage;
pageObjects: PageObjects;
}

export interface ScoutWorkerFixtures {
log: ToolingLog;
config: ScoutTestConfig;
kbnUrl: KibanaUrl;
kbnClient: KbnClient;
esClient: EsClient;
esArchiver: EsArchiverFixture;
uiSettings: UiSettingsFixture;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

export type LoginFunction = (role: string) => Promise<void>;

export interface BrowserAuthFixture {
/**
* Logs in as a user with viewer-only permissions.
* @returns A Promise that resolves once the cookie in browser is set.
*/
loginAsViewer: () => Promise<void>;
/**
* Logs in as a user with administrative privileges
* @returns A Promise that resolves once the cookie in browser is set.
*/
loginAsAdmin: () => Promise<void>;
/**
* Logs in as a user with elevated, but not admin, permissions.
* @returns A Promise that resolves once the cookie in browser is set.
*/
loginAsPrivilegedUser: () => Promise<void>;
}

export { browserAuthParallelFixture } from './parallel';
export { browserAuthFixture } from './single_thread';
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { BrowserAuthFixture, LoginFunction } from '.';
import { PROJECT_DEFAULT_ROLES } from '../../../../common';
import { serviceLoadedMsg } from '../../../utils';
import { coreWorkerFixtures } from '../../worker';
import { ScoutSpaceParallelFixture } from '../../worker/scout_space';

/**
* The "browserAuth" fixture simplifies the process of logging into Kibana with
* different roles during tests. It uses the "samlAuth" fixture to create an authentication session
* for the specified role and the "context" fixture to update the cookie with the role-scoped session.
*/
export const browserAuthParallelFixture = coreWorkerFixtures.extend<
{ browserAuth: BrowserAuthFixture },
{ scoutSpace: ScoutSpaceParallelFixture }
>({
browserAuth: async ({ log, context, samlAuth, config, scoutSpace }, use) => {
const setSessionCookie = async (cookieValue: string) => {
await context.clearCookies();
await context.addCookies([
{
name: 'sid',
value: cookieValue,
path: '/',
domain: 'localhost',
},
]);
};

const loginAs: LoginFunction = async (role) => {
const spaceId = scoutSpace.id;
const cookie = await samlAuth.getInteractiveUserSessionCookieWithRoleScope(role, { spaceId });
await setSessionCookie(cookie);
};

const loginAsAdmin = () => loginAs('admin');
const loginAsViewer = () => loginAs('viewer');
const loginAsPrivilegedUser = () => {
const roleName = config.serverless
? PROJECT_DEFAULT_ROLES.get(config.projectType!)!
: 'editor';
return loginAs(roleName);
};

log.debug(serviceLoadedMsg(`browserAuth:${scoutSpace.id}`));
await use({ loginAsAdmin, loginAsViewer, loginAsPrivilegedUser });
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,17 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { test as base } from '@playwright/test';
import { PROJECT_DEFAULT_ROLES } from '../../../common';
import { LoginFixture, ScoutWorkerFixtures } from '../types';
import { serviceLoadedMsg } from '../../utils';

type LoginFunction = (role: string) => Promise<void>;
import { PROJECT_DEFAULT_ROLES } from '../../../../common';
import { serviceLoadedMsg } from '../../../utils';
import { coreWorkerFixtures } from '../../worker';
import { BrowserAuthFixture, LoginFunction } from '.';

/**
* The "browserAuth" fixture simplifies the process of logging into Kibana with
* different roles during tests. It uses the "samlAuth" fixture to create an authentication session
* for the specified role and the "context" fixture to update the cookie with the role-scoped session.
*/
export const browserAuthFixture = base.extend<{ browserAuth: LoginFixture }, ScoutWorkerFixtures>({
export const browserAuthFixture = coreWorkerFixtures.extend<{ browserAuth: BrowserAuthFixture }>({
browserAuth: async ({ log, context, samlAuth, config }, use) => {
const setSessionCookie = async (cookieValue: string) => {
await context.clearCookies();
Expand Down
19 changes: 7 additions & 12 deletions packages/kbn-scout/src/playwright/fixtures/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,10 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { mergeTests } from '@playwright/test';
import { browserAuthFixture } from './browser_auth';
import { scoutPageFixture } from './page';
import { pageObjectsFixture } from './page_objects';
import { validateTagsFixture } from './validate_tags';

export const scoutTestFixtures = mergeTests(
browserAuthFixture,
scoutPageFixture,
pageObjectsFixture,
validateTagsFixture
);
export { browserAuthFixture, browserAuthParallelFixture } from './browser_auth';
export type { BrowserAuthFixture } from './browser_auth';
export { scoutPageFixture, scoutPageParallelFixture } from './scout_page';
export type { ScoutPage } from './scout_page';
export { validateTagsFixture } from './validate_tags';
export { pageObjectsFixture, pageObjectsParallelFixture } from './page_objects';
export type { PageObjects } from './page_objects';
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

export type LoginFunction = (role: string) => Promise<void>;

export type { PageObjects } from '../../../page_objects';

export { pageObjectsParallelFixture } from './parallel';
export { pageObjectsFixture } from './single_thread';
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { PageObjects, createCorePageObjects } from '../../../page_objects';
import { serviceLoadedMsg } from '../../../utils';
import { ScoutSpaceParallelFixture } from '../../worker';
import { scoutPageParallelFixture } from '../scout_page';

/**
* The "pageObjects" fixture provides a centralized and consistent way to access and
* interact with reusable Page Objects in tests. This fixture automatically
* initializes core Page Objects and makes them available to tests, promoting
* modularity and reducing redundant setup.
*
* Note: Page Objects are lazily instantiated on first access.
*/
export const pageObjectsParallelFixture = scoutPageParallelFixture.extend<
{
pageObjects: PageObjects;
},
{ scoutSpace: ScoutSpaceParallelFixture }
>({
pageObjects: async ({ page, log, scoutSpace }, use) => {
const corePageObjects = createCorePageObjects(page);
log.debug(serviceLoadedMsg(`pageObjects:${scoutSpace.id}`));
await use(corePageObjects);
},
});
Loading
Loading