diff --git a/.eslintrc.js b/.eslintrc.js index b1ea75213aa5b..0d4cbc2f8fb47 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1471,7 +1471,8 @@ module.exports = { 'playwright/no-slowed-test': 'error', 'playwright/no-standalone-expect': 'error', 'playwright/no-unsafe-references': 'error', - 'playwright/no-wait-for-selector': 'warn', + 'playwright/no-useless-await': 'error', + 'playwright/no-wait-for-selector': 'error', 'playwright/max-nested-describe': ['error', { max: 1 }], 'playwright/missing-playwright-await': 'error', 'playwright/prefer-comparison-matcher': 'error', diff --git a/src/platform/packages/private/kbn-scout-reporting/src/helpers/cli_processing.test.ts b/src/platform/packages/private/kbn-scout-reporting/src/helpers/cli_processing.test.ts index 7f37884517014..3c42aa54b367d 100644 --- a/src/platform/packages/private/kbn-scout-reporting/src/helpers/cli_processing.test.ts +++ b/src/platform/packages/private/kbn-scout-reporting/src/helpers/cli_processing.test.ts @@ -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' ); }); @@ -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' ); }); diff --git a/src/platform/packages/shared/kbn-scout/README.md b/src/platform/packages/shared/kbn-scout/README.md index 12515588aa12d..7e4235e64f092 100644 --- a/src/platform/packages/shared/kbn-scout/README.md +++ b/src/platform/packages/shared/kbn-scout/README.md @@ -186,9 +186,11 @@ 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 /ui_tests/playwright.config.ts +npx playwright test --config /ui_tests/playwright.config.ts --project local ``` +We use `project` flag to define test target, where tests to be run: local servers or Elastic Cloud. Currently we only support local servers. + ### Contributing We welcome contributions to improve and extend `kbn-scout`. This guide will help you get started, add new features, and align with existing project standards. diff --git a/src/platform/packages/shared/kbn-scout/index.ts b/src/platform/packages/shared/kbn-scout/index.ts index ed0d18bd17ef8..c94ff296c54cc 100644 --- a/src/platform/packages/shared/kbn-scout/index.ts +++ b/src/platform/packages/shared/kbn-scout/index.ts @@ -12,11 +12,10 @@ export { expect, test, spaceTest, + globalSetupHook, tags, createPlaywrightConfig, createLazyPageObject, - ingestTestDataHook, - ingestSynthtraceDataHook, } from './src/playwright'; export type { ScoutPlaywrightOptions, diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/config/create_config.test.ts b/src/platform/packages/shared/kbn-scout/src/playwright/config/create_config.test.ts index 08eab1ab15cb1..7fd7bfe6f14d7 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/config/create_config.test.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/config/create_config.test.ts @@ -64,7 +64,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', () => { @@ -96,12 +97,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', () => { diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/config/create_config.ts b/src/platform/packages/shared/kbn-scout/src/playwright/config/create_config.ts index 452f09a64cd66..bb83c16dbf3e7 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/config/create_config.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/config/create_config.ts @@ -27,9 +27,34 @@ export function createPlaywrightConfig(options: ScoutPlaywrightOptions): Playwri process.env.TEST_RUN_ID = runId; } + const scoutProjects: PlaywrightTestConfig['projects'] = [ + { + name: 'local', + use: { ...devices['Desktop Chrome'], configName: 'local' }, + }, + ]; + + /** + * For parallel tests, we need to add a setup project that runs before the tests project. + */ + if (options.workers && options.workers > 1) { + const parentProject = scoutProjects.find((p) => p.use?.configName); + + scoutProjects.unshift({ + name: 'setup', + use: parentProject?.use ? { ...parentProject.use } : {}, + testMatch: /global.setup\.ts/, + }); + + scoutProjects.forEach((project) => { + if (project.name !== 'setup') { + project.dependencies = ['setup']; + } + }); + } + return defineConfig({ 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. */ @@ -47,6 +72,7 @@ export function createPlaywrightConfig(options: ScoutPlaywrightOptions): Playwri ], /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { + // 'configName' is not defined by default to enforce using '--project' flag when running the tests testIdAttribute: 'data-test-subj', serversConfigDir: SCOUT_SERVERS_ROOT, [VALID_CONFIG_MARKER]: true, @@ -70,24 +96,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, }); } diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/parallel_run_fixtures.ts b/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/parallel_run_fixtures.ts index 7638b0eb91a2c..381d61dd501d3 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/parallel_run_fixtures.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/parallel_run_fixtures.ts @@ -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, @@ -52,3 +58,10 @@ export interface ScoutParallelWorkerFixtures extends ApiParallelWorkerFixtures { esClient: EsClient; scoutSpace: ScoutSpaceParallelFixture; } + +export const globalSetup = mergeTests( + coreWorkerFixtures, + esArchiverFixture, + synthtraceFixture, + apiFixtures +); diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/worker/core_fixtures.ts b/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/worker/core_fixtures.ts index c861985aa7e4d..c59d53d99526d 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/worker/core_fixtures.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/worker/core_fixtures.ts @@ -66,10 +66,15 @@ export const coreWorkerFixtures = base.extend< */ config: [ ({ log }, use, workerInfo) => { - const configName = 'local'; const projectUse = workerInfo.project.use as ScoutTestOptions; + if (!projectUse.configName) { + throw new Error( + `Failed to read the 'configName' property. Make sure to run tests with '--project' flag and target enviroment (local or cloud), + e.g. 'npx playwright test --project local --config '` + ); + } const serversConfigDir = projectUse.serversConfigDir; - const configInstance = createScoutConfig(serversConfigDir, configName, log); + const configInstance = createScoutConfig(serversConfigDir, projectUse.configName, log); use(configInstance); }, diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/worker/synthtrace.ts b/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/worker/synthtrace.ts index f82cd962fb7de..93adc03c81a03 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/worker/synthtrace.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/worker/synthtrace.ts @@ -8,7 +8,13 @@ */ import { Readable } from 'stream'; -import type { ApmFields, Fields, InfraDocument, OtelDocument } from '@kbn/apm-synthtrace-client'; +import type { + ApmFields, + Fields, + InfraDocument, + OtelDocument, + SynthtraceGenerator, +} from '@kbn/apm-synthtrace-client'; import Url from 'url'; import type { SynthtraceEsClient } from '@kbn/apm-synthtrace/src/lib/shared/base_client'; import { @@ -17,10 +23,9 @@ import { getOtelSynthtraceEsClient, } from '../../../common/services/synthtrace'; import { coreWorkerFixtures } from './core_fixtures'; -import type { SynthtraceEvents } from '../../global_hooks/synthtrace_ingestion'; interface SynthtraceFixtureEsClient { - index: (events: SynthtraceEvents) => Promise; + index: (events: SynthtraceGenerator) => Promise; clean: SynthtraceEsClient['clean']; } @@ -34,15 +39,12 @@ const useSynthtraceClient = async ( client: SynthtraceEsClient, use: (client: SynthtraceFixtureEsClient) => Promise ) => { - const index = async (events: SynthtraceEvents) => + const index = async (events: SynthtraceGenerator) => await client.index(Readable.from(Array.from(events).flatMap((event) => event.serialize()))); const clean = async () => await client.clean(); await use({ index, clean }); - - // cleanup function after all tests have ran - await client.clean(); }; export const synthtraceFixture = coreWorkerFixtures.extend<{}, SynthtraceFixture>({ diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/global_hooks/synthtrace_ingestion.ts b/src/platform/packages/shared/kbn-scout/src/playwright/global_hooks/synthtrace_ingestion.ts index 7af809f66801b..447ee12c47098 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/global_hooks/synthtrace_ingestion.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/global_hooks/synthtrace_ingestion.ts @@ -65,6 +65,9 @@ const getSynthtraceClient = ( } }; +/** + * @deprecated Use `globalSetupHook` and synthtrace fixtures instead + */ export async function ingestSynthtraceDataHook(config: FullConfig, data: SynthtraceIngestionData) { const log = getLogger(); diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/index.ts b/src/platform/packages/shared/kbn-scout/src/playwright/index.ts index 0f6d62a176c35..579596822688c 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/index.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/index.ts @@ -7,7 +7,7 @@ * 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; @@ -15,6 +15,8 @@ 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'; diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/runner/flags.test.ts b/src/platform/packages/shared/kbn-scout/src/playwright/runner/flags.test.ts index 94683146e5278..a310659e3f1c0 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/runner/flags.test.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/runner/flags.test.ts @@ -72,6 +72,7 @@ describe('parseTestFlags', () => { expect(result).toEqual({ mode: 'serverless=oblt', configPath: '/path/to/config', + testTarget: 'local', headed: false, esFrom: undefined, installDir: undefined, @@ -82,6 +83,7 @@ describe('parseTestFlags', () => { it(`should parse with correct config and stateful flags`, async () => { const flags = new FlagsReader({ config: '/path/to/config', + testTarget: 'local', stateful: true, logToFile: false, headed: true, @@ -93,10 +95,41 @@ describe('parseTestFlags', () => { expect(result).toEqual({ mode: 'stateful', configPath: '/path/to/config', + testTarget: 'local', headed: true, esFrom: 'snapshot', installDir: undefined, logsDir: undefined, }); }); + + it(`should throw an error with incorrect '--testTarget' flag`, async () => { + const flags = new FlagsReader({ + config: '/path/to/config', + testTarget: 'a', + stateful: true, + logToFile: false, + headed: true, + esFrom: 'snapshot', + }); + + await expect(parseTestFlags(flags)).rejects.toThrow( + 'invalid --testTarget, expected one of "local", "cloud"' + ); + }); + + it(`should throw an error with incorrect '--testTarget' flag set to 'cloud'`, async () => { + const flags = new FlagsReader({ + config: '/path/to/config', + testTarget: 'cloud', + stateful: true, + logToFile: false, + headed: true, + esFrom: 'snapshot', + }); + validatePlaywrightConfigMock.mockResolvedValueOnce(); + await expect(parseTestFlags(flags)).rejects.toThrow( + 'Running tests against Cloud / MKI is not supported yet' + ); + }); }); diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/runner/flags.ts b/src/platform/packages/shared/kbn-scout/src/playwright/runner/flags.ts index e5bded7d6f1c2..38d997a5d4191 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/runner/flags.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/runner/flags.ts @@ -19,6 +19,7 @@ export interface RunTestsOptions { configPath: string; headed: boolean; mode: CliSupportedServerModes; + testTarget: 'local' | 'cloud'; esFrom: 'serverless' | 'source' | 'snapshot' | undefined; installDir: string | undefined; logsDir: string | undefined; @@ -27,11 +28,12 @@ export interface RunTestsOptions { export const TEST_FLAG_OPTIONS: FlagOptions = { ...SERVER_FLAG_OPTIONS, boolean: [...(SERVER_FLAG_OPTIONS.boolean || []), 'headed'], - string: [...(SERVER_FLAG_OPTIONS.string || []), 'config'], - default: { headed: false }, + string: [...(SERVER_FLAG_OPTIONS.string || []), 'config', 'testTarget'], + default: { headed: false, testTarget: 'local' }, help: `${SERVER_FLAG_OPTIONS.help} --config Playwright config file path --headed Run Playwright with browser head + --testTarget Run tests agaist locally started servers or Cloud deployment / MKI project `, }; @@ -39,6 +41,11 @@ export async function parseTestFlags(flags: FlagsReader) { const options = parseServerFlags(flags); const configPath = flags.string('config'); const headed = flags.boolean('headed'); + const testTarget = flags.enum('testTarget', ['local', 'cloud']) || 'local'; + + if (testTarget === 'cloud') { + throw createFlagError(`Running tests against Cloud / MKI is not supported yet`); + } if (!configPath) { throw createFlagError(`Path to playwright config is required: --config `); @@ -51,5 +58,6 @@ export async function parseTestFlags(flags: FlagsReader) { ...options, configPath, headed, + testTarget, }; } diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/runner/run_tests.ts b/src/platform/packages/shared/kbn-scout/src/playwright/runner/run_tests.ts index 8753ba6d4b519..2b33f85923c32 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/runner/run_tests.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/runner/run_tests.ts @@ -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.testTarget}`, + ]; await withProcRunner(log, async (procs) => { log.info(`scout: Validate Playwright config has tests`); @@ -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'] : [])], diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/types/index.ts b/src/platform/packages/shared/kbn-scout/src/playwright/types/index.ts index 78a40ff4f1c65..8bb657cb93434 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/types/index.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/types/index.ts @@ -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 { +export interface ScoutPlaywrightOptions extends Pick { testDir: string; workers?: 1 | 2 | 3; // to keep performance consistent within test suites - globalSetup?: string; } diff --git a/src/platform/packages/shared/kbn-scout/src/servers/start_servers.ts b/src/platform/packages/shared/kbn-scout/src/servers/start_servers.ts index 32eb2030c978d..0d10fa1498401 100644 --- a/src/platform/packages/shared/kbn-scout/src/servers/start_servers.ts +++ b/src/platform/packages/shared/kbn-scout/src/servers/start_servers.ts @@ -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 ' to run tests' + Use 'npx playwright test --config --project local' to run tests' ` + '\n\n' ); diff --git a/x-pack/platform/plugins/private/discover_enhanced/ui_tests/README.md b/x-pack/platform/plugins/private/discover_enhanced/ui_tests/README.md index 93879514adac3..7b7865e048f90 100644 --- a/x-pack/platform/plugins/private/discover_enhanced/ui_tests/README.md +++ b/x-pack/platform/plugins/private/discover_enhanced/ui_tests/README.md @@ -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 ``` diff --git a/x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel.playwright.config.ts b/x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel.playwright.config.ts index 70035f4b5a40c..997f5d57098fa 100644 --- a/x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel.playwright.config.ts +++ b/x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel.playwright.config.ts @@ -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, }); diff --git a/x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel_tests/global_setup.ts b/x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel_tests/global.setup.ts similarity index 61% rename from x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel_tests/global_setup.ts rename to x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel_tests/global.setup.ts index d427909fe87d4..5f029e22dd19f 100644 --- a/x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel_tests/global_setup.ts +++ b/x-pack/platform/plugins/private/discover_enhanced/ui_tests/parallel_tests/global.setup.ts @@ -5,11 +5,10 @@ * 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, @@ -17,8 +16,8 @@ async function globalSetup(config: FullConfig) { 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); + } +}); diff --git a/x-pack/solutions/observability/packages/kbn-scout-oblt/index.ts b/x-pack/solutions/observability/packages/kbn-scout-oblt/index.ts index 804af1d20f7ab..02f539439b5f6 100644 --- a/x-pack/solutions/observability/packages/kbn-scout-oblt/index.ts +++ b/x-pack/solutions/observability/packages/kbn-scout-oblt/index.ts @@ -17,10 +17,10 @@ export type { // re-export from @kbn/scout export { expect, + globalSetupHook, tags, createPlaywrightConfig, createLazyPageObject, - ingestTestDataHook, } from '@kbn/scout'; export type { @@ -29,7 +29,6 @@ export type { KibanaUrl, ScoutLogger, ScoutPage, - PageObjects, ScoutServerConfig, ScoutTestConfig, ScoutPlaywrightOptions, diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/README.md b/x-pack/solutions/observability/plugins/apm/ui_tests/README.md index 68fd9a1fa4127..5e6d71ce07c70 100644 --- a/x-pack/solutions/observability/plugins/apm/ui_tests/README.md +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/README.md @@ -14,10 +14,10 @@ Then you can run the parallel tests in another terminal: ```bash // ESS -npx playwright test --config x-pack/solutions/observability/plugins/apm/ui_tests/parallel.playwright.config.ts --grep @ess +npx playwright test --config x-pack/solutions/observability/plugins/apm/ui_tests/parallel.playwright.config.ts --project=local --grep @ess // Serverless -npx playwright test --config x-pack/solutions/observability/plugins/apm/ui_tests/parallel.playwright.config.ts --grep @svlOblt +npx playwright test --project local --config x-pack/solutions/observability/plugins/apm/ui_tests/parallel.playwright.config.ts --grep @svlOblt ``` Test results are available in `x-pack/solutions/observability/plugins/apm/ui_tests/output` diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/constants.ts b/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/constants.ts new file mode 100644 index 0000000000000..19c6fafe73061 --- /dev/null +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/constants.ts @@ -0,0 +1,9 @@ +/* + * 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. + */ + +export const OPBEANS_START_DATE = '2021-10-10T00:00:00.000Z'; +export const OPBEANS_END_DATE = '2021-10-10T00:15:00.000Z'; diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/index.ts b/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/index.ts index 5c9e4769c2d0d..8cb863b4c31ba 100644 --- a/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/index.ts +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/index.ts @@ -5,19 +5,24 @@ * 2.0. */ -import type { PageObjects, ScoutTestFixtures, ScoutWorkerFixtures, KibanaUrl } from '@kbn/scout'; -import { test as base, createLazyPageObject } from '@kbn/scout'; +import type { + ObltPageObjects, + ObltTestFixtures, + ObltWorkerFixtures, + KibanaUrl, +} from '@kbn/scout-oblt'; +import { test as base, createLazyPageObject } from '@kbn/scout-oblt'; import { ServiceMapPage } from './page_objects/service_map'; import { ServiceInventoryPage } from './page_objects/service_inventory'; -export interface ExtendedScoutTestFixtures extends ScoutTestFixtures { - pageObjects: PageObjects & { +export interface ExtendedScoutTestFixtures extends ObltTestFixtures { + pageObjects: ObltPageObjects & { serviceMapPage: ServiceMapPage; serviceInventoryPage: ServiceInventoryPage; }; } -export const test = base.extend({ +export const test = base.extend({ pageObjects: async ( { pageObjects, @@ -39,3 +44,5 @@ export const test = base.extend( await use(extendedPageObjects); }, }); + +export * as testData from './constants'; diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/page_objects/service_inventory.ts b/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/page_objects/service_inventory.ts index fceff0e6710c9..df8dd98f866a2 100644 --- a/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/page_objects/service_inventory.ts +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/page_objects/service_inventory.ts @@ -5,20 +5,13 @@ * 2.0. */ -import type { KibanaUrl, ScoutPage } from '@kbn/scout'; +import type { KibanaUrl, ScoutPage } from '@kbn/scout-oblt'; export class ServiceInventoryPage { constructor(private readonly page: ScoutPage, private readonly kbnUrl: KibanaUrl) {} - async waitForPageToLoad() { - await this.page.waitForSelector( - '[data-test-subj="kbnAppWrapper visibleChrome"] [aria-busy="false"]', - { state: 'visible' } - ); - } - async gotoDetailedServiceInventoryWithDateSelected(start: string, end: string) { - this.page.goto(`${this.kbnUrl.app('apm')}/services?&rangeFrom=${start}&rangeTo=${end}`); - await this.waitForPageToLoad(); + await this.page.goto(`${this.kbnUrl.app('apm')}/services?&rangeFrom=${start}&rangeTo=${end}`); + return this.page.waitForLoadingIndicatorHidden(); } } diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/page_objects/service_map.ts b/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/page_objects/service_map.ts index fc82c51765e60..6a82a7b54ca80 100644 --- a/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/page_objects/service_map.ts +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/page_objects/service_map.ts @@ -5,36 +5,52 @@ * 2.0. */ -import type { KibanaUrl, ScoutPage } from '@kbn/scout'; +import type { KibanaUrl, Locator, ScoutPage } from '@kbn/scout-oblt'; +import { expect } from '@kbn/scout-oblt'; export class ServiceMapPage { - constructor(private readonly page: ScoutPage, private readonly kbnUrl: KibanaUrl) {} + public serviceMap: Locator; + public zoomInBtn: Locator; + public zoomOutBtn: Locator; + public centerServiceMapBtn: Locator; + public noServicesPlaceholder: Locator; - async waitForPageToLoad() { - await this.page.waitForSelector( - '[data-test-subj="kbnAppWrapper visibleChrome"] [aria-busy="false"]', - { state: 'visible' } - ); + constructor(private readonly page: ScoutPage, private readonly kbnUrl: KibanaUrl) { + this.serviceMap = page.testSubj.locator('serviceMap'); + this.zoomInBtn = page.locator('button[aria-label="Zoom in"]'); + this.zoomOutBtn = page.locator('button[aria-label="Zoom out"]'); + this.centerServiceMapBtn = page.testSubj.locator('centerServiceMap'); + this.noServicesPlaceholder = page.locator('.euiEmptyPrompt__content .euiTitle'); } async gotoWithDateSelected(start: string, end: string) { - this.page.goto(`${this.kbnUrl.app('apm')}/service-map?&rangeFrom=${start}&rangeTo=${end}`); - await this.waitForPageToLoad(); + await this.page.goto( + `${this.kbnUrl.app('apm')}/service-map?&rangeFrom=${start}&rangeTo=${end}` + ); + return this.page.waitForLoadingIndicatorHidden(); } + async gotoDetailedServiceMapWithDateSelected(start: string, end: string) { - this.page.goto( + await this.page.goto( `${this.kbnUrl.app( 'apm' )}/services/opbeans-java/service-map?&rangeFrom=${start}&rangeTo=${end}` ); - await this.waitForPageToLoad(); + return this.page.waitForLoadingIndicatorHidden(); } + async getSearchBar() { await this.page.testSubj.waitForSelector('apmUnifiedSearchBar'); } - async typeInTheSearchBar() { + + async typeInTheSearchBar(text: string) { await this.getSearchBar(); - await this.page.testSubj.typeWithDelay('apmUnifiedSearchBar', '_id : foo'); - await this.page.getByTestId('querySubmitButton').press('Enter'); + await this.page.testSubj.typeWithDelay('apmUnifiedSearchBar', text); + return this.page.getByTestId('querySubmitButton').press('Enter'); + } + + async waitForServiceMapToLoad() { + await this.serviceMap.waitFor({ state: 'visible' }); + return expect(this.serviceMap.getByLabel('Loading')).toBeHidden(); } } diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/synthtrace/opbeans.ts b/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/synthtrace/opbeans.ts index dcfccfb53460b..55d0c090844a1 100644 --- a/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/synthtrace/opbeans.ts +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/fixtures/synthtrace/opbeans.ts @@ -4,9 +4,16 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import type { ApmFields, SynthtraceGenerator } from '@kbn/apm-synthtrace-client'; import { apm, timerange } from '@kbn/apm-synthtrace-client'; -export function opbeans({ from, to }: { from: number; to: number }) { +export function opbeans({ + from, + to, +}: { + from: number; + to: number; +}): SynthtraceGenerator { const range = timerange(from, to); const opbeansJava = apm diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/parallel.playwright.config.ts b/x-pack/solutions/observability/plugins/apm/ui_tests/parallel.playwright.config.ts index 70035f4b5a40c..deadf91cadb21 100644 --- a/x-pack/solutions/observability/plugins/apm/ui_tests/parallel.playwright.config.ts +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/parallel.playwright.config.ts @@ -5,11 +5,10 @@ * 2.0. */ -import { createPlaywrightConfig } from '@kbn/scout'; +import { createPlaywrightConfig } from '@kbn/scout-oblt'; // eslint-disable-next-line import/no-default-export export default createPlaywrightConfig({ - globalSetup: require.resolve('./parallel_tests/global_setup'), testDir: './parallel_tests', workers: 2, }); diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/global_setup.ts b/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/global_setup.ts index 81b0bca98df51..97f22aa5821a5 100644 --- a/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/global_setup.ts +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/global_setup.ts @@ -5,27 +5,16 @@ * 2.0. */ -import { ingestSynthtraceDataHook } from '@kbn/scout'; -import { type FullConfig } from '@playwright/test'; +import { globalSetupHook } from '@kbn/scout-oblt'; +import type { ApmFields, SynthtraceGenerator } from '@kbn/apm-synthtrace-client'; import { opbeans } from '../fixtures/synthtrace/opbeans'; +import { testData } from '../fixtures'; -async function globalSetup(config: FullConfig) { - const start = '2021-10-10T00:00:00.000Z'; - const end = '2021-10-10T00:15:00.000Z'; - const data = { - apm: [ - opbeans({ - from: new Date(start).getTime(), - to: new Date(end).getTime(), - }), - ], - // TODO add infra and otel fixtures - infra: [], - otel: [], - }; +globalSetupHook('Ingest data to Elasticsearch', async ({ apmSynthtraceEsClient }) => { + const dataGenerator: SynthtraceGenerator = opbeans({ + from: new Date(testData.OPBEANS_START_DATE).getTime(), + to: new Date(testData.OPBEANS_END_DATE).getTime(), + }); - return ingestSynthtraceDataHook(config, data); -} - -// eslint-disable-next-line import/no-default-export -export default globalSetup; + await apmSynthtraceEsClient.index(dataGenerator); +}); diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/service_inventory/service_inventory.spec.ts b/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/service_inventory/service_inventory.spec.ts index 9a75f9d0085d1..957bb149c5e23 100644 --- a/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/service_inventory/service_inventory.spec.ts +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/service_inventory/service_inventory.spec.ts @@ -4,34 +4,34 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { expect } from '@kbn/scout'; -import { test } from '../../fixtures'; - -const start = '2021-10-10T00:00:00.000Z'; -const end = '2021-10-10T00:15:00.000Z'; +import { expect } from '@kbn/scout-oblt'; +import { test, testData } from '../../fixtures'; test.describe('Service Inventory', { tag: ['@ess', '@svlOblt'] }, () => { - test.beforeEach(async ({ browserAuth, page, pageObjects: { serviceInventoryPage } }) => { + test.beforeEach(async ({ browserAuth, pageObjects: { serviceInventoryPage } }) => { await browserAuth.loginAsViewer(); - await serviceInventoryPage.gotoDetailedServiceInventoryWithDateSelected(start, end); - await serviceInventoryPage.waitForPageToLoad(); + await serviceInventoryPage.gotoDetailedServiceInventoryWithDateSelected( + testData.OPBEANS_START_DATE, + testData.OPBEANS_END_DATE + ); }); - test('shows the service inventory', async ({ page, pageObjects: { serviceInventoryPage } }) => { - await serviceInventoryPage.gotoDetailedServiceInventoryWithDateSelected(start, end); - expect(page.url()).toContain('/app/apm/services'); - await expect(page.getByRole('heading', { name: 'Services', level: 1 })).toBeVisible(); - }); + test('renders page with selected date range', async ({ page }) => { + await test.step('shows correct heading', async () => { + expect(page.url()).toContain('/app/apm/services'); + await expect(page.getByRole('heading', { name: 'Services', level: 1 })).toBeVisible(); + }); - test('shows a list of services', async ({ page }) => { - await expect(page.getByText('opbeans-node')).toBeVisible(); - await expect(page.getByText('opbeans-java')).toBeVisible(); - await expect(page.getByText('opbeans-rum')).toBeVisible(); - }); + await test.step('shows a list of services', async () => { + await expect(page.getByText('opbeans-node')).toBeVisible(); + await expect(page.getByText('opbeans-java')).toBeVisible(); + await expect(page.getByText('opbeans-rum')).toBeVisible(); + }); - test('shows a list of environments', async ({ page }) => { - const environmentEntrySelector = page.locator('td:has-text("production")'); - await expect(environmentEntrySelector).toHaveCount(3); + await test.step('shows a list of environments', async () => { + const environmentEntrySelector = page.locator('td:has-text("production")'); + await expect(environmentEntrySelector).toHaveCount(3); + }); }); test('loads the service overview for a service when clicking on it', async ({ page }) => { @@ -41,15 +41,9 @@ test.describe('Service Inventory', { tag: ['@ess', '@svlOblt'] }, () => { }); test('shows the correct environment when changing the environment', async ({ page }) => { + await page.testSubj.click('environmentFilter > comboBoxSearchInput'); await page - .locator('[data-test-subj="environmentFilter"]') - .locator('[data-test-subj="comboBoxSearchInput"]') - .click(); - await expect( - page.getByTestId('comboBoxOptionsList environmentFilter-optionsList') - ).toBeVisible(); - await page - .locator('[data-test-subj="comboBoxOptionsList environmentFilter-optionsList"]') + .getByTestId('comboBoxOptionsList environmentFilter-optionsList') .locator('button:has-text("production")') .click(); await expect(page.getByTestId('comboBoxSearchInput')).toHaveValue('production'); diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/sevice_map/service_map.spec.ts b/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/sevice_map/service_map.spec.ts index 7995dbce5c282..54322d22e18ed 100644 --- a/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/sevice_map/service_map.spec.ts +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/parallel_tests/sevice_map/service_map.spec.ts @@ -5,46 +5,54 @@ * 2.0. */ -import { expect } from '@kbn/scout'; -import { test } from '../../fixtures'; - -const start = '2021-10-10T00:00:00.000Z'; -const end = '2021-10-10T00:15:00.000Z'; +import { expect } from '@kbn/scout-oblt'; +import { test, testData } from '../../fixtures'; test.describe('Service Map', { tag: ['@ess', '@svlOblt'] }, () => { - test.beforeEach(async ({ browserAuth, page, pageObjects: { serviceMapPage } }) => { + test.beforeEach(async ({ browserAuth }) => { await browserAuth.loginAsViewer(); - await serviceMapPage.gotoWithDateSelected(start, end); - await serviceMapPage.waitForPageToLoad(); }); - test('shows the service map', async ({ page, pageObjects: { serviceMapPage } }) => { - await serviceMapPage.gotoWithDateSelected(start, end); + + test('renders page with selected date range', async ({ + page, + pageObjects: { serviceMapPage }, + }) => { + await serviceMapPage.gotoWithDateSelected( + testData.OPBEANS_START_DATE, + testData.OPBEANS_END_DATE + ); expect(page.url()).toContain('/app/apm/service-map'); - await page.waitForSelector('[data-test-subj="serviceMap"]'); - await expect(page.getByTestId('serviceMap').getByLabel('Loading')).toBeHidden(); - await page.getByLabel('Zoom In').click(); - await page.getByTestId('centerServiceMap').click(); - await expect(page.getByTestId('serviceMap').getByLabel('Loading')).toBeHidden(); + await serviceMapPage.waitForServiceMapToLoad(); + await serviceMapPage.zoomInBtn.click(); + await serviceMapPage.centerServiceMapBtn.click(); + await serviceMapPage.waitForServiceMapToLoad(); }); test('shows a detailed service map', async ({ page, pageObjects: { serviceMapPage } }) => { - await serviceMapPage.gotoDetailedServiceMapWithDateSelected(start, end); + await serviceMapPage.gotoDetailedServiceMapWithDateSelected( + testData.OPBEANS_START_DATE, + testData.OPBEANS_END_DATE + ); expect(page.url()).toContain('/services/opbeans-java/service-map'); - await page.waitForSelector('[data-test-subj="serviceMap"]'); - await expect(page.getByTestId('serviceMap').getByLabel('Loading')).toBeHidden(); - await page.getByLabel('Zoom out').click(); - await page.getByTestId('centerServiceMap').click(); - await expect(page.getByTestId('serviceMap').getByLabel('Loading')).toBeHidden(); + await serviceMapPage.waitForServiceMapToLoad(); + await serviceMapPage.zoomOutBtn.click(); + await serviceMapPage.centerServiceMapBtn.click(); + await serviceMapPage.zoomInBtn.click(); + await serviceMapPage.waitForServiceMapToLoad(); }); test('shows empty state when there is no data', async ({ page, pageObjects: { serviceMapPage }, }) => { - await serviceMapPage.typeInTheSearchBar(); - await expect(page.getByTestId('serviceMap').getByLabel('Loading')).toBeHidden(); - page.getByText('No services available'); - // search bar is still visible + await serviceMapPage.gotoWithDateSelected( + testData.OPBEANS_START_DATE, + testData.OPBEANS_END_DATE + ); + await serviceMapPage.typeInTheSearchBar('_id : foo'); + await serviceMapPage.waitForServiceMapToLoad(); + await expect(serviceMapPage.noServicesPlaceholder).toBeVisible(); + await expect(serviceMapPage.noServicesPlaceholder).toHaveText('No services available'); await expect(page.getByTestId('apmUnifiedSearchBar')).toBeVisible(); }); }); diff --git a/x-pack/solutions/observability/plugins/apm/ui_tests/tsconfig.json b/x-pack/solutions/observability/plugins/apm/ui_tests/tsconfig.json index 95c76f3f661a2..5d31d0b906507 100644 --- a/x-pack/solutions/observability/plugins/apm/ui_tests/tsconfig.json +++ b/x-pack/solutions/observability/plugins/apm/ui_tests/tsconfig.json @@ -7,8 +7,8 @@ "**/*" ], "kbn_references": [ - "@kbn/scout", - "@kbn/apm-synthtrace-client" + "@kbn/apm-synthtrace-client", + "@kbn/scout-oblt" ], "exclude": [ "target/**/*" diff --git a/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/README.md b/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/README.md index ccf77c804d3c1..88a68a64f7e02 100644 --- a/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/README.md +++ b/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/README.md @@ -16,20 +16,22 @@ Some tests are designed to run sequentially: ```bash // ESS -npx playwright test --config x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/playwright.config.ts --grep @ess +npx playwright test --config x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/playwright.config.ts --project=local --grep @ess // Serverless -npx playwright test --config x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/playwright.config.ts --grep @svlOblt +npx playwright test --config x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/playwright.config.ts --project=local --grep @svlOblt ``` Some tests are designed to run concurrently (preferred option): ```bash // ESS -npx playwright test --config x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/parallel_playwright.config.ts --grep @ess +npx playwright test --config x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/parallel_playwright.config.ts +--project=local --grep @ess // Serverless -npx playwright test --config x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/parallel_playwright.config.ts --grep @svlOblt +npx playwright test --config x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/parallel_playwright.config.ts +--project=local --grep @svlOblt ``` Test results are available in `x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/output` diff --git a/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/parallel.playwright.config.ts b/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/parallel.playwright.config.ts index 997f5d57098fa..deadf91cadb21 100644 --- a/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/parallel.playwright.config.ts +++ b/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/parallel.playwright.config.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { createPlaywrightConfig } from '@kbn/scout'; +import { createPlaywrightConfig } from '@kbn/scout-oblt'; // eslint-disable-next-line import/no-default-export export default createPlaywrightConfig({ diff --git a/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/playwright.config.ts b/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/playwright.config.ts index 34b370396b67e..37b621c2246a6 100644 --- a/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/playwright.config.ts +++ b/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/playwright.config.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { createPlaywrightConfig } from '@kbn/scout'; +import { createPlaywrightConfig } from '@kbn/scout-oblt'; // eslint-disable-next-line import/no-default-export export default createPlaywrightConfig({ diff --git a/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/tsconfig.json b/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/tsconfig.json index f29bcbcf52ebf..43ceeeff667bb 100644 --- a/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/tsconfig.json +++ b/x-pack/solutions/observability/plugins/observability_onboarding/ui_tests/tsconfig.json @@ -7,7 +7,6 @@ "**/*" ], "kbn_references": [ - "@kbn/scout", "@kbn/scout-oblt" ], "exclude": [