Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
cc8e833
Add scout tests for feature settings page
saikatsarkar056 Apr 7, 2026
ca4140d
Refactor code
saikatsarkar056 Apr 7, 2026
e30d180
Add tests for add-model
saikatsarkar056 Apr 7, 2026
dbd8fb5
Add tests for copy-to
saikatsarkar056 Apr 7, 2026
0b689de
Refactor code
saikatsarkar056 Apr 7, 2026
a4dd1e4
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 7, 2026
895df27
Refactor code
saikatsarkar056 Apr 7, 2026
ad09b7a
Refactor code
saikatsarkar056 Apr 7, 2026
9f7d0ac
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 7, 2026
67b38ef
Refactor code
saikatsarkar056 Apr 7, 2026
c8cbf22
Refactor code
saikatsarkar056 Apr 7, 2026
1cfea43
Refactor code
saikatsarkar056 Apr 7, 2026
3cecb11
Refactor code
saikatsarkar056 Apr 7, 2026
b0cf116
Refactor code
saikatsarkar056 Apr 7, 2026
0e699be
Refactor code
saikatsarkar056 Apr 7, 2026
1177a15
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 8, 2026
779c9f5
Merge branch 'main' into scout-feature-settings-tests
saikatsarkar056 Apr 8, 2026
77a545e
Add comment for each line of disable next-line
saikatsarkar056 Apr 9, 2026
855303e
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 9, 2026
3d7953e
Mock inference api
saikatsarkar056 Apr 9, 2026
3daabef
Refactor code
saikatsarkar056 Apr 9, 2026
da80fdf
Merge branch 'scout-feature-settings-tests' of github.com:saikatsarka…
saikatsarkar056 Apr 9, 2026
064de6d
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 9, 2026
ee311fb
Refactor code
saikatsarkar056 Apr 9, 2026
9d9f7d3
Introduce fixture plugin
saikatsarkar056 Apr 9, 2026
7b7a520
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 9, 2026
0b008fc
Refactor code
saikatsarkar056 Apr 9, 2026
e7f676c
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 9, 2026
b9c0268
Refactor code
saikatsarkar056 Apr 9, 2026
14f23ed
Refactor code
saikatsarkar056 Apr 9, 2026
70f7ee6
Refactor code
saikatsarkar056 Apr 9, 2026
248e78c
Refactor code
saikatsarkar056 Apr 9, 2026
29e1843
Refactor code
saikatsarkar056 Apr 9, 2026
9dcdde6
Refactor code
saikatsarkar056 Apr 9, 2026
c8e8bc4
Refactor code
saikatsarkar056 Apr 9, 2026
56748f1
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 9, 2026
030558b
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 10, 2026
6754973
Refactor code
saikatsarkar056 Apr 10, 2026
e39a2dc
Skip MKI
saikatsarkar056 Apr 10, 2026
ca516e8
Refactor code
saikatsarkar056 Apr 10, 2026
8a6506d
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 10, 2026
798d229
Refactor code
saikatsarkar056 Apr 10, 2026
c7d85fe
Refactor code
saikatsarkar056 Apr 10, 2026
5a7c34f
Refactor code
saikatsarkar056 Apr 10, 2026
7deba2d
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 10, 2026
30d464a
Add readonly class fields
saikatsarkar056 Apr 13, 2026
f45cd45
Refactor code
saikatsarkar056 Apr 13, 2026
7a70e17
Merge branch 'main' of github.com:elastic/kibana into scout-feature-s…
saikatsarkar056 Apr 13, 2026
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
6 changes: 5 additions & 1 deletion .agents/skills/scout-ui-testing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,14 @@ description: Use when creating, updating, debugging, or reviewing Scout UI tests
## Page objects (UI)

- Prefer `page.testSubj.locator(...)`, role/label locators; avoid brittle CSS.
- Keep selectors + interactions inside the page object class.
- Keep selectors + interactions inside the page object class. **Do not use `expect` assertions in page objects** — use `waitForSelector` for waiting on elements. Assertions belong in test specs only.
- **Keep route mocks out of page objects** — page objects are for UI interactions only. Put `page.route()` mocks in a dedicated `fixtures/mocks.ts` file as standalone functions that accept `page` as a parameter. See `cloud_security_posture/test/scout_cspm_agentless/ui/fixtures/mocks.ts` for the reference pattern.
- Don't make API calls from page objects (use `apiServices`/`kbnClient` in hooks instead).
- Register plugin page objects by extending the `pageObjects` fixture in `test/scout*/ui/fixtures/index.ts`.
- **Use `readonly` class fields for static locators** — assign them in the constructor, not as getter methods. Use methods only for parameterized locators/actions. See `DashboardApp` in `kbn-scout` for the reference pattern.
- Scout provides EUI component wrappers for stable interactions with common EUI widgets: `EuiComboBoxWrapper`, `EuiDataGridWrapper`, `EuiSelectableWrapper`, `EuiCheckBoxWrapper`, `EuiFieldTextWrapper`, `EuiCodeBlockWrapper`, `EuiSuperSelectWrapper`, `EuiToastWrapper`. Import them from `@kbn/scout` and use them as class members in page objects.
- **Avoid `.first()`, `.nth()`, `.last()`** — the `playwright/no-nth-methods` lint rule flags these. Instead, use `data-test-subj` attributes or other targeted selectors. If the component lacks a `data-test-subj`, add one rather than disabling the rule.
Comment thread
saikatsarkar056 marked this conversation as resolved.
- **Do not disable eslint rules** — avoid `eslint-disable` comments in test files. Fix the underlying issue (e.g., use targeted selectors instead of positional ones, add `data-test-subj` to the components) rather than suppressing the lint rule.
Comment thread
saikatsarkar056 marked this conversation as resolved.

