Skip to content

Commit 3c19184

Browse files
committed
Merge remote-tracking branch 'upstream/main' into graph-popovers-impl
2 parents 8ba2a2a + 9fa5c56 commit 3c19184

File tree

14,973 files changed

+778216
-258978
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

14,973 files changed

+778216
-258978
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
name: ftr-testing
3+
description: Use when creating, updating, debugging, or reviewing Kibana Functional Test Runner (FTR) tests, including test structure, services/page objects, loadTestFile patterns, tags, and how to run FTR locally.
4+
---
5+
6+
# FTR Testing
7+
8+
## Overview
9+
FTR (FunctionalTestRunner) runs Kibana UI functional tests written in mocha with `@kbn/expect`. Core principle: use FTR services/page objects for interactions, keep tests organized by config, and understand loadTestFile-driven suites.
10+
11+
## Core workflow
12+
13+
1. Identify the FTR config and test file location.
14+
- FTR suites live under `test/**` or `x-pack/**/test/**` with config files.
15+
- To confirm a config is actually executed in CI, check the relevant `.buildkite/ftr_*_configs.yml` and whether it’s listed under `enabled:` vs `disabled:`.
16+
2. Understand the test structure.
17+
- Tests export a provider function that defines a mocha suite.
18+
- Use `describe/it/before/beforeEach/after/afterEach`.
19+
3. Use services and page objects.
20+
- Services provide shared capabilities (browser, testSubjects, retry, esArchiver).
21+
- Services are named singletons created from `FtrService` subclasses.
22+
- Page objects wrap UI interactions.
23+
4. Watch for `loadTestFile` usage.
24+
- Index files can load multiple suites with shared setup.
25+
5. Use tags in `describe()` to control CI grouping and skips.
26+
6. If unfamiliar with a page, run the existing FTR tests to learn the flow before migrating.
27+
28+
## Quick reference
29+
30+
- Run all-in-one: `node scripts/functional_tests`
31+
- Run server + tests:
32+
- `node scripts/functional_tests_server`
33+
- `node scripts/functional_test_runner --config <path>`
34+
- Common services: `browser`, `testSubjects`, `retry`, `esArchiver`, `kibanaServer`.
35+
- Page objects and services are fetched via `getPageObjects()` / `getService()`.
36+
37+
## Common patterns
38+
39+
### loadTestFile
40+
41+
```ts
42+
export default ({ loadTestFile }: FtrProviderContext) => {
43+
describe('suite', () => {
44+
loadTestFile(require.resolve('./pages/rules_page'));
45+
});
46+
};
47+
```
48+
49+
Notes:
50+
- Index files often include shared setup/teardown; it applies to every loaded suite.
51+
- When migrating, each `loadTestFile` target becomes its own Scout spec and shared setup
52+
must be duplicated or refactored into fixtures/helpers.
53+
54+
### Services and page objects
55+
56+
```ts
57+
export default ({ getService, getPageObjects }: FtrProviderContext) => {
58+
const testSubjects = getService('testSubjects');
59+
const browser = getService('browser');
60+
const pageObjects = getPageObjects(['header', 'common']);
61+
62+
describe('My suite', () => {
63+
it('does something', async () => {
64+
await pageObjects.common.navigateToApp('home');
65+
await testSubjects.existOrFail('homeApp');
66+
expect(await browser.getCurrentUrl()).toContain('home');
67+
});
68+
});
69+
};
70+
```
71+
72+
## Common mistakes
73+
74+
- Adding UI logic directly in tests instead of using services/page objects.
75+
- Ignoring `loadTestFile` shared setup in index files.
76+
- Running with the wrong config file (stateful vs serverless).

