Set up Scout in your plugin or package
This page shows the minimum setup to add Scout tests to a plugin/package. For choosing the right import (@kbn/scout vs solution packages), see Scout packages.
-
Generate a working scaffold
Generate a working scaffold (folders, configs, and sample tests) by following the guided setup:
node scripts/scout.js generateThis command will also automatically enable your plugin or package's Scout tests in the CI by updating the
.buildkite/scout_ci_config.ymlfile. -
Write and run tests
Tweak the new Playwright config(s) and write UI tests or API tests.
-
Create the folder layout
Create
test/scout:your-plugin/ └── test/ └── scout/ ├── ui/ ├── api/ └── common/- UI tests (optional)
- API tests (optional)
- shared code (optional)
TipLarge plugins often accumulate tests across different functional areas, sometimes owned by different teams. Rather than placing them all directly under the Scout root, group them into functional-area namespaces and assign ownership per area.
-
Create Playwright config(s)
Create a config under
test/scout/uiand/ortest/scout/api.Create
playwright.config.ts:import { createPlaywrightConfig } from '@kbn/scout'; export default createPlaywrightConfig({ testDir: './tests', });ImportantUse the conventional name
playwright.config.tsso Scout tooling can discover the config.Then create the
tests/directory next to the config.If many files share one-time setup (archives/ingest/settings), add a global setup hook.
If your UI suites can be isolated, add
parallel.playwright.config.tsundertest/scout/uiand point it atparallel_tests/:import { createPlaywrightConfig } from '@kbn/scout'; export default createPlaywrightConfig({ testDir: './parallel_tests', workers: 2, });ImportantUse the conventional name
parallel.playwright.config.tsso Scout tooling can discover the config.Then create the
parallel_tests/directory next to the config. For parallel suites, prefer defining test suites and test cases usingspaceTestso each worker runs in an isolated Space (see Parallelism).If many files share one-time setup (archives/ingest/settings), add a global setup hook.
-
Enable Scout runs in CI
Ensure your plugin or package is listed in
.buildkite/scout_ci_config.ymlso Scout tests run in CI. If not already in the list, add one line under the appropriateenabledlist:- Plugins: Add
- <plugin_name>underplugins.enabled. The name is the path segment(s) afterplugins/(the plugin folder name, or a slash-separated path for nested plugins). - Packages: Add
- <package_name>underpackages.enabled. The name is the folder name afterpackages/.
plugins: enabled: - <plugin_name> disabled: packages: enabled: - <package_name> disabled: - Plugins: Add
-
Write and run tests
Tweak the new Playwright config(s) and write UI tests or API tests.
By default, a plugin keeps all of its Scout tests directly under the Scout root (test/scout/{ui,api}/). Large plugins can instead group tests into namespaces (single-level sub-directories named after a functional area):
your-plugin/
└── test/
└── scout/
├── detection_engine/
│ ├── ui/
│ └── api/
├── entity_analytics/
│ └── ui/
└── common/
- namespace
- namespace
- shared code (optional, reserved name)
A namespace holds the same layout you'd otherwise place at the Scout root, one level deeper, with its own Playwright config(s), fixtures, and tests (for example test/scout/<namespace>/ui/playwright.config.ts).
Why use namespaces?
- Scoped ownership: assign each area to the team that owns it in
.github/CODEOWNERS, so failures reach the smaller group that maintains that functionality. - Run a focused subset: point Scout at a single namespace's config to run (or re-run) only that area's tests, instead of the whole plugin's suite.
- Independently runnable in CI: each namespace is discovered as its own config, so selective testing and CI reporting are scoped per area, while all namespaces still share the same server configuration.
Pass --namespace to the Scout CLI:
node scripts/scout.js generate \
--path x-pack/solutions/security/plugins/security_solution \
--namespace detection_engine
In interactive mode, if the plugin already uses namespaces, the generator lists the existing ones so you can pick one or create a new one. After scaffolding, it reminds you to set the namespace owner in .github/CODEOWNERS:
/x-pack/solutions/security/plugins/security_solution/test/scout/detection_engine/ @elastic/<team>
- One level only: use
test/scout/<namespace>/{ui,api}/(deeper nesting such as.../<area>/<sub-area>/{ui,api}/is not supported). - Don't mix layouts: a Scout root is either entirely root-level (
test/scout/{ui,api}/) or entirely namespace-based. Mixing the two fails the build. To adopt namespaces in an existing plugin, migrate the root-level tests into a namespace first. - Naming: start with a lowercase letter and use only lowercase letters, digits, and underscores.
ui,api,.meta, andcommonare reserved (commonis a plain shared-utilities directory with no Playwright config).