## Parallel UI specifics (spaceTest)

Expand Down
1 change: 1 addition & 0 deletions .buildkite/scout_ci_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ plugins:
- saved_objects_management
- search_getting_started
- search_homepage
- search_inference_endpoints
- security
- security_solution
- share
Expand Down
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,7 @@ x-pack/platform/test/plugin_api_perf/plugins/task_manager_performance @elastic/r
x-pack/platform/test/reporting_api_integration/plugins/reporting_fixture @elastic/response-ops
x-pack/platform/test/reporting_api_integration/plugins/reporting_test_routes @elastic/response-ops
x-pack/platform/test/saved_object_api_integration/common/plugins/saved_object_test_plugin @elastic/kibana-security
x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture @elastic/search-kibana
x-pack/platform/test/security_api_integration/packages/helpers @elastic/kibana-security
x-pack/platform/test/security_api_integration/plugins/audit_log @elastic/kibana-security
x-pack/platform/test/security_api_integration/plugins/features_provider @elastic/kibana-security
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,7 @@
"@kbn/search-homepage": "link:x-pack/solutions/search/plugins/search_homepage",
"@kbn/search-index-documents": "link:x-pack/platform/packages/shared/kbn-search-index-documents",
"@kbn/search-inference-endpoints": "link:x-pack/platform/plugins/shared/search_inference_endpoints",
"@kbn/search-inference-endpoints-fixture-plugin": "link:x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture",
"@kbn/search-navigation": "link:x-pack/solutions/search/plugins/search_navigation",
"@kbn/search-notebooks": "link:x-pack/solutions/search/plugins/search_notebooks",
"@kbn/search-playground": "link:x-pack/solutions/search/plugins/search_playground",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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 { resolve } from 'path';
import { REPO_ROOT } from '@kbn/repo-info';
import { servers as defaultConfig } from '../../default/serverless/search.serverless.config';
import type { ScoutServerConfig } from '../../../../../types';

const pluginPath = `--plugin-path=${resolve(
REPO_ROOT,
'x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture'
)}`;

