Skip to content

Commit 52c0a54

Browse files
[Inference UI] Add scout tests for feature settings page (elastic#261790)
## Summary Adds Scout tests for the Feature Settings (Model Settings) page under Stack Management. This page allows users to configure default AI models and manage per-feature inference endpoint assignments. ### How to run the tests ``` node scripts/scout.js start-server --arch stateful --domain classic npx playwright test --config .../test/scout/ui/playwright.config.ts --project local --headed feature_settings.spec ``` ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ...
1 parent 810bda0 commit 52c0a54

24 files changed

Lines changed: 777 additions & 3 deletions

File tree

.agents/skills/scout-ui-testing/SKILL.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,14 @@ description: Use when creating, updating, debugging, or reviewing Scout UI tests
3838
## Page objects (UI)
3939

4040
- Prefer `page.testSubj.locator(...)`, role/label locators; avoid brittle CSS.
41-
- Keep selectors + interactions inside the page object class.
41+
- 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.
42+
- **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.
4243
- Don't make API calls from page objects (use `apiServices`/`kbnClient` in hooks instead).
4344
- Register plugin page objects by extending the `pageObjects` fixture in `test/scout*/ui/fixtures/index.ts`.
45+
- **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.
4446
- 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.
47+
- **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.
48+
- **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.
4549

4650
## Parallel UI specifics (spaceTest)
4751

.buildkite/scout_ci_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ plugins:
3535
- saved_objects_management
3636
- search_getting_started
3737
- search_homepage
38+
- search_inference_endpoints
3839
- security
3940
- security_solution
4041
- share

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,7 @@ x-pack/platform/test/plugin_api_perf/plugins/task_manager_performance @elastic/r
12001200
x-pack/platform/test/reporting_api_integration/plugins/reporting_fixture @elastic/response-ops
12011201
x-pack/platform/test/reporting_api_integration/plugins/reporting_test_routes @elastic/response-ops
12021202
x-pack/platform/test/saved_object_api_integration/common/plugins/saved_object_test_plugin @elastic/kibana-security
1203+
x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture @elastic/search-kibana
12031204
x-pack/platform/test/security_api_integration/packages/helpers @elastic/kibana-security
12041205
x-pack/platform/test/security_api_integration/plugins/audit_log @elastic/kibana-security
12051206
x-pack/platform/test/security_api_integration/plugins/features_provider @elastic/kibana-security

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,7 @@
999999
"@kbn/search-homepage": "link:x-pack/solutions/search/plugins/search_homepage",
10001000
"@kbn/search-index-documents": "link:x-pack/platform/packages/shared/kbn-search-index-documents",
10011001
"@kbn/search-inference-endpoints": "link:x-pack/platform/plugins/shared/search_inference_endpoints",
1002+
"@kbn/search-inference-endpoints-fixture-plugin": "link:x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture",
10021003
"@kbn/search-navigation": "link:x-pack/solutions/search/plugins/search_navigation",
10031004
"@kbn/search-notebooks": "link:x-pack/solutions/search/plugins/search_notebooks",
10041005
"@kbn/search-playground": "link:x-pack/solutions/search/plugins/search_playground",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
import { resolve } from 'path';
11+
import { REPO_ROOT } from '@kbn/repo-info';
12+
import { servers as defaultConfig } from '../../default/serverless/search.serverless.config';
13+
import type { ScoutServerConfig } from '../../../../../types';
14+
15+
const pluginPath = `--plugin-path=${resolve(
16+
REPO_ROOT,
17+
'x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture'
18+
)}`;
19+
20+
export const servers: ScoutServerConfig = {
21+
...defaultConfig,
22+
kbnTestServer: {
23+
...defaultConfig.kbnTestServer,
24+
serverArgs: [...defaultConfig.kbnTestServer.serverArgs, pluginPath],
25+
},
26+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
import { resolve } from 'path';
11+
import { REPO_ROOT } from '@kbn/repo-info';
12+
import type { ScoutServerConfig } from '../../../../../types';
13+
import { defaultConfig } from '../../default/stateful/base.config';
14+
15+
const pluginPath = `--plugin-path=${resolve(
16+
REPO_ROOT,
17+
'x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture'
18+
)}`;
19+
20+
export const servers: ScoutServerConfig = {
21+
...defaultConfig,
22+
kbnTestServer: {
23+
...defaultConfig.kbnTestServer,
24+
serverArgs: [...defaultConfig.kbnTestServer.serverArgs, pluginPath],
25+
},
26+
};

tsconfig.base.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,6 +2042,8 @@
20422042
"@kbn/search-index-documents/*": ["x-pack/platform/packages/shared/kbn-search-index-documents/*"],
20432043
"@kbn/search-inference-endpoints": ["x-pack/platform/plugins/shared/search_inference_endpoints"],
20442044
"@kbn/search-inference-endpoints/*": ["x-pack/platform/plugins/shared/search_inference_endpoints/*"],
2045+
"@kbn/search-inference-endpoints-fixture-plugin": ["x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture"],
2046+
"@kbn/search-inference-endpoints-fixture-plugin/*": ["x-pack/platform/test/search_inference_endpoints/plugins/search_inference_endpoints_fixture/*"],
20452047
"@kbn/search-navigation": ["x-pack/solutions/search/plugins/search_navigation"],
20462048
"@kbn/search-navigation/*": ["x-pack/solutions/search/plugins/search_navigation/*"],
20472049
"@kbn/search-notebooks": ["x-pack/solutions/search/plugins/search_notebooks"],

x-pack/platform/plugins/shared/search_inference_endpoints/moon.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ dependsOn:
5353
- '@kbn/inference-common'
5454
- '@kbn/inference-plugin'
5555
- '@kbn/management-settings-ids'
56+
- '@kbn/scout'
5657
tags:
5758
- plugin
5859
- prod
@@ -65,6 +66,7 @@ fileGroups:
6566
- common/**/*
6667
- public/**/*
6768
- server/**/*
69+
- test/scout_inference_test/**/*
6870
- '!target/**/*'
6971
jest-config:
7072
- jest.config.js

x-pack/platform/plugins/shared/search_inference_endpoints/public/components/settings/add_model_popover.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ export const AddModelPopover: React.FC<AddModelPopoverProps> = ({
104104
onChange={handleChange}
105105
singleSelection
106106
searchable
107+
data-test-subj="add-model-selectable"
107108
searchProps={{
108109
placeholder: i18n.translate('xpack.searchInferenceEndpoints.settings.addModel.search', {
109110
defaultMessage: 'Search models...',
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import type { PageObjects, ScoutTestFixtures, ScoutWorkerFixtures } from '@kbn/scout';
9+
import { test as baseTest, createLazyPageObject } from '@kbn/scout';
10+
import { FeatureSettingsPage } from './page_objects';
11+
12+
export interface ExtScoutTestFixtures extends ScoutTestFixtures {
13+
pageObjects: PageObjects & {
14+
featureSettings: FeatureSettingsPage;
15+
};
16+
}
17+
18+
export const test = baseTest.extend<ExtScoutTestFixtures, ScoutWorkerFixtures>({
19+
pageObjects: async (
20+
{
21+
pageObjects,
22+
page,
23+
}: {
24+
pageObjects: ExtScoutTestFixtures['pageObjects'];
25+
page: ExtScoutTestFixtures['page'];
26+
},
27+
use: (pageObjects: ExtScoutTestFixtures['pageObjects']) => Promise<void>
28+
) => {
29+
const extendedPageObjects = {
30+
...pageObjects,
31+
featureSettings: createLazyPageObject(FeatureSettingsPage, page),
32+
};
33+
34+
await use(extendedPageObjects);
35+
},
36+
});

0 commit comments

Comments
 (0)