.agents/skills/kibana-api/SKILL.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
name: kibana-api
3+
description: Shared utilities for interacting with a local Kibana instance. Provides auto-detection of Kibana URL and auth, and a kibana_curl wrapper.
4+
user-invocable: false
5+
---
6+
7+
# Kibana API Utilities
8+
9+
This skill provides shared shell utilities for other skills that need to call Kibana APIs.
10+
11+
## Usage
12+
13+
Source `scripts/kibana_api_common.sh` from any skill script:
14+
15+
```bash
16+
REPO_ROOT="$(git rev-parse --show-toplevel)"
17+
source "$REPO_ROOT/scripts/kibana_api_common.sh"
18+
```
19+
20+
After sourcing, the following are available:
21+
22+
- **`KIBANA_URL`** — Detected base URL (e.g., `http://localhost:5601`)
23+
- **`KIBANA_AUTH`** — Detected credentials (e.g., `elastic:changeme`)
24+
- **`kibana_curl [curl args...]`** — curl wrapper with auth, `kbn-xsrf`, `x-elastic-internal-origin`, and TLS flags pre-configured
25+
26+
## Auto-Detection
27+
28+
Tries these permutations automatically:
29+
- URLs: `http://localhost:5601`, `https://localhost:5601`
30+
- Auth: `elastic:changeme`, `elastic_serverless:changeme`
31+
32+
Override with environment variables `KIBANA_URL` and/or `KIBANA_AUTH` before sourcing.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
name: scout-api-testing
3+
description: Use when creating, updating, debugging, or reviewing Scout API tests in Kibana (apiTest/apiClient/requestAuth/samlAuth/apiServices), including auth choices, response assertions, and API service patterns.
4+
---
5+
6+
# Scout API Testing
7+
8+
## Core rules (API)
9+
10+
- API specs live in `<module-root>/test/scout*/api/{tests,parallel_tests}/**/*.spec.ts` (examples: `test/scout/api/...`, `test/scout_uiam_local/api/...`).
11+
- Use the Scout package that matches the module root:
12+
- `src/platform/**` or `x-pack/platform/**` -> `@kbn/scout`
13+
- `x-pack/solutions/observability/**` -> `@kbn/scout-oblt`
14+
- `x-pack/solutions/search/**` -> `@kbn/scout-search`
15+
- `x-pack/solutions/security/**` -> `@kbn/scout-security`
16+
- Prefer a single top-level `apiTest.describe(...)` per file and avoid nested `describe` blocks; multiple top-level `describe`s are supported, but files get hard to read quickly.
17+
- Tags: add `{ tag: ... }` on the suite (or individual tests) so CI/discovery can select the right test target (for example `tags.deploymentAgnostic` or `[...tags.stateful.classic]`). Unlike UI tests, API tests don’t currently validate tags at runtime.
18+
- If the module provides Scout fixtures, import `apiTest` from `<module-root>/test/scout*/api/fixtures` to get module-specific extensions. Importing directly from the module’s Scout package is also fine when you don’t need extensions.
19+
- Browser fixtures are disabled for `apiTest` (no `page`, `browserAuth`, `pageObjects`).
20+
21+
## Imports
22+
23+
- Test framework + tags: `import { apiTest, tags } from '@kbn/scout';` (or the module's Scout package, e.g. `@kbn/scout-oblt`)
24+
- Assertions: `import { expect } from '@kbn/scout/api';` (or `@kbn/scout-oblt/api`, etc.) — **not** from the main entry
25+
- Types: `import type { RoleApiCredentials } from '@kbn/scout';`
26+
- `expect` is **not** exported from the main `@kbn/scout` entry. Use the `/api` subpath for API tests.
27+
28+
## Auth: pick based on endpoint
29+
30+
- `api/*` endpoints: use **API keys** via `requestAuth` (`getApiKey`, `getApiKeyForCustomRole`).
31+
- `internal/*` endpoints: use **cookies** via `samlAuth.asInteractiveUser(...)`.
32+
33+
## Recommended test shape
34+
35+
1. **Prepare** environment (optional): `apiServices`/`kbnClient`/`esArchiver` in `beforeAll`.
36+
2. **Authenticate** (least privilege): generate credentials in `beforeAll` and reuse.
37+
3. **Request**: call the endpoint with `apiClient` and the right headers.
38+
4. **Assert**: verify `statusCode` and response body; verify side effects via `apiServices`/`kbnClient` when needed.
39+
40+
Important: `apiServices`/`kbnClient` run with elevated privileges. Don’t use them to validate the endpoint under test (use `apiClient` + scoped auth).
41+
42+
Header reminders:
43+
- State-changing requests usually need `kbn-xsrf`.
44+
- Prefer sending `x-elastic-internal-origin: kibana` for Kibana APIs.
45+
- Include `elastic-api-version` for versioned public APIs (e.g. `'2023-10-31'`) or internal APIs (e.g. `'1'`).
46+
47+
## Assertions
48+
49+
- `apiClient` methods (`get`, `post`, `put`, `delete`, `patch`, `head`) return `{ statusCode, body, headers }`.
50+
- Use the custom matchers from `@kbn/scout/api`:
51+
- `expect(response).toHaveStatusCode(200)`
52+
- `expect(response).toHaveStatusText('OK')`
53+
- `expect(response).toHaveHeaders({ 'content-type': 'application/json' })`
54+
- Standard matchers (`toBe`, `toStrictEqual`, `toMatchObject`, etc.) and asymmetric matchers (`expect.objectContaining(...)`, `expect.any(String)`) are also available.
55+
56+
## API services
57+
58+
- Put reusable server-side helpers behind `apiServices` (no UI interactions). Use it for setup/teardown and verifying side effects, not for RBAC validation.
59+
- **Module-local service**: create it under `<module-root>/test/scout*/api/services/<service>_api_service.ts` (or similar). Register it by extending the module's `apiServices` fixture in `<module-root>/test/scout*/api/fixtures/index.ts` (prefer `{ scope: 'worker' }` when the helper doesn't need per-test state).
60+
- **Shared service** (reused across modules): consider contributing it to the Scout packages under `src/platform/packages/shared/kbn-scout/src/playwright/fixtures/scope/worker/apis/`.
61+
62+
## Extending fixtures
63+
64+
When tests need custom auth helpers or API services, extend `apiTest` in the module's `fixtures/index.ts`:
65+
66+
```ts
67+
import { apiTest as base } from '@kbn/scout'; // or the module's Scout package
68+
import type { RequestAuthFixture } from '@kbn/scout';
69+
70+
interface MyApiFixtures {
71+
requestAuth: RequestAuthFixture & { getMyPluginApiKey: () => Promise<RoleApiCredentials> };
72+
}
73+
74+
export const apiTest = base.extend<MyApiFixtures>({
75+
requestAuth: async ({ requestAuth }, use) => {
76+
const getMyPluginApiKey = async () =>
77+
requestAuth.getApiKeyForCustomRole({
78+
kibana: [{ base: [], feature: { myPlugin: ['all'] }, spaces: ['*'] }],
79+
});
80+
await use({ ...requestAuth, getMyPluginApiKey });
81+
},
82+
});
83+
```
84+
85+
Tests then import `apiTest` from the local fixtures: `import { apiTest } from '../fixtures';`
86+
87+
## Parallelism
88+
89+
- Treat Scout API tests as sequential by default. Parallel API runs require manual isolation (spaces, indices, saved objects) and are uncommon.
90+
91+
## Run / debug quickly
92+
93+
- Use either `--config` or `--testFiles` (they are mutually exclusive).
94+
- Run by config: `node scripts/scout.js run-tests --stateful --config <module-root>/test/scout*/api/playwright.config.ts` (or `.../api/parallel.playwright.config.ts` for parallel API runs)
95+
- Run by file/dir (Scout derives the right `playwright.config.ts` vs `parallel.playwright.config.ts`): `node scripts/scout.js run-tests --stateful --testFiles <module-root>/test/scout*/api/tests/my.spec.ts`
96+
- For faster iteration, start servers once in another terminal: `node scripts/scout.js start-server --stateful [--config-dir <configSet>]`, then run Playwright directly: `npx playwright test --config <...> --project local --grep <tag>`.
97+
- `--config-dir` notes:
98+
- `run-tests` auto-detects the custom config dir from `.../test/scout_<name>/...` paths (override with `--config-dir <name>` if needed).
99+
- `start-server` has no Playwright config to inspect, so pass `--config-dir <name>` when your tests require a custom server config.
100+
- Debug: `SCOUT_LOG_LEVEL=debug`
101+
102+
## CI enablement
103+
104+
- Scout tests run in CI only for modules listed under `plugins.enabled` / `packages.enabled` in `.buildkite/scout_ci_config.yml`.
105+
- `node scripts/scout.js generate` registers the module under `enabled` so the new configs run in CI.
106+
107+
## References
108+
109+
Open only what you need:
110+
111+
- requestAuth vs samlAuth, headers, and least-privilege auth tips: `references/scout-api-auth.md`
112+
- Creating and registering `apiServices` helpers (kbnClient + retries + logging): `references/scout-api-services.md`
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Scout API Test Authentication (requestAuth vs samlAuth)
2+
3+
Use this when writing API tests with `apiTest`/`apiClient`, especially when validating RBAC.
4+
5+
## Pick an auth method
6+
7+
- `api/*` endpoints: use API keys via `requestAuth`.
8+
- `internal/*` endpoints: use cookies via `samlAuth.asInteractiveUser(...)`.
9+
10+
Both methods return headers you spread into `apiClient` requests.
11+
12+
## API key auth (requestAuth)
13+
14+
- `requestAuth.getApiKey(roleName)`
15+
- `requestAuth.getApiKeyForCustomRole(roleDescriptor)`
16+
17+
```ts
18+
import type { RoleApiCredentials } from '@kbn/scout'; // or the module's Scout package (e.g. @kbn/scout-oblt)
19+
import { apiTest, tags } from '@kbn/scout'; // or the module's Scout package
20+
import { expect } from '@kbn/scout/api'; // or '@kbn/scout-oblt/api', etc.
21+
22+
const COMMON_HEADERS = {
23+
'kbn-xsrf': 'scout',
24+
'x-elastic-internal-origin': 'kibana',
25+
'elastic-api-version': '2023-10-31', // include for versioned public APIs
26+
};
27+
28+
apiTest.describe('GET /api/my_plugin/foo', { tag: tags.DEPLOYMENT_AGNOSTIC }, () => {
29+
let viewer: RoleApiCredentials;
30+
31+
apiTest.beforeAll(async ({ requestAuth }) => {
32+
viewer = await requestAuth.getApiKey('viewer');
33+
});
34+
35+
apiTest('works', async ({ apiClient }) => {
36+
const response = await apiClient.get('api/my_plugin/foo', {
37+
headers: { ...COMMON_HEADERS, ...viewer.apiKeyHeader },
38+
responseType: 'json',
39+
});
40+
41+
expect(response).toHaveStatusCode(200);
42+
expect(response.body).toStrictEqual(expect.objectContaining({ id: expect.any(String) }));
43+
});
44+
});
45+
```
46+
47+
## Cookie auth (samlAuth) for internal endpoints
48+
49+
```ts
50+
import { apiTest, tags } from '@kbn/scout'; // or the module's Scout package
51+
import { expect } from '@kbn/scout/api'; // or '@kbn/scout-oblt/api', etc.
52+
53+
const INTERNAL_HEADERS = {
54+
'kbn-xsrf': 'scout',
55+
'x-elastic-internal-origin': 'kibana',
56+
};
57+
58+
apiTest.describe('GET /internal/my_plugin/foo', { tag: tags.DEPLOYMENT_AGNOSTIC }, () => {
59+
apiTest('calls internal endpoint', async ({ apiClient, samlAuth }) => {
60+
const { cookieHeader } = await samlAuth.asInteractiveUser('viewer');
61+
62+
const response = await apiClient.get('internal/my_plugin/foo', {
63+
headers: { ...INTERNAL_HEADERS, ...cookieHeader },
64+
responseType: 'json',
65+
});
66+
67+
expect(response).toHaveStatusCode(200);
68+
});
69+
});
70+
```
71+
72+
## API assertions (`@kbn/scout/api`)
73+
74+
Import `expect` from `@kbn/scout/api` (or `@kbn/scout-<solution>/api`). It provides custom matchers on top of standard ones:
75+
76+
- `expect(response).toHaveStatusCode(200)` — assert HTTP status code.
77+
- `expect(response).toHaveStatusText('OK')` — assert HTTP status text.
78+
- `expect(response).toHaveHeaders({ 'content-type': 'application/json' })` — assert response headers.
79+
- Standard matchers like `toBe`, `toStrictEqual`, `toBeDefined`, `toMatchObject` are also available.
80+
- Asymmetric matchers: `expect.objectContaining(...)`, `expect.any(String)`, `expect.toBeGreaterThan(0)`, etc.
81+
82+
`apiClient` methods (`get`, `post`, `put`, `delete`, `patch`, `head`) return `{ statusCode, body, headers }`.
83+
84+
## Tips
85+
86+
- Generate credentials in `beforeAll` if reused across tests.
87+
- Prefer custom roles for permission-boundary tests instead of `admin`.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Scout API Services
2+
3+
API services provide server-side helpers through the `apiServices` fixture.
4+
Keep API services strictly server-side (no UI interactions).
5+
Import helper utilities (like `measurePerformanceAsync`) from the Scout package used by the module (`@kbn/scout` or the relevant solution package).
6+
7+
## Create a new API service (summary)
8+
9+
1. Add a new service file under the API fixtures directory.
10+
2. Add a `types.ts` file for request/response types when the API is non-trivial.
11+
3. Export a helper function that accepts `log` and `kbnClient` and uses
12+
`kbnClient.request` with retries (and `ignoreErrors` when needed).
13+
4. Wrap calls with `measurePerformanceAsync` for consistent logging.
14+
5. Register the service in the API fixtures index so it appears under
15+
`apiServices.<name>`.
16+
17+
## Minimal sketch
18+
19+
```ts
20+
import type { KbnClient, ScoutLogger } from '@kbn/scout'; // or the module's Scout package (e.g. @kbn/scout-security)
21+
import { measurePerformanceAsync } from '@kbn/scout'; // or the module's Scout package
22+
23+
export interface MyApiService {
24+
enable: () => Promise<void>;
25+
}
26+
27+
export const getMyApiService = ({
28+
log,
29+
kbnClient,
30+
}: {
31+
log: ScoutLogger;
32+
kbnClient: KbnClient;
33+
}): MyApiService => {
34+
return {
35+
enable: async () => {
36+
await measurePerformanceAsync(log, 'myService.enable', async () => {
37+
await kbnClient.request({
38+
method: 'POST',
39+
path: '/api/my/endpoint',
40+
retries: 3,
41+
});
42+
});
43+
},
44+
};
45+
};
46+
```
47+
48+
Register it in the fixture so tests can call:
49+
50+
```ts
51+
await apiServices.myService.enable();
52+
```
53+
54+
When adding a module-local API service, extend the `apiServices` fixture (prefer worker scope) and merge in the new
55+
service:
56+
57+
```ts
58+
apiServices: async ({ apiServices, kbnClient, log }, use) => {
59+
const extended = {
60+
...apiServices,
61+
myService: getMyApiService({ kbnClient, log }),
62+
};
63+
64+
await use(extended);
65+
}
66+
```
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
name: scout-best-practices-reviewer
3+
description: Use when writing and reviewing Scout UI and API test files.
4+
---
5+
6+
# Scout Best Practices Reviewer
7+
8+
## Overview
9+
10+
- Identify whether the spec is **UI** (`test`/`spaceTest`) or **API** (`apiTest`) and review against the relevant best practices.
11+
- Keep feedback concise and actionable: focus on correctness, flake risk, and CI/runtime impact.
12+
- Report findings ordered by severity and include the matching best-practice heading (from the reference) next to each finding.
13+
14+
## References
15+
16+
Open only what you need:
17+
18+
- Review checklist (tagging, structure, auth, flake control): `references/scout-best-practices.md`

0 commit comments

Comments
 (0)