export const servers: ScoutServerConfig = {
...defaultConfig,
kbnTestServer: {
...defaultConfig.kbnTestServer,
serverArgs: [...defaultConfig.kbnTestServer.serverArgs, pluginPath],
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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 { resolve } from 'path';
import { REPO_ROOT } from '@kbn/repo-info';
import type { ScoutServerConfig } from '../../../../../types';
import { defaultConfig } from '../../default/stateful/base.config';

const pluginPath = `--plugin-path=${resolve(
REPO_ROOT,
'x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture'
)}`;

export const servers: ScoutServerConfig = {
...defaultConfig,
kbnTestServer: {
...defaultConfig.kbnTestServer,
serverArgs: [...defaultConfig.kbnTestServer.serverArgs, pluginPath],
},
};
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -2042,6 +2042,8 @@
"@kbn/search-index-documents/*": ["x-pack/platform/packages/shared/kbn-search-index-documents/*"],
"@kbn/search-inference-endpoints": ["x-pack/platform/plugins/shared/search_inference_endpoints"],
"@kbn/search-inference-endpoints/*": ["x-pack/platform/plugins/shared/search_inference_endpoints/*"],
"@kbn/search-inference-endpoints-fixture-plugin": ["x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture"],
"@kbn/search-inference-endpoints-fixture-plugin/*": ["x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture/*"],
"@kbn/search-navigation": ["x-pack/solutions/search/plugins/search_navigation"],
"@kbn/search-navigation/*": ["x-pack/solutions/search/plugins/search_navigation/*"],
"@kbn/search-notebooks": ["x-pack/solutions/search/plugins/search_notebooks"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ dependsOn:
- '@kbn/inference-common'
- '@kbn/inference-plugin'
- '@kbn/management-settings-ids'
- '@kbn/scout'
tags:
- plugin
- prod
Expand All @@ -65,6 +66,7 @@ fileGroups:
- common/**/*
- public/**/*
- server/**/*
- test/scout_inference_test/**/*
- '!target/**/*'
jest-config:
- jest.config.js
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export const AddModelPopover: React.FC<AddModelPopoverProps> = ({
onChange={handleChange}
singleSelection
searchable
data-test-subj="add-model-selectable"
searchProps={{
placeholder: i18n.translate('xpack.searchInferenceEndpoints.settings.addModel.search', {
defaultMessage: 'Search models...',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.
*/

import type { PageObjects, ScoutTestFixtures, ScoutWorkerFixtures } from '@kbn/scout';
import { test as baseTest, createLazyPageObject } from '@kbn/scout';
import { FeatureSettingsPage } from './page_objects';

export interface ExtScoutTestFixtures extends ScoutTestFixtures {
pageObjects: PageObjects & {
featureSettings: FeatureSettingsPage;
};
}

export const test = baseTest.extend<ExtScoutTestFixtures, ScoutWorkerFixtures>({
pageObjects: async (
{
pageObjects,
page,
}: {
pageObjects: ExtScoutTestFixtures['pageObjects'];
page: ExtScoutTestFixtures['page'];
},
use: (pageObjects: ExtScoutTestFixtures['pageObjects']) => Promise<void>
) => {
const extendedPageObjects = {
...pageObjects,
featureSettings: createLazyPageObject(FeatureSettingsPage, page),
};

await use(extendedPageObjects);
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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 mockInferenceEndpoints = [
{
inference_id: '.mock-anthropic-claude-3.7-sonnet-chat_completion-a3f1',
task_type: 'chat_completion',
service: 'elastic',
service_settings: { model_id: 'anthropic-claude-3.7-sonnet' },
metadata: {
heuristics: { properties: ['multilingual', 'multimodal'], status: 'ga' },
display: { name: 'Anthropic Claude Sonnet 3.7', model_creator: 'Anthropic' },
},
},
{
inference_id: '.mock-anthropic-claude-3.7-sonnet-completion-b7d2',
task_type: 'completion',
service: 'elastic',
service_settings: { model_id: 'anthropic-claude-3.7-sonnet' },
metadata: {
heuristics: { properties: ['multilingual', 'multimodal'], status: 'ga' },
display: { name: 'Anthropic Claude Sonnet 3.7', model_creator: 'Anthropic' },
},
},
{
inference_id: '.mock-openai-gpt-4.1-chat_completion-c9e4',
task_type: 'chat_completion',
service: 'elastic',
service_settings: { model_id: 'openai-gpt-4.1' },
metadata: {
heuristics: { properties: ['multilingual', 'multimodal'], status: 'ga' },
display: { name: 'OpenAI GPT-4.1', model_creator: 'OpenAI' },
},
},
{
inference_id: '.mock-openai-gpt-4.1-completion-d5f6',
task_type: 'completion',
service: 'elastic',
service_settings: { model_id: 'openai-gpt-4.1' },
metadata: {
heuristics: { properties: ['multilingual', 'multimodal'], status: 'ga' },
display: { name: 'OpenAI GPT-4.1', model_creator: 'OpenAI' },
},
},
{
inference_id: '.mock-google-gemini-2.5-pro-chat_completion-e2a8',
task_type: 'chat_completion',
service: 'elastic',
service_settings: { model_id: 'google-gemini-2.5-pro' },
metadata: {
heuristics: { properties: ['multilingual', 'multimodal'], status: 'ga' },
display: { name: 'Google Gemini 2.5 Pro', model_creator: 'Google' },
},
},
{
inference_id: '.mock-google-gemini-2.5-pro-completion-f1b3',
task_type: 'completion',
service: 'elastic',
service_settings: { model_id: 'google-gemini-2.5-pro' },
metadata: {
heuristics: { properties: ['multilingual', 'multimodal'], status: 'ga' },
display: { name: 'Google Gemini 2.5 Pro', model_creator: 'Google' },
},
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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.
*/

import type { ScoutPage } from '@kbn/scout';

const CONNECTORS_ROUTE = '**/internal/inference/connectors';
const ENDPOINTS_ROUTE = '**/internal/inference_endpoints/endpoints';

export async function mockConnectors(page: ScoutPage) {
await page.route(CONNECTORS_ROUTE, async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
connectors: [
{
connectorId: 'mock-connector',
name: 'Mock Connector',
type: '.gen-ai',
config: {},
capabilities: {},
isPreconfigured: false,
},
],
}),
});
});
}

export async function mockEmptyConnectors(page: ScoutPage) {
await page.route(CONNECTORS_ROUTE, async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ connectors: [] }),
});
});
}

export async function unmockConnectors(page: ScoutPage) {
await page.unroute(CONNECTORS_ROUTE);
}

export async function mockInferenceEndpoints(page: ScoutPage, endpoints: unknown[]) {
await page.route(ENDPOINTS_ROUTE, async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ inference_endpoints: endpoints }),
});
});
}

export async function unmockInferenceEndpoints(page: ScoutPage) {
await page.unroute(ENDPOINTS_ROUTE);
}
Loading
Loading