Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c94ec44
[scout] use project deps as global hooks for parallel tests
dmlemeshko Feb 17, 2025
877dd6f
[CI] Auto-commit changed files from 'node scripts/styled_components_m…
kibanamachine Feb 17, 2025
fea8235
Merge remote-tracking branch 'upstream/main' into scout/use-project-d…
dmlemeshko Feb 17, 2025
bea8083
Merge branch 'main' into scout/use-project-deps-for-setup-hook
dmlemeshko Feb 17, 2025
e515789
fix test
dmlemeshko Feb 17, 2025
635d3ec
Merge branch 'main' into scout/use-project-deps-for-setup-hook
dmlemeshko Feb 17, 2025
a587e61
Merge branch 'scout/use-project-deps-for-setup-hook' of github.com:dm…
dmlemeshko Feb 17, 2025
00a4836
Merge remote-tracking branch 'upstream/main' into scout/use-project-d…
dmlemeshko Mar 4, 2025
ec41d69
fix the test
dmlemeshko Mar 4, 2025
c3067e6
Merge branch 'main' into scout/use-project-deps-for-setup-hook
dmlemeshko Mar 7, 2025
78750fc
use 'testTarget' flag
dmlemeshko Mar 7, 2025
2784c92
Merge branch 'main' into scout/use-project-deps-for-setup-hook
dmlemeshko Mar 10, 2025
dd209a8
update apm tests
dmlemeshko Mar 10, 2025
2666497
update tests, POs, imports
dmlemeshko Mar 10, 2025
c44c2ec
[CI] Auto-commit changed files from 'node scripts/styled_components_m…
kibanamachine Mar 10, 2025
f9b78bd
Merge remote-tracking branch 'upstream/main' into scout/use-project-d…
dmlemeshko Mar 11, 2025
40aec68
update global_setup
dmlemeshko Mar 11, 2025
b94cecc
fix service and speedup tests
dmlemeshko Mar 11, 2025
bdc3907
update eslint rules
dmlemeshko Mar 11, 2025
f4e15e0
add missing await
dmlemeshko Mar 11, 2025
44393bf
Update .eslintrc.js
dmlemeshko Mar 11, 2025
9fc55bd
Merge branch 'main' into scout/use-project-deps-for-setup-hook
dmlemeshko Mar 11, 2025
bf1af52
review fixes
dmlemeshko Mar 12, 2025
dd37a3b
Revert "review fixes"
dmlemeshko Mar 12, 2025
5dea2ff
enforce using project flag
dmlemeshko Mar 12, 2025
20cf7a7
add comment about project flag
dmlemeshko Mar 12, 2025
089e756
Merge branch 'main' into scout/use-project-deps-for-setup-hook
dmlemeshko Mar 12, 2025
108554c
copy main project context to setup project
dmlemeshko Mar 12, 2025
c1ade3a
Update x-pack/solutions/observability/plugins/apm/ui_tests/README.md
dmlemeshko Mar 12, 2025
c8ec61a
Merge branch 'main' into scout/use-project-deps-for-setup-hook
dmlemeshko Mar 12, 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
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,19 @@ import { getRunTarget, stripRunCommand } from './cli_processing';
describe('cli_processing', () => {
describe('stripRunCommand', () => {
it(`should return the correct run command when started with 'npx'`, () => {
const argv = ['npx', 'playwright', 'test', '--config', 'path/to/config', '--grep=@svlSearch'];
const argv = [
'npx',
'playwright',
'test',
'--config',
'path/to/config',
'--project',
'local',
'--grep=@svlSearch',
];

expect(stripRunCommand(argv)).toBe(
'npx playwright test --config path/to/config --grep=@svlSearch'
'npx playwright test --config path/to/config --project local --grep=@svlSearch'
);
});

Expand All @@ -26,11 +35,13 @@ describe('cli_processing', () => {
'test',
'--config',
'path/to/config',
'--project',
'local',
'--grep=@svlSearch',
];

expect(stripRunCommand(argv)).toBe(
'npx playwright test --config path/to/config --grep=@svlSearch'
'npx playwright test --config path/to/config --project local --grep=@svlSearch'
);
});

Expand Down
2 changes: 1 addition & 1 deletion src/platform/packages/shared/kbn-scout/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ If the servers are already running, you can execute tests independently using ei
- Command Line: Use the following command to run tests:

```bash
npx playwright test --config <plugin-path>/ui_tests/playwright.config.ts
npx playwright test --config <plugin-path>/ui_tests/playwright.config.ts --project local
Comment thread
dmlemeshko marked this conversation as resolved.
```

### Contributing
Expand Down
1 change: 1 addition & 0 deletions src/platform/packages/shared/kbn-scout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export {
expect,
test,
spaceTest,
globalSetupHook,
tags,
createPlaywrightConfig,
createLazyPageObject,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe('createPlaywrightConfig', () => {
expect(config.fullyParallel).toBe(false);
expect(config.use).toEqual({
serversConfigDir: SCOUT_SERVERS_ROOT,
configName: 'local',
[VALID_CONFIG_MARKER]: true,
screenshot: 'only-on-failure',
testIdAttribute: 'data-test-subj',
Expand All @@ -64,7 +65,8 @@ describe('createPlaywrightConfig', () => {
expect(config.timeout).toBe(60000);
expect(config.expect?.timeout).toBe(10000);
expect(config.outputDir).toBe('./output/test-artifacts');
expect(config.projects![0].name).toEqual('chromium');
expect(config.projects).toHaveLength(1);
expect(config.projects![0].name).toEqual('local');
});

it('should return a Playwright configuration with Scout reporters', () => {
Expand Down Expand Up @@ -96,12 +98,17 @@ describe('createPlaywrightConfig', () => {
]);
});

it(`should override 'workers' count in Playwright configuration`, () => {
it(`should override 'workers' count and add 'setup' project dependency`, () => {
const testDir = './my_tests';
const workers = 2;

const config = createPlaywrightConfig({ testDir, workers });
expect(config.workers).toBe(workers);

expect(config.projects).toHaveLength(2);
expect(config.projects![0].name).toEqual('setup');
expect(config.projects![1].name).toEqual('local');
expect(config.projects![1]).toHaveProperty('dependencies', ['setup']);
});

it('should generate and cache runId in process.env.TEST_RUN_ID', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,31 @@ export function createPlaywrightConfig(options: ScoutPlaywrightOptions): Playwri
process.env.TEST_RUN_ID = runId;
}

const scoutProjects: PlaywrightTestConfig<ScoutTestOptions>['projects'] = [
{
name: 'local',
use: { ...devices['Desktop Chrome'], configName: 'local' },

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

each project will override default configName to pass source of servers configuration ('local.json', 'cloud-mki', 'cloud-ech', etc)

},
];

/**
* For parallel tests, we need to add a setup project that runs before the tests project.
*/
if (options.workers && options.workers > 1) {
scoutProjects.unshift({
name: 'setup',
testMatch: /global.setup\.ts/,
});

scoutProjects.forEach((project) => {
if (project.name !== 'setup') {
project.dependencies = ['setup'];
}
});
}

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 All @@ -49,6 +71,7 @@ export function createPlaywrightConfig(options: ScoutPlaywrightOptions): Playwri
use: {
testIdAttribute: 'data-test-subj',
serversConfigDir: SCOUT_SERVERS_ROOT,
configName: 'local',
[VALID_CONFIG_MARKER]: true,
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://127.0.0.1:3000',
Expand All @@ -70,24 +93,6 @@ export function createPlaywrightConfig(options: ScoutPlaywrightOptions): Playwri

outputDir: './output/test-artifacts', // For other test artifacts (screenshots, videos, traces)

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},

// {
// name: 'firefox',
// use: { ...devices['Desktop Firefox'] },
// },
],

/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// url: 'http://127.0.0.1:3000',
// reuseExistingServer: !process.env.CI,
// },
projects: scoutProjects,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
*/

import { mergeTests } from 'playwright/test';
import { apiFixtures, coreWorkerFixtures, scoutSpaceParallelFixture } from './worker';
import {
apiFixtures,
coreWorkerFixtures,
esArchiverFixture,
scoutSpaceParallelFixture,
synthtraceFixture,
} from './worker';
import type {
ApiParallelWorkerFixtures,
EsClient,
Expand Down Expand Up @@ -52,3 +58,10 @@ export interface ScoutParallelWorkerFixtures extends ApiParallelWorkerFixtures {
esClient: EsClient;
scoutSpace: ScoutSpaceParallelFixture;
}

export const globalSetup = mergeTests(
coreWorkerFixtures,
esArchiverFixture,
synthtraceFixture,
apiFixtures
);
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,14 @@ export const coreWorkerFixtures = base.extend<
*/
config: [
({ log }, use, testInfo) => {
const configName = 'local';
const projectUse = testInfo.project.use as ScoutTestOptions;
if (!projectUse.configName) {
throw new Error(
'Invalid Playwright project configuration. Make sure to set "configName" property'
Comment thread
csr marked this conversation as resolved.
Outdated
);
}
const serversConfigDir = projectUse.serversConfigDir;
const configInstance = createScoutConfig(serversConfigDir, configName, log);
const configInstance = createScoutConfig(serversConfigDir, projectUse.configName, log);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

projectUse.configName should match filename in .scout/servers local directory


use(configInstance);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { scoutFixtures, scoutParallelFixtures } from './fixtures';
import { scoutFixtures, scoutParallelFixtures, globalSetup } from './fixtures';

// Scout core fixtures: worker & test scope
export const test = scoutFixtures;

// Scout core 'space aware' fixtures: worker & test scope
export const spaceTest = scoutParallelFixtures;

export const globalSetupHook = globalSetup;

export { createPlaywrightConfig } from './config';
export { createLazyPageObject } from './page_objects/utils';
export { expect } from './expect';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ describe('parseTestFlags', () => {
expect(result).toEqual({
mode: 'serverless=oblt',
configPath: '/path/to/config',
env: 'local',
headed: false,
esFrom: undefined,
installDir: undefined,
Expand All @@ -82,6 +83,7 @@ describe('parseTestFlags', () => {
it(`should parse with correct config and stateful flags`, async () => {
const flags = new FlagsReader({
config: '/path/to/config',
env: 'local',
stateful: true,
logToFile: false,
headed: true,
Expand All @@ -93,6 +95,7 @@ describe('parseTestFlags', () => {
expect(result).toEqual({
mode: 'stateful',
configPath: '/path/to/config',
env: 'local',
headed: true,
esFrom: 'snapshot',
installDir: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface RunTestsOptions {
configPath: string;
headed: boolean;
mode: CliSupportedServerModes;
env: 'local' | 'cloud';
Comment thread
dmlemeshko marked this conversation as resolved.
Outdated
esFrom: 'serverless' | 'source' | 'snapshot' | undefined;
installDir: string | undefined;
logsDir: string | undefined;
Expand All @@ -28,17 +29,23 @@ export const TEST_FLAG_OPTIONS: FlagOptions = {
...SERVER_FLAG_OPTIONS,
boolean: [...(SERVER_FLAG_OPTIONS.boolean || []), 'headed'],
string: [...(SERVER_FLAG_OPTIONS.string || []), 'config'],
default: { headed: false },
default: { headed: false, env: 'local' },
help: `${SERVER_FLAG_OPTIONS.help}
--config Playwright config file path
--headed Run Playwright with browser head
--env Run tests agaist locally started servers or Cloud deployment / MKI project
`,
};

export async function parseTestFlags(flags: FlagsReader) {
const options = parseServerFlags(flags);
const configPath = flags.string('config');
const headed = flags.boolean('headed');
const env = flags.enum('env', ['local', 'cloud']) || 'local';

if (env === 'cloud') {
throw createFlagError(`Running tests against Cloud / MKI is not supported yet`);
}

if (!configPath) {
throw createFlagError(`Path to playwright config is required: --config <file path>`);
Expand All @@ -51,5 +58,6 @@ export async function parseTestFlags(flags: FlagsReader) {
...options,
configPath,
headed,
env,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ export async function runTests(log: ToolingLog, options: RunTestsOptions) {
const playwrightConfigPath = options.configPath;

const cmd = resolve(REPO_ROOT, './node_modules/.bin/playwright');
const cmdArgs = ['test', `--config=${playwrightConfigPath}`, `--grep=${playwrightGrepTag}`];
const cmdArgs = [
'test',
`--config=${playwrightConfigPath}`,
`--grep=${playwrightGrepTag}`,
`--project=${options.env}`,
];

await withProcRunner(log, async (procs) => {
log.info(`scout: Validate Playwright config has tests`);
Expand Down Expand Up @@ -78,7 +83,7 @@ export async function runTests(log: ToolingLog, options: RunTestsOptions) {
// wait for 5 seconds
await silence(log, 5000);

// Running 'npx playwright test --config=${playwrightConfigPath}'
// Running 'npx playwright test --config=${playwrightConfigPath} --project local'
await procs.run(`playwright`, {
cmd,
args: [...cmdArgs, ...(options.headed ? ['--headed'] : [])],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ export type Protocol = 'http' | 'https';

export const VALID_CONFIG_MARKER = Symbol('validConfig');

export type ScoutConfigName = 'local';

export interface ScoutTestOptions extends PlaywrightTestOptions {
serversConfigDir: string;
configName: ScoutConfigName;
[VALID_CONFIG_MARKER]: boolean;
}

export interface ScoutPlaywrightOptions
extends Pick<PlaywrightTestConfig, 'testDir' | 'workers' | 'globalSetup'> {
export interface ScoutPlaywrightOptions extends Pick<PlaywrightTestConfig, 'testDir' | 'workers'> {
testDir: string;
workers?: 1 | 2 | 3; // to keep performance consistent within test suites
globalSetup?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export async function startServers(log: ToolingLog, options: StartServerOptions)
'\n\n' +
dedent`
Elasticsearch and Kibana are ready for functional testing.
Use 'npx playwright test --config <path_to_Playwright.config.ts>' to run tests'
Use 'npx playwright test --config <path_to_Playwright.config.ts> --project local' to run tests'
` +
'\n\n'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ Then you can run the tests multiple times in another terminal with:

```bash
// ESS
npx playwright test --config x-pack/platform/plugins/private/discover_enhanced/ui_tests/playwright.config.ts --grep @ess
npx playwright test --config x-pack/platform/plugins/private/discover_enhanced/ui_tests/playwright.config.ts --project local --grep @ess

// Serverless
npx playwright test --config x-pack/platform/plugins/private/discover_enhanced/ui_tests/playwright.config.ts --grep @svlSearch
npx playwright test --config x-pack/platform/plugins/private/discover_enhanced/ui_tests/playwright.config.ts --project local --grep @svlSearch

// @svlOblt, @svlSecurity
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { createPlaywrightConfig } from '@kbn/scout';

// eslint-disable-next-line import/no-default-export
export default createPlaywrightConfig({
globalSetup: require.resolve('./parallel_tests/global_setup'),
testDir: './parallel_tests',
workers: 2,
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@
* 2.0.
*/

import { ingestTestDataHook } from '@kbn/scout';
import { type FullConfig } from '@playwright/test';
import { globalSetupHook } from '@kbn/scout';
import { testData } from '../fixtures';

async function globalSetup(config: FullConfig) {
globalSetupHook('Ingest data to Elasticsearch', async ({ esArchiver, log }) => {
// add archives to load, if needed
const archives = [
testData.ES_ARCHIVES.LOGSTASH,
testData.ES_ARCHIVES.NO_TIME_FIELD,
testData.ES_ARCHIVES.ECOMMERCE,
];

return ingestTestDataHook(config, archives);
}

// eslint-disable-next-line import/no-default-export
export default globalSetup;
log.debug('[setup] loading test data (only if indexes do not exist)...');
for (const archive of archives) {
await esArchiver.loadIfNeeded(archive);
}
});
Loading