From c354e7e83459524a1aad86dcc9825ba38f667f9a Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Thu, 13 Nov 2025 00:27:08 -0600
Subject: [PATCH 01/41] home_page test port
---
.buildkite/scout_ci_config.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.buildkite/scout_ci_config.yml b/.buildkite/scout_ci_config.yml
index f63440018e772..09c55901434a5 100644
--- a/.buildkite/scout_ci_config.yml
+++ b/.buildkite/scout_ci_config.yml
@@ -3,6 +3,7 @@ plugins:
enabled:
- apm
- discover_enhanced
+ - index_management
- maps
- observability
- observability_onboarding
From 36d966a593d600f6b37537ad71eb36b1b8aa6971 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Thu, 13 Nov 2025 00:28:22 -0600
Subject: [PATCH 02/41] home_page test port
---
.../test/scout/ui/fixtures/index.ts | 32 +++++
.../scout/ui/fixtures/page_objects/index.ts | 24 ++++
.../page_objects/index_management_page.ts | 81 +++++++++++++
.../test/scout/ui/playwright.config.ts | 12 ++
.../test/scout/ui/tests/home_page.spec.ts | 111 ++++++++++++++++++
5 files changed, 260 insertions(+)
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index.ts
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/playwright.config.ts
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
new file mode 100644
index 0000000000000..7f79274779652
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
@@ -0,0 +1,32 @@
+/*
+ * 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 { test as base } from '@kbn/scout';
+import type { ScoutPage, ScoutTestFixtures, ScoutWorkerFixtures } from '@kbn/scout';
+
+import type { IndexManagementPageObjects } from './page_objects';
+import { extendPageObjects } from './page_objects';
+
+export interface ConsoleTestFixtures extends ScoutTestFixtures {
+ pageObjects: IndexManagementPageObjects;
+}
+
+export const test = base.extend({
+ pageObjects: async (
+ {
+ pageObjects,
+ page,
+ }: {
+ pageObjects: IndexManagementPageObjects;
+ page: ScoutPage;
+ },
+ use: (pageObjects: IndexManagementPageObjects) => Promise
+ ) => {
+ const extendedPageObjects = extendPageObjects(pageObjects, page);
+ await use(extendedPageObjects);
+ },
+});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index.ts
new file mode 100644
index 0000000000000..ef6d312f3a37f
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index.ts
@@ -0,0 +1,24 @@
+/*
+ * 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, ScoutPage } from '@kbn/scout';
+import { createLazyPageObject } from '@kbn/scout';
+import { IndexManagement } from './index_management_page';
+
+export interface IndexManagementPageObjects extends PageObjects {
+ indexManagement: IndexManagement;
+}
+
+export function extendPageObjects(
+ pageObjects: PageObjects,
+ page: ScoutPage
+): IndexManagementPageObjects {
+ return {
+ ...pageObjects,
+ indexManagement: createLazyPageObject(IndexManagement, page),
+ };
+}
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
new file mode 100644
index 0000000000000..671eb1e79192a
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -0,0 +1,81 @@
+/*
+ * 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';
+
+export class IndexManagement {
+ constructor(public readonly page: ScoutPage) {}
+
+ async goto() {
+ await this.page.gotoApp('management/data/index_management');
+ }
+
+ async sectionHeadingText() {
+ return await this.page.testSubj.locator('appTitle').textContent();
+ }
+
+ async changeTabs(
+ tab:
+ | 'indicesTab'
+ | 'data_streamsTab'
+ | 'templatesTab'
+ | 'component_templatesTab'
+ | 'enrich_policiesTab'
+ ) {
+ await this.page.testSubj.locator(tab).click();
+ }
+
+ async clickCreateIndexButton() {
+ await this.page.testSubj.locator('createIndexButton').click();
+ }
+
+ async setCreateIndexName(value: string) {
+ const nameField = this.page.testSubj.locator('createIndexNameFieldText');
+ await nameField.waitFor({ state: 'visible' });
+ await nameField.fill(value);
+ }
+
+ async setCreateIndexMode(value: string) {
+ const modeField = this.page.testSubj.locator('indexModeField');
+ await modeField.waitFor({ state: 'visible' });
+ // await this.page.pause();
+ await modeField.click();
+ await this.page.testSubj.locator(`indexMode${value}Option`).click();
+ }
+
+ async clickCreateIndexSaveButton() {
+ const saveButton = this.page.testSubj.locator('createIndexSaveButton');
+ await saveButton.waitFor({ state: 'visible' });
+ await saveButton.click();
+ // Wait for modal to close
+ await saveButton.waitFor({ state: 'hidden', timeout: 30000 });
+ }
+
+ async expectIndexToExist(indexName: string) {
+ // Wait for the table to be visible
+ const table = this.page.locator('table');
+ await table.waitFor({ state: 'visible' });
+
+ // Get all index name links
+ const indexLinks = this.page.testSubj.locator('indexTableIndexNameLink');
+ const count = await indexLinks.count();
+
+ // Check if any of the links contain the index name
+ let found = false;
+ for (let i = 0; i < count; i++) {
+ const text = await indexLinks.nth(i).textContent();
+ if (text === indexName) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ throw new Error(`Expected index "${indexName}" to exist in the table, but it was not found`);
+ }
+ }
+}
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/playwright.config.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/playwright.config.ts
new file mode 100644
index 0000000000000..75a7694d12043
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/playwright.config.ts
@@ -0,0 +1,12 @@
+/*
+ * 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 { createPlaywrightConfig } from '@kbn/scout';
+
+export default createPlaywrightConfig({
+ testDir: './tests',
+});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
new file mode 100644
index 0000000000000..fe2c90cb23070
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
@@ -0,0 +1,111 @@
+/*
+ * 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 { expect } from '@kbn/scout';
+import { test } from '../fixtures';
+
+test.describe('Home page', { tag: ['@ess'] }, () => {
+ test.beforeEach(async ({ browserAuth, pageObjects }) => {
+ // TODO: Create loginAsIndexManagementUser role
+ await browserAuth.loginAsAdmin();
+ await pageObjects.indexManagement.goto();
+ });
+
+ test('Loads the app and renders the indices tab by default', async ({
+ pageObjects,
+ log,
+ page,
+ }) => {
+ await log.debug('Checking for section heading to say Index Management.');
+
+ const headingText = await pageObjects.indexManagement.sectionHeadingText();
+ expect(headingText).toBe('Index Management');
+
+ // Verify url
+ expect(page.url()).toContain('/indices');
+
+ // Verify content
+ await expect(page.testSubj.locator('indicesList')).toBeVisible();
+ await expect(page.testSubj.locator('reloadIndicesButton')).toBeVisible();
+ });
+
+ test('Indices - renders the indices tab', async ({ pageObjects, page }) => {
+ // Navigate to the indices tab
+ await pageObjects.indexManagement.changeTabs('indicesTab');
+
+ // Verify url
+ expect(page.url()).toContain('/indices');
+
+ // Verify content - wait for table to be visible
+ await expect(page.testSubj.locator('indexTable')).toBeVisible();
+ });
+
+ test('Indices - can create an index', async ({ pageObjects, esClient, log }) => {
+ const testIndexName = `index-test-${Math.random()}`;
+
+ await pageObjects.indexManagement.clickCreateIndexButton();
+ await pageObjects.indexManagement.setCreateIndexName(testIndexName);
+ await pageObjects.indexManagement.setCreateIndexMode('Lookup');
+ await pageObjects.indexManagement.clickCreateIndexSaveButton();
+ await pageObjects.indexManagement.expectIndexToExist(testIndexName);
+
+ // Cleanup
+ try {
+ await esClient.indices.delete({ index: testIndexName });
+ } catch (e: any) {
+ log.debug(`Index cleanup failed for ${testIndexName}: ${e.message}`);
+ }
+ });
+
+ test('Data streams - renders the data streams tab', async ({ pageObjects, page }) => {
+ // Navigate to the data streams tab
+ await pageObjects.indexManagement.changeTabs('data_streamsTab');
+
+ // Verify url
+ expect(page.url()).toContain('/data_streams');
+
+ // Verify content - wait for table to be visible
+ await expect(page.testSubj.locator('dataStreamTable')).toBeVisible();
+ });
+
+ test('Index templates - renders the index templates tab', async ({ pageObjects, page }) => {
+ // Navigate to the index templates tab
+ await pageObjects.indexManagement.changeTabs('templatesTab');
+
+ // Verify url
+ expect(page.url()).toContain('/templates');
+
+ // Verify content
+ await expect(page.testSubj.locator('templateList')).toBeVisible();
+ });
+
+ test('Component templates - renders the component templates tab', async ({
+ pageObjects,
+ page,
+ }) => {
+ // Navigate to the component templates tab
+ await pageObjects.indexManagement.changeTabs('component_templatesTab');
+
+ // Verify url
+ expect(page.url()).toContain('/component_templates');
+
+ // Verify content. Component templates may have been created by other apps, e.g. Ingest Manager,
+ // so we don't make any assertion about the presence or absence of component templates.
+ await expect(page.testSubj.locator('componentTemplateList')).toBeVisible();
+ });
+
+ test('Enrich policies - renders the enrich policies tab', async ({ pageObjects, page }) => {
+ // Navigate to the enrich policies tab
+ await pageObjects.indexManagement.changeTabs('enrich_policiesTab');
+
+ // Verify url
+ expect(page.url()).toContain('/enrich_policies');
+
+ // Verify content
+ await expect(page.testSubj.locator('sectionEmpty')).toBeVisible();
+ });
+});
From f3b31407dc03e78909b4553c0c45e996b54db936 Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Thu, 13 Nov 2025 06:39:22 +0000
Subject: [PATCH 03/41] Changes from node scripts/lint_ts_projects --fix
---
x-pack/platform/plugins/shared/index_management/tsconfig.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/x-pack/platform/plugins/shared/index_management/tsconfig.json b/x-pack/platform/plugins/shared/index_management/tsconfig.json
index 45a1243ac270f..a8e5357b3ed39 100644
--- a/x-pack/platform/plugins/shared/index_management/tsconfig.json
+++ b/x-pack/platform/plugins/shared/index_management/tsconfig.json
@@ -65,7 +65,8 @@
"@kbn/inference-common",
"@kbn/upgrade-assistant-pkg-common",
"@kbn/failure-store-modal",
- "@kbn/react-query"
+ "@kbn/react-query",
+ "@kbn/scout"
],
"exclude": ["target/**/*"]
}
From e7f7760a27feae49bc9cbc16281b94674fb05368 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Thu, 13 Nov 2025 09:26:17 -0600
Subject: [PATCH 04/41] fix lint issues
---
.../page_objects/index_management_page.ts | 57 +++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index 671eb1e79192a..4f22669d6f6cf 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -67,6 +67,8 @@ export class IndexManagement {
// Check if any of the links contain the index name
let found = false;
for (let i = 0; i < count; i++) {
+ // todo
+ // eslint-disable-next-line playwright/no-nth-methods
const text = await indexLinks.nth(i).textContent();
if (text === indexName) {
found = true;
@@ -78,4 +80,59 @@ export class IndexManagement {
throw new Error(`Expected index "${indexName}" to exist in the table, but it was not found`);
}
}
+
+ async toggleHiddenIndices() {
+ await this.page.testSubj.locator('checkboxToggles-includeHiddenIndices').click();
+ }
+
+ async openIndexDetailsPage(indexOfRow: number) {
+ const indexLinks = this.page.testSubj.locator('indexTableIndexNameLink');
+ // todo
+ // eslint-disable-next-line playwright/no-nth-methods
+ await indexLinks.nth(indexOfRow).click();
+
+ // Wait for index details page to load
+ await this.page.testSubj.locator('indexDetailsHeader').waitFor({ state: 'visible' });
+ }
+
+ async navigateToIndexManagementTab(
+ tab: 'indices' | 'data_streams' | 'templates' | 'component_templates' | 'enrich_policies'
+ ) {
+ await this.goto();
+ const tabMap = {
+ indices: 'indicesTab',
+ data_streams: 'data_streamsTab',
+ templates: 'templatesTab',
+ component_templates: 'component_templatesTab',
+ enrich_policies: 'enrich_policiesTab',
+ };
+ await this.page.testSubj.locator(tabMap[tab]).click();
+ }
+
+ async clickNextButton() {
+ await this.page.testSubj.locator('nextButton').click();
+ }
+
+ async setComboBox(testSubject: string, value: string) {
+ const comboBox = this.page.testSubj.locator(testSubject);
+ await comboBox.click();
+
+ // Type the value
+ const input = comboBox.locator('input');
+ await input.fill(value);
+
+ // Wait for and click the option
+ const option = this.page.locator(`[role="option"]`).filter({ hasText: value });
+ await option.waitFor({ state: 'visible' });
+ await option.click();
+ }
+
+ async changeMappingsEditorTab(tab: 'fields' | 'advancedOptions' | 'templates') {
+ const tabMap = {
+ fields: 'formTab',
+ advancedOptions: 'advancedOptionsTab',
+ templates: 'templatesTab',
+ };
+ await this.page.testSubj.locator(tabMap[tab]).click();
+ }
}
From b32f61fb5b7829710b8735ca3c7fb12437b239e6 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Thu, 13 Nov 2025 09:27:08 -0600
Subject: [PATCH 05/41] fix lint issues
---
.../scout/ui/tests/index_details_page.spec.ts | 37 ++
.../ui/tests/index_template_wizard.spec.ts | 344 ++++++++++++++++++
2 files changed, 381 insertions(+)
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
new file mode 100644
index 0000000000000..fce4d056edbd7
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
@@ -0,0 +1,37 @@
+/*
+ * 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 { expect } from '@kbn/scout';
+import { test } from '../fixtures';
+
+test.describe('Index details page', { tag: ['@ess'] }, () => {
+ test.beforeEach(async ({ browserAuth, pageObjects }) => {
+ // TODO: Create loginAsIndexManagementUser role
+ await browserAuth.loginAsAdmin();
+ await pageObjects.indexManagement.goto();
+ });
+
+ test('Navigates to the index details page from the home page', async ({
+ pageObjects,
+ log,
+ page,
+ }) => {
+ await log.debug('Navigating to the index details page');
+
+ // Display hidden indices to have some rows in the indices table
+ await pageObjects.indexManagement.toggleHiddenIndices();
+
+ // Click the first index in the table and wait for the index details page
+ await pageObjects.indexManagement.openIndexDetailsPage(0);
+
+ // Verify index details page is loaded
+ await expect(page.testSubj.locator('indexDetailsTab-overview')).toBeVisible();
+ await expect(page.testSubj.locator('indexDetailsContent')).toBeVisible();
+ await expect(page.testSubj.locator('indexDetailsBackToIndicesButton')).toBeVisible();
+ });
+});
+
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
new file mode 100644
index 0000000000000..e82ad55b33805
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -0,0 +1,344 @@
+/*
+ * 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 { expect } from '@kbn/scout';
+import { test } from '../fixtures';
+
+test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
+ test.beforeEach(async ({ browserAuth, pageObjects, page }) => {
+ // TODO: Create loginAsIndexManagementUser role
+ await browserAuth.loginAsAdmin();
+ await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
+ // Click Create Template button
+ await page.testSubj.locator('createTemplateButton').click();
+ });
+
+ test.afterEach(async ({ esClient, log }) => {
+ try {
+ await esClient.indices.deleteIndexTemplate({ name: 'test-index-template' });
+ } catch (e) {
+ log.debug(
+ `Template cleanup failed for test-index-template: ${
+ e instanceof Error ? e.message : String(e)
+ }`
+ );
+ }
+ });
+
+ test('should set the correct page title', async ({ page }) => {
+ await expect(page.testSubj.locator('pageTitle')).toBeVisible();
+ await expect(page.testSubj.locator('pageTitle')).toHaveText('Create template');
+ });
+
+ test('renders logistics (step 1)', async ({ page, pageObjects }) => {
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Logistics');
+
+ // Fill out required fields
+ await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ test('renders component templates (step 2)', async ({ page, pageObjects }) => {
+ // Fill logistics step
+ await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify empty prompt
+ await expect(page.testSubj.locator('emptyPrompt')).toBeVisible();
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ test('renders index settings (step 3)', async ({ page, pageObjects }) => {
+ // Fill logistics step
+ await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Skip component templates step
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Index settings (optional)');
+
+ // Verify that index mode callout is displayed
+ await expect(page.testSubj.locator('indexModeCallout')).toHaveText(
+ 'The index.mode setting has been set to Standard within the Logistics step. Any changes to index.mode set on this page will be overwritten by the Logistics selection.'
+ );
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ test('renders mappings (step 4)', async ({ page, pageObjects }) => {
+ // Fill logistics step
+ await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Skip component templates and settings steps
+ await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ test('renders aliases (step 5)', async ({ page, pageObjects }) => {
+ // Fill logistics step
+ await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Skip component templates, settings, and mappings steps
+ await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Aliases (optional)');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ test('renders review template (step 6)', async ({ page, pageObjects }) => {
+ // Fill logistics step
+ await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Skip all intermediate steps
+ await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText(
+ "Review details for 'test-index-template'"
+ );
+
+ // Verify that summary exists
+ await expect(page.testSubj.locator('summaryTabContent')).toBeVisible();
+
+ // Verify that index mode is set to "Standard"
+ await expect(page.testSubj.locator('indexModeTitle')).toBeVisible();
+ await expect(page.testSubj.locator('indexModeValue')).toHaveText('Standard');
+
+ // Click Create template
+ await pageObjects.indexManagement.clickNextButton();
+ });
+});
+
+test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, () => {
+ test.beforeEach(async ({ browserAuth, pageObjects }) => {
+ // TODO: Create loginAsIndexManagementUser role
+ await browserAuth.loginAsAdmin();
+ await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
+ });
+
+ test('can preview index template that matches a_fake_index_pattern_that_wont_match_any_indices', async ({
+ page,
+ pageObjects,
+ esClient,
+ log,
+ }) => {
+ // Click Create Template button
+ await page.testSubj.locator('createTemplateButton').click();
+ await expect(page.testSubj.locator('pageTitle')).toHaveText('Create template');
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Logistics');
+
+ // Fill out required fields
+ await page.testSubj.locator('nameField').locator('input').fill('a-star');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('a*');
+ await page.testSubj.locator('priorityField').locator('input').fill('1000');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify empty prompt
+ await expect(page.testSubj.locator('emptyPrompt')).toBeVisible();
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Index settings (optional)');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Aliases (optional)');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText("Review details for 'a-star'");
+
+ // Verify that summary exists
+ await expect(page.testSubj.locator('summaryTabContent')).toBeVisible();
+
+ // Verify that index mode is set to "Standard"
+ await expect(page.testSubj.locator('indexModeTitle')).toBeVisible();
+ await expect(page.testSubj.locator('indexModeValue')).toHaveText('Standard');
+
+ // Click Create template
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Click preview tab, we know its the last one
+ const tabs = page.testSubj.locator('tab');
+ const tabCount = await tabs.count();
+ // todo
+ // eslint-disable-next-line playwright/no-nth-methods
+ await tabs.nth(tabCount - 1).click();
+
+ const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
+ expect(templatePreview).not.toContain('error');
+
+ await page.testSubj.locator('closeDetailsButton').click();
+
+ // Cleanup
+ try {
+ await esClient.indices.deleteIndexTemplate({ name: 'a-star' });
+ } catch (e) {
+ log.debug(
+ `Template cleanup failed for a-star: ${e instanceof Error ? e.message : String(e)}`
+ );
+ }
+ });
+});
+
+test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () => {
+ test.beforeEach(async ({ browserAuth, pageObjects, page }) => {
+ // TODO: Create loginAsIndexManagementUser role
+ await browserAuth.loginAsAdmin();
+ await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
+
+ // Click Create Template button
+ await page.testSubj.locator('createTemplateButton').click();
+
+ // Fill out required fields
+ await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
+
+ // Go to Mappings step
+ await page.testSubj.locator('formWizardStep-3').click();
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
+ });
+
+ test.afterEach(async ({ esClient, log }) => {
+ try {
+ await esClient.indices.deleteIndexTemplate({ name: 'test-index-template' });
+ } catch (e) {
+ log.debug(
+ `Template cleanup failed in mappings test: ${e instanceof Error ? e.message : String(e)}`
+ );
+ }
+ });
+
+ test("clearing up the Numeric subtype dropdown doesn't break the page", async ({
+ page,
+ pageObjects,
+ }) => {
+ // Add a mapping field
+ await page.testSubj.locator('addFieldButton').click();
+
+ // Select Numeric type
+ await pageObjects.indexManagement.setComboBox('fieldType', 'Numeric');
+
+ // Clear up subtype dropdown
+ await page.testSubj.locator('fieldSubType').click();
+ await page.keyboard.press('Backspace');
+
+ // Verify that elements are still visible
+ await expect(page.testSubj.locator('addFieldButton')).toBeVisible();
+ await expect(page.testSubj.locator('fieldType')).toBeVisible();
+ await expect(page.testSubj.locator('fieldSubType')).toBeVisible();
+ await expect(page.testSubj.locator('nextButton')).toBeVisible();
+ });
+
+ test("clearing up the Range subtype dropdown doesn't break the page", async ({
+ page,
+ pageObjects,
+ }) => {
+ // Add a mapping field
+ await page.testSubj.locator('addFieldButton').click();
+
+ // Select Range type
+ await pageObjects.indexManagement.setComboBox('fieldType', 'Range');
+
+ // Clear up subtype dropdown
+ await page.testSubj.locator('fieldSubType').click();
+ await page.keyboard.press('Backspace');
+
+ // Verify that elements are still visible
+ await expect(page.testSubj.locator('addFieldButton')).toBeVisible();
+ await expect(page.testSubj.locator('fieldType')).toBeVisible();
+ await expect(page.testSubj.locator('fieldSubType')).toBeVisible();
+ await expect(page.testSubj.locator('nextButton')).toBeVisible();
+ });
+
+ test("advanced options tab doesn't add default values to request by default", async ({
+ page,
+ pageObjects,
+ log,
+ }) => {
+ await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
+ await page.testSubj.locator('previewIndexTemplate').click();
+ const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
+
+ log.debug(`Template preview text: ${templatePreview}`);
+
+ // All advanced options should not be part of the request
+ expect(templatePreview).not.toContain('"dynamic"');
+ expect(templatePreview).not.toContain('"subobjects"');
+ expect(templatePreview).not.toContain('"dynamic_date_formats"');
+ expect(templatePreview).not.toContain('"date_detection"');
+ expect(templatePreview).not.toContain('"numeric_detection"');
+ });
+
+ test('advanced options tab adds the set values to the request', async ({
+ page,
+ pageObjects,
+ log,
+ }) => {
+ await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
+
+ // Toggle the subobjects field to false
+ await page.testSubj.locator('subobjectsToggle').click();
+
+ await page.testSubj.locator('previewIndexTemplate').click();
+ const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
+
+ log.debug(`Template preview text: ${templatePreview}`);
+
+ // Only the subobjects option should be part of the request
+ expect(templatePreview).toContain('"subobjects": false');
+ expect(templatePreview).not.toContain('"dynamic"');
+ expect(templatePreview).not.toContain('"dynamic_date_formats"');
+ expect(templatePreview).not.toContain('"date_detection"');
+ expect(templatePreview).not.toContain('"numeric_detection"');
+ });
+});
From 57f2ef80db55768bdc6ffaf28c0281585302efb4 Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Thu, 13 Nov 2025 15:54:06 +0000
Subject: [PATCH 06/41] Changes from node scripts/eslint_all_files --no-cache
--fix
---
.../test/scout/ui/tests/index_details_page.spec.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
index fce4d056edbd7..f4d0a1b7805b1 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
@@ -34,4 +34,3 @@ test.describe('Index details page', { tag: ['@ess'] }, () => {
await expect(page.testSubj.locator('indexDetailsBackToIndicesButton')).toBeVisible();
});
});
-
From e320a3af7b57e45e1acde46353bf27c1a55d1e1e Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Thu, 13 Nov 2025 17:38:27 -0600
Subject: [PATCH 07/41] make data-test-subj's unique
---
.../public/application/components/no_match/no_match.tsx | 8 +++++++-
.../home/index_list/create_index/create_index_button.tsx | 5 +++--
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/public/application/components/no_match/no_match.tsx b/x-pack/platform/plugins/shared/index_management/public/application/components/no_match/no_match.tsx
index b1a065a98c81a..a96e4dce62f62 100644
--- a/x-pack/platform/plugins/shared/index_management/public/application/components/no_match/no_match.tsx
+++ b/x-pack/platform/plugins/shared/index_management/public/application/components/no_match/no_match.tsx
@@ -65,7 +65,13 @@ export const NoMatch = ({
if (extensionsService.emptyListContent) {
return extensionsService.emptyListContent.renderContent({
- createIndexButton: ,
+ createIndexButton: (
+
+ ),
});
}
diff --git a/x-pack/platform/plugins/shared/index_management/public/application/sections/home/index_list/create_index/create_index_button.tsx b/x-pack/platform/plugins/shared/index_management/public/application/sections/home/index_list/create_index/create_index_button.tsx
index 4200d9b0d2462..99db6adcc1001 100644
--- a/x-pack/platform/plugins/shared/index_management/public/application/sections/home/index_list/create_index/create_index_button.tsx
+++ b/x-pack/platform/plugins/shared/index_management/public/application/sections/home/index_list/create_index/create_index_button.tsx
@@ -17,9 +17,10 @@ import { useAppContext } from '../../../../app_context';
export interface CreateIndexButtonProps {
loadIndices: () => void;
share?: SharePluginStart;
+ dataTestSubj?: string;
}
-export const CreateIndexButton = ({ loadIndices, share }: CreateIndexButtonProps) => {
+export const CreateIndexButton = ({ loadIndices, share, dataTestSubj }: CreateIndexButtonProps) => {
const [createIndexModalOpen, setCreateIndexModalOpen] = useState(false);
const createIndexUrl = share?.url.locators.get('SEARCH_CREATE_INDEX')?.useUrl({});
@@ -40,7 +41,7 @@ export const CreateIndexButton = ({ loadIndices, share }: CreateIndexButtonProps
fill
iconType="plusInCircleFilled"
key="createIndexButton"
- data-test-subj="createIndexButton"
+ data-test-subj={dataTestSubj || 'createIndexButton'}
data-telemetry-id="idxMgmt-indexList-createIndexButton"
{...actionProp}
>
From 277213c6f65f617444159a52d68d4e7ccaca4330 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 07:40:17 -0600
Subject: [PATCH 08/41] functional test fixes
---
.../components/mappings_editor/mappings_editor.tsx | 8 ++++----
.../public/application/components/no_match/no_match.tsx | 8 +++++++-
.../ui/fixtures/page_objects/index_management_page.ts | 2 +-
.../test/scout/ui/tests/index_details_page.spec.ts | 1 -
.../test/scout/ui/tests/index_template_wizard.spec.ts | 5 +----
5 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/mappings_editor.tsx b/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/mappings_editor.tsx
index c1975d501969b..bf912d1fca1d4 100644
--- a/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/mappings_editor.tsx
+++ b/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/mappings_editor.tsx
@@ -184,7 +184,7 @@ export const MappingsEditor = React.memo(
changeTab('fields')}
isSelected={selectedTab === 'fields'}
- data-test-subj="formTab"
+ data-test-subj="fieldsTab"
>
{i18n.translate('xpack.idxMgmt.mappingsEditor.fieldsTabLabel', {
defaultMessage: 'Mapped fields',
@@ -193,7 +193,7 @@ export const MappingsEditor = React.memo(
changeTab('runtimeFields')}
isSelected={selectedTab === 'runtimeFields'}
- data-test-subj="formTab"
+ data-test-subj="runtimeTab"
>
{i18n.translate('xpack.idxMgmt.mappingsEditor.runtimeFieldsTabLabel', {
defaultMessage: 'Runtime fields',
@@ -202,7 +202,7 @@ export const MappingsEditor = React.memo(
changeTab('templates')}
isSelected={selectedTab === 'templates'}
- data-test-subj="formTab"
+ data-test-subj="templatesTab"
>
{i18n.translate('xpack.idxMgmt.mappingsEditor.templatesTabLabel', {
defaultMessage: 'Dynamic templates',
@@ -211,7 +211,7 @@ export const MappingsEditor = React.memo(
changeTab('advanced')}
isSelected={selectedTab === 'advanced'}
- data-test-subj="formTab"
+ data-test-subj="advancedOptionsTab"
>
{i18n.translate('xpack.idxMgmt.mappingsEditor.advancedTabLabel', {
defaultMessage: 'Advanced options',
diff --git a/x-pack/platform/plugins/shared/index_management/public/application/components/no_match/no_match.tsx b/x-pack/platform/plugins/shared/index_management/public/application/components/no_match/no_match.tsx
index a96e4dce62f62..71673cdd24900 100644
--- a/x-pack/platform/plugins/shared/index_management/public/application/components/no_match/no_match.tsx
+++ b/x-pack/platform/plugins/shared/index_management/public/application/components/no_match/no_match.tsx
@@ -94,7 +94,13 @@ export const NoMatch = ({
/>
}
- actions={}
+ actions={
+
+ }
/>
);
};
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index 4f22669d6f6cf..75bf4e83801d3 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -129,7 +129,7 @@ export class IndexManagement {
async changeMappingsEditorTab(tab: 'fields' | 'advancedOptions' | 'templates') {
const tabMap = {
- fields: 'formTab',
+ fields: 'fieldsTab',
advancedOptions: 'advancedOptionsTab',
templates: 'templatesTab',
};
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
index fce4d056edbd7..f4d0a1b7805b1 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
@@ -34,4 +34,3 @@ test.describe('Index details page', { tag: ['@ess'] }, () => {
await expect(page.testSubj.locator('indexDetailsBackToIndicesButton')).toBeVisible();
});
});
-
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index e82ad55b33805..857924c79aaea 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -263,8 +263,6 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
pageObjects,
}) => {
// Add a mapping field
- await page.testSubj.locator('addFieldButton').click();
-
// Select Numeric type
await pageObjects.indexManagement.setComboBox('fieldType', 'Numeric');
@@ -284,8 +282,6 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
pageObjects,
}) => {
// Add a mapping field
- await page.testSubj.locator('addFieldButton').click();
-
// Select Range type
await pageObjects.indexManagement.setComboBox('fieldType', 'Range');
@@ -305,6 +301,7 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
pageObjects,
log,
}) => {
+ await page.pause();
await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
await page.testSubj.locator('previewIndexTemplate').click();
const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
From 5c2671bd4a2027fcfc584419a01eb30895da3cd4 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 08:18:38 -0600
Subject: [PATCH 09/41] remove page.pause
---
.../test/scout/ui/tests/index_template_wizard.spec.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 857924c79aaea..2da19dc9d794c 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -301,7 +301,6 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
pageObjects,
log,
}) => {
- await page.pause();
await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
await page.testSubj.locator('previewIndexTemplate').click();
const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
From e6538db1d7132aea020c44cc42b5ed5c2c51dc06 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 11:07:22 -0600
Subject: [PATCH 10/41] fix jest tests
---
.../template_create.test.tsx | 22 ++++++++-----------
.../template_form.helpers.ts | 4 ++--
.../helpers/mappings_editor.helpers.tsx | 3 ++-
.../mappings_editor.test.tsx | 10 ++++-----
4 files changed, 17 insertions(+), 22 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx
index e58bcbf951a17..63718bd8e4c69 100644
--- a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx
+++ b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx
@@ -390,21 +390,14 @@ describe('', () => {
});
describe('plugin parameters', () => {
- const selectMappingsEditorTab = async (
- tab: 'fields' | 'runtimeFields' | 'templates' | 'advanced'
- ) => {
- const tabIndex = ['fields', 'runtimeFields', 'templates', 'advanced'].indexOf(tab);
- const tabElement = testBed.find('mappingsEditor.formTab').at(tabIndex);
- await act(async () => {
- tabElement.simulate('click');
- });
- testBed.component.update();
- };
-
test('should not render the _size parameter if the mapper size plugin is not installed', async () => {
const { exists } = testBed;
// Navigate to the advanced configuration
- await selectMappingsEditorTab('advanced');
+
+ await act(async () => {
+ testBed.find('advancedOptionsTab').simulate('click');
+ });
+ testBed.component.update();
expect(exists('mappingsEditor.advancedConfiguration.sizeEnabledToggle')).toBe(false);
});
@@ -418,7 +411,10 @@ describe('', () => {
testBed.component.update();
await navigateToMappingsStep();
- await selectMappingsEditorTab('advanced');
+ await act(async () => {
+ testBed.find('advancedOptionsTab').simulate('click');
+ });
+ testBed.component.update();
expect(testBed.exists('mappingsEditor.advancedConfiguration.sizeEnabledToggle')).toBe(
true
diff --git a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/index_template_wizard/template_form.helpers.ts b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/index_template_wizard/template_form.helpers.ts
index 9b4ed84052d30..43d2f58a62bf6 100644
--- a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/index_template_wizard/template_form.helpers.ts
+++ b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/index_template_wizard/template_form.helpers.ts
@@ -402,6 +402,6 @@ export type TestSubjects =
| 'valueDataRetentionField'
| 'formWizardStep-5'
| 'lifecycleValue'
- | 'mappingsEditor.formTab'
| 'mappingsEditor.advancedConfiguration.sizeEnabledToggle'
- | 'previewIndexTemplate';
+ | 'previewIndexTemplate'
+ | 'advancedOptionsTab';
diff --git a/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.tsx b/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.tsx
index 02f7fb379f552..5b47ae51ab626 100644
--- a/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.tsx
+++ b/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.tsx
@@ -314,8 +314,9 @@ const createActions = (testBed: TestBed) => {
// --- Other ---
const selectTab = async (tab: 'fields' | 'runtimeFields' | 'templates' | 'advanced') => {
const index = ['fields', 'runtimeFields', 'templates', 'advanced'].indexOf(tab);
+ const dataTestSubjValues = ['fieldsTab', 'runtimeTab', 'templatesTab', 'advancedOptionsTab'];
- const tabElement = find('formTab').at(index);
+ const tabElement = find(dataTestSubjValues[index]);
if (tabElement.length === 0) {
throw new Error(`Tab not found: "${tab}"`);
}
diff --git a/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx b/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx
index 9d165da556b19..469709b0ff454 100644
--- a/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx
+++ b/x-pack/platform/plugins/shared/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx
@@ -166,12 +166,10 @@ describe('Mappings editor: core', () => {
test('should have 4 tabs (fields, runtime, template, advanced settings)', () => {
const { find } = testBed;
- const tabs = find('formTab').map((wrapper) => wrapper.text());
-
- expect(tabs).toEqual([
- 'Mapped fields',
- 'Runtime fields',
- 'Dynamic templates',
+ expect(find('fieldsTab').map((wrapper) => wrapper.text())).toEqual(['Mapped fields']);
+ expect(find('runtimeTab').map((wrapper) => wrapper.text())).toEqual(['Runtime fields']);
+ expect(find('templatesTab').map((wrapper) => wrapper.text())).toEqual(['Dynamic templates']);
+ expect(find('advancedOptionsTab').map((wrapper) => wrapper.text())).toEqual([
'Advanced options',
]);
});
From ed6f186fbcdfdea30324ade7cfd25993ce6ccba5 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 11:09:06 -0600
Subject: [PATCH 11/41] remove FTR tests that were ported
---
.../apps/index_management/home_page.ts | 150 ---------
.../functional/apps/index_management/index.ts | 3 -
.../index_management/index_details_page.ts | 31 --
.../index_management/index_template_wizard.ts | 307 ------------------
4 files changed, 491 deletions(-)
delete mode 100644 x-pack/platform/test/functional/apps/index_management/home_page.ts
delete mode 100644 x-pack/platform/test/functional/apps/index_management/index_details_page.ts
delete mode 100644 x-pack/platform/test/functional/apps/index_management/index_template_wizard.ts
diff --git a/x-pack/platform/test/functional/apps/index_management/home_page.ts b/x-pack/platform/test/functional/apps/index_management/home_page.ts
deleted file mode 100644
index 3cdcadef65b40..0000000000000
--- a/x-pack/platform/test/functional/apps/index_management/home_page.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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 expect from '@kbn/expect';
-import type { FtrProviderContext } from '../../ftr_provider_context';
-
-export default ({ getPageObjects, getService }: FtrProviderContext) => {
- const testSubjects = getService('testSubjects');
- const pageObjects = getPageObjects(['common', 'indexManagement', 'header']);
- const log = getService('log');
- const browser = getService('browser');
- const retry = getService('retry');
- const security = getService('security');
- const es = getService('es');
-
- describe('Home page', function () {
- before(async () => {
- await security.testUser.setRoles(['index_management_user']);
- await pageObjects.common.navigateToApp('indexManagement');
- });
-
- it('Loads the app and renders the indices tab by default', async () => {
- await log.debug('Checking for section heading to say Index Management.');
-
- const headingText = await pageObjects.indexManagement.sectionHeadingText();
- expect(headingText).to.be('Index Management');
-
- // Verify url
- const url = await browser.getCurrentUrl();
- expect(url).to.contain(`/indices`);
-
- // Verify content
- const indicesList = await testSubjects.exists('indicesList');
- expect(indicesList).to.be(true);
-
- const reloadIndicesButton = await pageObjects.indexManagement.reloadIndicesButton();
- expect(await reloadIndicesButton.isDisplayed()).to.be(true);
- });
-
- describe('Indices', function () {
- const testIndexName = `index-test-${Math.random()}`;
-
- it('renders the indices tab', async () => {
- // Navigate to the data streams tab
- await pageObjects.indexManagement.changeTabs('indicesTab');
-
- await pageObjects.header.waitUntilLoadingHasFinished();
-
- // Verify url
- const url = await browser.getCurrentUrl();
- expect(url).to.contain(`/indices`);
-
- // Verify content
- await retry.waitFor('Wait until indices table is visible.', async () => {
- return await testSubjects.isDisplayed('indexTable');
- });
- });
-
- it('can create an index', async () => {
- await pageObjects.indexManagement.clickCreateIndexButton();
- await pageObjects.indexManagement.setCreateIndexName(testIndexName);
- await pageObjects.indexManagement.setCreateIndexMode('Lookup');
- await pageObjects.indexManagement.clickCreateIndexSaveButton();
- await pageObjects.indexManagement.expectIndexToExist(testIndexName);
- });
-
- after(async () => {
- try {
- await es.indices.delete({ index: testIndexName });
- } catch (e) {
- log.debug(`Index cleanup failed for ${testIndexName}: ${e.message}`);
- }
- });
- });
-
- describe('Data streams', () => {
- it('renders the data streams tab', async () => {
- // Navigate to the data streams tab
- await pageObjects.indexManagement.changeTabs('data_streamsTab');
-
- await pageObjects.header.waitUntilLoadingHasFinished();
-
- // Verify url
- const url = await browser.getCurrentUrl();
- expect(url).to.contain(`/data_streams`);
-
- // Verify content
- await retry.waitFor('Wait until dataStream Table is visible.', async () => {
- return await testSubjects.isDisplayed('dataStreamTable');
- });
- });
- });
-
- describe('Index templates', () => {
- it('renders the index templates tab', async () => {
- // Navigate to the index templates tab
- await pageObjects.indexManagement.changeTabs('templatesTab');
-
- await pageObjects.header.waitUntilLoadingHasFinished();
-
- // Verify url
- const url = await browser.getCurrentUrl();
- expect(url).to.contain(`/templates`);
-
- // Verify content
- const templateList = await testSubjects.exists('templateList');
- expect(templateList).to.be(true);
- });
- });
-
- describe('Component templates', () => {
- it('renders the component templates tab', async () => {
- // Navigate to the component templates tab
- await pageObjects.indexManagement.changeTabs('component_templatesTab');
-
- await pageObjects.header.waitUntilLoadingHasFinished();
-
- // Verify url
- const url = await browser.getCurrentUrl();
- expect(url).to.contain(`/component_templates`);
-
- // Verify content. Component templates may have been created by other apps, e.g. Ingest Manager,
- // so we don't make any assertion about the presence or absence of component templates.
- const componentTemplateList = await testSubjects.exists('componentTemplateList');
- expect(componentTemplateList).to.be(true);
- });
- });
-
- describe('Enrich policies', () => {
- it('renders the enrich policies tab', async () => {
- // Navigate to the enrich policies tab
- await pageObjects.indexManagement.changeTabs('enrich_policiesTab');
-
- await pageObjects.header.waitUntilLoadingHasFinished();
-
- // Verify url
- const url = await browser.getCurrentUrl();
- expect(url).to.contain(`/enrich_policies`);
-
- // Verify content
- const enrichPoliciesList = await testSubjects.exists('sectionEmpty');
- expect(enrichPoliciesList).to.be(true);
- });
- });
- });
-};
diff --git a/x-pack/platform/test/functional/apps/index_management/index.ts b/x-pack/platform/test/functional/apps/index_management/index.ts
index 20303af196119..3da18702e6e16 100644
--- a/x-pack/platform/test/functional/apps/index_management/index.ts
+++ b/x-pack/platform/test/functional/apps/index_management/index.ts
@@ -10,9 +10,6 @@ import type { FtrProviderContext } from '../../ftr_provider_context';
export default ({ loadTestFile }: FtrProviderContext) => {
describe('Index Management app', function () {
loadTestFile(require.resolve('./feature_controls'));
- loadTestFile(require.resolve('./home_page'));
- loadTestFile(require.resolve('./index_template_wizard'));
- loadTestFile(require.resolve('./index_details_page'));
loadTestFile(require.resolve('./enrich_policies_tab'));
loadTestFile(require.resolve('./create_enrich_policy'));
loadTestFile(require.resolve('./data_streams_tab'));
diff --git a/x-pack/platform/test/functional/apps/index_management/index_details_page.ts b/x-pack/platform/test/functional/apps/index_management/index_details_page.ts
deleted file mode 100644
index fc35a1212c610..0000000000000
--- a/x-pack/platform/test/functional/apps/index_management/index_details_page.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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 { FtrProviderContext } from '../../ftr_provider_context';
-
-export default ({ getPageObjects, getService }: FtrProviderContext) => {
- const pageObjects = getPageObjects(['common', 'indexManagement', 'header']);
- const log = getService('log');
- const security = getService('security');
-
- describe('Index details page', function () {
- before(async () => {
- await security.testUser.setRoles(['index_management_user']);
- await pageObjects.common.navigateToApp('indexManagement');
- });
-
- it('Navigates to the index details page from the home page', async () => {
- await log.debug('Navigating to the index details page');
-
- // display hidden indices to have some rows in the indices table
- await pageObjects.indexManagement.toggleHiddenIndices();
- // click the first index in the table and wait for the index details page
- await pageObjects.indexManagement.indexDetailsPage.openIndexDetailsPage(0);
- await pageObjects.indexManagement.indexDetailsPage.expectIndexDetailsPageIsLoaded();
- });
- });
-};
diff --git a/x-pack/platform/test/functional/apps/index_management/index_template_wizard.ts b/x-pack/platform/test/functional/apps/index_management/index_template_wizard.ts
deleted file mode 100644
index 3d5d0b1e8e26f..0000000000000
--- a/x-pack/platform/test/functional/apps/index_management/index_template_wizard.ts
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * 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 expect from '@kbn/expect';
-import type { FtrProviderContext } from '../../ftr_provider_context';
-
-export default ({ getPageObjects, getService }: FtrProviderContext) => {
- const testSubjects = getService('testSubjects');
- const pageObjects = getPageObjects(['common', 'indexManagement', 'header']);
- const security = getService('security');
- const comboBox = getService('comboBox');
- const find = getService('find');
- const browser = getService('browser');
- const log = getService('log');
- const es = getService('es');
-
- describe('Index template wizard', function () {
- before(async () => {
- await security.testUser.setRoles(['index_management_user']);
- });
-
- describe('Create', () => {
- before(async () => {
- await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
- // Click Create Template button
- await testSubjects.click('createTemplateButton');
- });
-
- after(async () => {
- try {
- await es.indices.deleteIndexTemplate({ name: 'test-index-template' });
- await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
- } catch (e) {
- log.debug(`Template cleanup failed for test-index-template: ${e.message}`);
- }
- });
-
- it('should set the correct page title', async () => {
- const pageTitle = await testSubjects.exists('pageTitle');
- expect(pageTitle).to.be(true);
-
- const pageTitleText = await testSubjects.getVisibleText('pageTitle');
- expect(pageTitleText).to.be('Create template');
- });
-
- it('renders logistics (step 1)', async () => {
- // Verify step title
- const stepTitle = await testSubjects.getVisibleText('stepTitle');
- expect(stepTitle).to.be('Logistics');
-
- // Fill out required fields
- await testSubjects.setValue('nameField', 'test-index-template');
- await testSubjects.setValue('indexPatternsField', 'test-index-pattern');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
- });
-
- it('renders component templates (step 2)', async () => {
- // Verify empty prompt
- const emptyPrompt = await testSubjects.exists('emptyPrompt');
- expect(emptyPrompt).to.be(true);
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
- });
-
- it('renders index settings (step 3)', async () => {
- // Verify step title
- const stepTitle = await testSubjects.getVisibleText('stepTitle');
- expect(stepTitle).to.be('Index settings (optional)');
-
- // Verify that index mode callout is displayed
- const indexModeCalloutText = await testSubjects.getVisibleText('indexModeCallout');
- expect(indexModeCalloutText).to.be(
- 'The index.mode setting has been set to Standard within the Logistics step. Any changes to index.mode set on this page will be overwritten by the Logistics selection.'
- );
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
- });
-
- it('renders mappings (step 4)', async () => {
- // Verify step title
- const stepTitle = await testSubjects.getVisibleText('stepTitle');
- expect(stepTitle).to.be('Mappings (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
- });
-
- it('renders aliases (step 5)', async () => {
- // Verify step title
- const stepTitle = await testSubjects.getVisibleText('stepTitle');
- expect(stepTitle).to.be('Aliases (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
- });
-
- it('renders review template (step 6)', async () => {
- // Verify step title
- const stepTitle = await testSubjects.getVisibleText('stepTitle');
- expect(stepTitle).to.be("Review details for 'test-index-template'");
-
- // Verify that summary exists
- const summaryTabContent = await testSubjects.exists('summaryTabContent');
- expect(summaryTabContent).to.be(true);
-
- // Verify that index mode is set to "Standard"
- expect(await testSubjects.exists('indexModeTitle')).to.be(true);
- expect(await testSubjects.getVisibleText('indexModeValue')).to.be('Standard');
-
- // Click Create template
- await pageObjects.indexManagement.clickNextButton();
- });
- });
-
- // https://github.com/elastic/kibana/pull/195174
- describe('Preview template test', () => {
- before(async () => {
- await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
- });
-
- after(async () => {
- try {
- await es.indices.deleteIndexTemplate({ name: 'a-star' });
- } catch (e) {
- log.debug(`Template cleanup failed for a-star: ${e.message}`);
- }
- });
-
- it('can preview index template that matches a_fake_index_pattern_that_wont_match_any_indices', async () => {
- // Click Create Template button
- await testSubjects.click('createTemplateButton');
- const pageTitleText = await testSubjects.getVisibleText('pageTitle');
- expect(pageTitleText).to.be('Create template');
-
- const stepTitle1 = await testSubjects.getVisibleText('stepTitle');
- expect(stepTitle1).to.be('Logistics');
-
- // Fill out required fields
- await testSubjects.setValue('nameField', 'a-star');
- await testSubjects.setValue('indexPatternsField', 'a*');
- await testSubjects.setValue('priorityField', '1000');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify empty prompt
- const emptyPrompt = await testSubjects.exists('emptyPrompt');
- expect(emptyPrompt).to.be(true);
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- const stepTitle2 = await testSubjects.getVisibleText('stepTitle');
- expect(stepTitle2).to.be('Index settings (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- const stepTitle3 = await testSubjects.getVisibleText('stepTitle');
- expect(stepTitle3).to.be('Mappings (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- const stepTitle4 = await testSubjects.getVisibleText('stepTitle');
- expect(stepTitle4).to.be('Aliases (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- const stepTitle = await testSubjects.getVisibleText('stepTitle');
- expect(stepTitle).to.be("Review details for 'a-star'");
-
- // Verify that summary exists
- const summaryTabContent = await testSubjects.exists('summaryTabContent');
- expect(summaryTabContent).to.be(true);
-
- // Verify that index mode is set to "Standard"
- expect(await testSubjects.exists('indexModeTitle')).to.be(true);
- expect(await testSubjects.getVisibleText('indexModeValue')).to.be('Standard');
-
- // Click Create template
- await pageObjects.indexManagement.clickNextButton();
-
- // Click preview tab, we know its the last one
- const tabs = await testSubjects.findAll('tab');
- await tabs[tabs.length - 1].click();
- const templatePreview = await testSubjects.getVisibleText('simulateTemplatePreview');
- expect(templatePreview).to.not.contain('error');
-
- await testSubjects.click('closeDetailsButton');
- });
- });
- describe('Mappings step', () => {
- beforeEach(async () => {
- await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
-
- // Click Create Template button
- await testSubjects.click('createTemplateButton');
-
- // Fill out required fields
- await testSubjects.setValue('nameField', 'test-index-template');
- await testSubjects.setValue('indexPatternsField', 'test-index-pattern');
-
- // Go to Mappings step
- await testSubjects.click('formWizardStep-3');
- expect(await testSubjects.getVisibleText('stepTitle')).to.be('Mappings (optional)');
- });
-
- afterEach(async () => {
- try {
- await es.indices.deleteIndexTemplate({ name: 'test-index-template' });
- } catch (e) {
- log.debug(`Template cleanup failed in mappings test: ${e.message}`);
- }
- });
-
- // Test for catching the bug reported in https://github.com/elastic/kibana/issues/156202
- it("clearing up the Numeric subtype dropdown doesn't break the page", async () => {
- // Add a mapping field
- await testSubjects.click('addFieldButton');
-
- // Select Numeric type
- await testSubjects.click('fieldType');
- await comboBox.set('fieldType', 'Numeric');
-
- // Clear up subtype dropdown
- await testSubjects.click('fieldSubType');
- const input = await find.activeElement();
- await input.pressKeys(browser.keys.BACK_SPACE);
-
- // Verify that elements are still visible
- expect(await testSubjects.exists('addFieldButton')).to.be(true);
- expect(await testSubjects.exists('fieldType')).to.be(true);
- expect(await testSubjects.exists('fieldSubType')).to.be(true);
- expect(await testSubjects.exists('nextButton')).to.be(true);
- });
-
- // Test for catching the bug reported in https://github.com/elastic/kibana/issues/156202
- it("clearing up the Range subtype dropdown doesn't break the page", async () => {
- // Add a mapping field
- await testSubjects.click('addFieldButton');
-
- // Select Range type
- await testSubjects.click('fieldType');
- await comboBox.set('fieldType', 'Range');
-
- // Clear up subtype dropdown
- await testSubjects.click('fieldSubType');
- const input = await find.activeElement();
- await input.pressKeys(browser.keys.BACK_SPACE);
-
- // Verify that elements are still visible
- expect(await testSubjects.exists('addFieldButton')).to.be(true);
- expect(await testSubjects.exists('fieldType')).to.be(true);
- expect(await testSubjects.exists('fieldSubType')).to.be(true);
- expect(await testSubjects.exists('nextButton')).to.be(true);
- });
-
- it("advanced options tab doesn't add default values to request by default", async () => {
- await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
- await testSubjects.click('previewIndexTemplate');
- const templatePreview = await testSubjects.getVisibleText('simulateTemplatePreview');
-
- await log.debug(`Template preview text: ${templatePreview}`);
-
- // All advanced options should not be part of the request
- expect(templatePreview).to.not.contain('"dynamic"');
- expect(templatePreview).to.not.contain('"subobjects"');
- expect(templatePreview).to.not.contain('"dynamic_date_formats"');
- expect(templatePreview).to.not.contain('"date_detection"');
- expect(templatePreview).to.not.contain('"numeric_detection"');
- });
-
- it('advanced options tab adds the set values to the request', async () => {
- await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
-
- // Toggle the subobjects field to false
- await testSubjects.click('subobjectsToggle');
-
- await testSubjects.click('previewIndexTemplate');
- const templatePreview = await testSubjects.getVisibleText('simulateTemplatePreview');
-
- await log.debug(`Template preview text: ${templatePreview}`);
-
- // Only the subobjects option should be part of the request
- expect(templatePreview).to.contain('"subobjects": false');
- expect(templatePreview).to.not.contain('"dynamic"');
- expect(templatePreview).to.not.contain('"dynamic_date_formats"');
- expect(templatePreview).to.not.contain('"date_detection"');
- expect(templatePreview).to.not.contain('"numeric_detection"');
- });
- });
- });
-};
From 3b9ec723b40f2db1beaeebfad5e5a3a1b2e3f548 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 11:31:44 -0600
Subject: [PATCH 12/41] cleanup and refer to tabs by dataTestSubj instead of
position
---
.../template_details_content.tsx | 7 +++++-
.../page_objects/index_management_page.ts | 22 +------------------
.../ui/tests/index_template_wizard.spec.ts | 8 ++-----
3 files changed, 9 insertions(+), 28 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx b/x-pack/platform/plugins/shared/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx
index 138e846c2bae7..e1376cb50c2fc 100644
--- a/x-pack/platform/plugins/shared/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx
+++ b/x-pack/platform/plugins/shared/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx
@@ -55,30 +55,35 @@ const TABS = [
name: i18n.translate('xpack.idxMgmt.templateDetails.summaryTabTitle', {
defaultMessage: 'Summary',
}),
+ dataTestSubj: 'summaryTab',
},
{
id: SETTINGS_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.settingsTabTitle', {
defaultMessage: 'Settings',
}),
+ dataTestSubj: 'settingsTab',
},
{
id: MAPPINGS_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.mappingsTabTitle', {
defaultMessage: 'Mappings',
}),
+ dataTestSubj: 'mappingsTab',
},
{
id: ALIASES_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.aliasesTabTitle', {
defaultMessage: 'Aliases',
}),
+ dataTestSubj: 'aliasesTab',
},
{
id: PREVIEW_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.previewTabTitle', {
defaultMessage: 'Preview',
}),
+ dataTestSubj: 'previewTab',
},
];
@@ -220,7 +225,7 @@ export const TemplateDetailsContent = ({
}}
isSelected={tab.id === activeTab}
key={tab.id}
- data-test-subj="tab"
+ data-test-subj={tab.dataTestSubj}
>
{tab.name}
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index 75bf4e83801d3..b93c9043d37a7 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -42,7 +42,6 @@ export class IndexManagement {
async setCreateIndexMode(value: string) {
const modeField = this.page.testSubj.locator('indexModeField');
await modeField.waitFor({ state: 'visible' });
- // await this.page.pause();
await modeField.click();
await this.page.testSubj.locator(`indexMode${value}Option`).click();
}
@@ -59,26 +58,7 @@ export class IndexManagement {
// Wait for the table to be visible
const table = this.page.locator('table');
await table.waitFor({ state: 'visible' });
-
- // Get all index name links
- const indexLinks = this.page.testSubj.locator('indexTableIndexNameLink');
- const count = await indexLinks.count();
-
- // Check if any of the links contain the index name
- let found = false;
- for (let i = 0; i < count; i++) {
- // todo
- // eslint-disable-next-line playwright/no-nth-methods
- const text = await indexLinks.nth(i).textContent();
- if (text === indexName) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- throw new Error(`Expected index "${indexName}" to exist in the table, but it was not found`);
- }
+ this.page.getByText(indexName);
}
async toggleHiddenIndices() {
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 2da19dc9d794c..164cd24ae9088 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -207,12 +207,8 @@ test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, ()
// Click Create template
await pageObjects.indexManagement.clickNextButton();
- // Click preview tab, we know its the last one
- const tabs = page.testSubj.locator('tab');
- const tabCount = await tabs.count();
- // todo
- // eslint-disable-next-line playwright/no-nth-methods
- await tabs.nth(tabCount - 1).click();
+ // Click preview tab
+ page.testSubj.locator('previewTab').click();
const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
expect(templatePreview).not.toContain('error');
From 6e7b8dce2c13e9db5f8dd4106fc186d7d7e9ae73 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 12:20:47 -0600
Subject: [PATCH 13/41] use custom role
---
.../index_management/test/scout/ui/tests/home_page.spec.ts | 4 +++-
.../test/scout/ui/tests/index_details_page.spec.ts | 3 ++-
.../test/scout/ui/tests/index_template_wizard.spec.ts | 3 ++-
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
index fe2c90cb23070..890e0556e6209 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
@@ -7,11 +7,13 @@
import { expect } from '@kbn/scout';
import { test } from '../fixtures';
+// import { CUSTOM_ROLES } from './custom_roles';
test.describe('Home page', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects }) => {
- // TODO: Create loginAsIndexManagementUser role
+ // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
await browserAuth.loginAsAdmin();
+
await pageObjects.indexManagement.goto();
});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
index f4d0a1b7805b1..e884c11586bda 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
@@ -7,10 +7,11 @@
import { expect } from '@kbn/scout';
import { test } from '../fixtures';
+// import { CUSTOM_ROLES } from './custom_roles';
test.describe('Index details page', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects }) => {
- // TODO: Create loginAsIndexManagementUser role
+ // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
await browserAuth.loginAsAdmin();
await pageObjects.indexManagement.goto();
});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 164cd24ae9088..5a0c5bde4f459 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -7,10 +7,11 @@
import { expect } from '@kbn/scout';
import { test } from '../fixtures';
+// import { CUSTOM_ROLES } from './custom_roles';
test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects, page }) => {
- // TODO: Create loginAsIndexManagementUser role
+ // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
await browserAuth.loginAsAdmin();
await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
// Click Create Template button
From fe5c01406ea8f12388ee65f224863ff68010299e Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 12:22:20 -0600
Subject: [PATCH 14/41] use custom role
---
.../test/scout/ui/tests/custom_roles.ts | 30 +++++++++++++++++++
.../ui/tests/index_template_wizard.spec.ts | 4 +--
2 files changed, 32 insertions(+), 2 deletions(-)
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
new file mode 100644
index 0000000000000..185059698a786
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
@@ -0,0 +1,30 @@
+/*
+ * 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 { KibanaRole } from '@kbn/scout';
+
+export const CUSTOM_ROLES: Record = {
+ indexManagement: {
+ elasticsearch: {
+ // would be nice if this wasn't needed
+ cluster: ['monitor'],
+ indices: [
+ {
+ names: ['*'],
+ privileges: ['all'],
+ },
+ ],
+ },
+ kibana: [
+ {
+ base: ['read'],
+ feature: {},
+ spaces: ['*'],
+ },
+ ],
+ },
+};
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 5a0c5bde4f459..05096f27de34c 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -147,7 +147,7 @@ test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects }) => {
- // TODO: Create loginAsIndexManagementUser role
+ // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
await browserAuth.loginAsAdmin();
await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
});
@@ -229,7 +229,7 @@ test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, ()
test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects, page }) => {
- // TODO: Create loginAsIndexManagementUser role
+ // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
await browserAuth.loginAsAdmin();
await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
From 6014af97f2f00ba7d72f85661288ce91bd5a1a32 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 12:23:57 -0600
Subject: [PATCH 15/41] remove todo
---
.../scout/ui/fixtures/page_objects/index_management_page.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index b93c9043d37a7..2f8e7ec8ebb9e 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -67,7 +67,7 @@ export class IndexManagement {
async openIndexDetailsPage(indexOfRow: number) {
const indexLinks = this.page.testSubj.locator('indexTableIndexNameLink');
- // todo
+ // this should be refactored to use data-test-subj on the table rows
// eslint-disable-next-line playwright/no-nth-methods
await indexLinks.nth(indexOfRow).click();
From e49993027261e10c22f9aa43d563648ca79dd4f3 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 13:11:13 -0600
Subject: [PATCH 16/41] await promise
---
.../test/scout/ui/tests/index_template_wizard.spec.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 05096f27de34c..8bc303dd25c7d 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -209,7 +209,7 @@ test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, ()
await pageObjects.indexManagement.clickNextButton();
// Click preview tab
- page.testSubj.locator('previewTab').click();
+ await page.testSubj.locator('previewTab').click();
const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
expect(templatePreview).not.toContain('error');
From 30f5383781e1ab99d37f88e2898d51322bff8f66 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 14:33:38 -0600
Subject: [PATCH 17/41] fix jest test
---
.../home/index_templates_tab.helpers.ts | 5 +++--
.../home/index_templates_tab.test.ts | 12 ++++++++++--
.../template_details/template_details_content.tsx | 10 +++++-----
3 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts
index 049015ea1fb57..abf985a3529e1 100644
--- a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts
+++ b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts
@@ -40,10 +40,11 @@ const createActions = (testBed: TestBed) => {
const selectDetailsTab = async (
tab: 'summary' | 'settings' | 'mappings' | 'aliases' | 'preview'
) => {
- const tabs = ['summary', 'settings', 'mappings', 'aliases', 'preview'];
+ // const tabs = ['summary', 'settings', 'mappings', 'aliases', 'preview'];
+ const tabTestDataSubj = `${tab}TabBtn` as TestSubjects;
await act(async () => {
- testBed.find('templateDetails.tab').at(tabs.indexOf(tab)).simulate('click');
+ testBed.find(tabTestDataSubj).simulate('click');
});
testBed.component.update();
};
diff --git a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.test.ts b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.test.ts
index 6647fea1cc4e2..2729b5b9f31c5 100644
--- a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.test.ts
+++ b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.test.ts
@@ -563,6 +563,7 @@ describe('Index Templates tab', () => {
expect(find('templateDetails.title').text().trim()).toEqual(name);
});
+ // todo
it('should have a close button and be able to close flyout', async () => {
const { actions, component, exists } = testBed;
@@ -624,6 +625,7 @@ describe('Index Templates tab', () => {
await actions.clickTemplateAt(0);
+ /*
expect(find('templateDetails.tab').length).toBe(5);
expect(find('templateDetails.tab').map((t) => t.text())).toEqual([
'Summary',
@@ -632,6 +634,13 @@ describe('Index Templates tab', () => {
'Aliases',
'Preview',
]);
+ */
+
+ expect(exists('summaryTabBtn')).toBe(true);
+ expect(exists('settingsTabBtn')).toBe(true);
+ expect(exists('mappingsTabBtn')).toBe(true);
+ expect(exists('aliasesTabBtn')).toBe(true);
+ expect(exists('previewTabBtn')).toBe(true);
// Summary tab should be initial active tab
expect(exists('summaryTab')).toBe(true);
@@ -671,7 +680,7 @@ describe('Index Templates tab', () => {
isLegacy: true,
});
- const { actions, find, exists } = testBed;
+ const { actions, exists } = testBed;
httpRequestsMockHelpers.setLoadTemplateResponse(
templates[0].name,
@@ -679,7 +688,6 @@ describe('Index Templates tab', () => {
);
await actions.clickTemplateAt(0);
- expect(find('templateDetails.tab').length).toBe(5);
expect(exists('summaryTab')).toBe(true);
// Navigate and verify callout message per tab
diff --git a/x-pack/platform/plugins/shared/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx b/x-pack/platform/plugins/shared/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx
index e1376cb50c2fc..01db4011555d2 100644
--- a/x-pack/platform/plugins/shared/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx
+++ b/x-pack/platform/plugins/shared/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx
@@ -55,35 +55,35 @@ const TABS = [
name: i18n.translate('xpack.idxMgmt.templateDetails.summaryTabTitle', {
defaultMessage: 'Summary',
}),
- dataTestSubj: 'summaryTab',
+ dataTestSubj: 'summaryTabBtn',
},
{
id: SETTINGS_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.settingsTabTitle', {
defaultMessage: 'Settings',
}),
- dataTestSubj: 'settingsTab',
+ dataTestSubj: 'settingsTabBtn',
},
{
id: MAPPINGS_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.mappingsTabTitle', {
defaultMessage: 'Mappings',
}),
- dataTestSubj: 'mappingsTab',
+ dataTestSubj: 'mappingsTabBtn',
},
{
id: ALIASES_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.aliasesTabTitle', {
defaultMessage: 'Aliases',
}),
- dataTestSubj: 'aliasesTab',
+ dataTestSubj: 'aliasesTabBtn',
},
{
id: PREVIEW_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.previewTabTitle', {
defaultMessage: 'Preview',
}),
- dataTestSubj: 'previewTab',
+ dataTestSubj: 'previewTabBtn',
},
];
From c43760d0bc7739901a1e64338a92629b7cd1e91d Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 14:47:29 -0600
Subject: [PATCH 18/41] type fix
---
.../client_integration/helpers/test_subjects.ts | 7 ++++++-
.../home/index_templates_tab.test.ts | 12 ------------
.../test/scout/ui/tests/home_page.spec.ts | 6 +++---
3 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/helpers/test_subjects.ts b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/helpers/test_subjects.ts
index 0862977d3bf2e..40f7bba2b4fb6 100644
--- a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/helpers/test_subjects.ts
+++ b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/helpers/test_subjects.ts
@@ -118,4 +118,9 @@ export type TestSubjects =
| 'noIndicesMessage'
| 'clearIndicesSearch'
| 'usingMaxRetention'
- | 'componentTemplatesLink';
+ | 'componentTemplatesLink'
+ | 'summaryTabBtn'
+ | 'settingsTabBtn'
+ | 'mappingsTabBtn'
+ | 'aliasesTabBtn'
+ | 'previewTabBtn';
diff --git a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.test.ts b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.test.ts
index 2729b5b9f31c5..34a56cffcb531 100644
--- a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.test.ts
+++ b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.test.ts
@@ -563,7 +563,6 @@ describe('Index Templates tab', () => {
expect(find('templateDetails.title').text().trim()).toEqual(name);
});
- // todo
it('should have a close button and be able to close flyout', async () => {
const { actions, component, exists } = testBed;
@@ -625,17 +624,6 @@ describe('Index Templates tab', () => {
await actions.clickTemplateAt(0);
- /*
- expect(find('templateDetails.tab').length).toBe(5);
- expect(find('templateDetails.tab').map((t) => t.text())).toEqual([
- 'Summary',
- 'Settings',
- 'Mappings',
- 'Aliases',
- 'Preview',
- ]);
- */
-
expect(exists('summaryTabBtn')).toBe(true);
expect(exists('settingsTabBtn')).toBe(true);
expect(exists('mappingsTabBtn')).toBe(true);
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
index 890e0556e6209..c5c9998527a3a 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
@@ -7,12 +7,12 @@
import { expect } from '@kbn/scout';
import { test } from '../fixtures';
-// import { CUSTOM_ROLES } from './custom_roles';
+import { CUSTOM_ROLES } from './custom_roles';
test.describe('Home page', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects }) => {
- // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
- await browserAuth.loginAsAdmin();
+ await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
+ // await browserAuth.loginAsAdmin();
await pageObjects.indexManagement.goto();
});
From 12b0f03012a7b42dc5925c614c0449c65574e45b Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 17:59:00 -0600
Subject: [PATCH 19/41] scout test fixes
---
.../test/scout/ui/fixtures/index.ts | 70 ++++++++++++++++++-
.../page_objects/index_management_page.ts | 6 +-
.../test/scout/ui/tests/custom_roles.ts | 2 +-
.../test/scout/ui/tests/home_page.spec.ts | 6 +-
.../ui/tests/index_template_wizard.spec.ts | 23 +++---
5 files changed, 88 insertions(+), 19 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
index 7f79274779652..77aa5168c5294 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
@@ -7,10 +7,30 @@
import { test as base } from '@kbn/scout';
import type { ScoutPage, ScoutTestFixtures, ScoutWorkerFixtures } from '@kbn/scout';
+import type { PageObjects } from '@kbn/scout';
+import { createLazyPageObject } from '@kbn/scout';
+import type { AbstractPageObject } from './page_objects/index_management_page';
+import { IndexManagement } from './page_objects/index_management_page';
-import type { IndexManagementPageObjects } from './page_objects';
-import { extendPageObjects } from './page_objects';
+// import type { IndexManagementPageObjects } from './page_objects';
+// import { extendPageObjects } from './page_objects';
+/*
+interface IndexManagementPO {
+ indexManagement: IndexManagement;
+}
+
+export type IndexManagementPageObjects = IndexManagementPO & PageObjects;
+
+export function extendPageObjects(
+ pageObjects: PageObjects,
+ page: ScoutPage
+): IndexManagementPageObjects {
+ return {
+ ...pageObjects,
+ indexManagement: createLazyPageObject(IndexManagement, page),
+ };
+}
export interface ConsoleTestFixtures extends ScoutTestFixtures {
pageObjects: IndexManagementPageObjects;
}
@@ -30,3 +50,49 @@ export const test = base.extend({
await use(extendedPageObjects);
},
});
+*/
+
+type PageObjectClass = new (page: ScoutPage) => AbstractPageObject;
+
+export const createTest = function >(
+ pageObjectClassMap: Record
+) {
+ type PageObjectsExtended = PageObjectsExtensions & PageObjects;
+ interface TestFixtures extends ScoutTestFixtures {
+ pageObjects: PageObjectsExtended;
+ }
+
+ function extendPOs(pageObjects: PageObjects, page: ScoutPage): PageObjectsExtended {
+ const initedLazyPageObjects = Object.keys(pageObjectClassMap).reduce<
+ Record
+ >((col, value) => {
+ col[value] = createLazyPageObject(pageObjectClassMap[value], page);
+ return col;
+ }, {});
+
+ return {
+ ...initedLazyPageObjects,
+ ...pageObjects,
+ } as PageObjectsExtended;
+ }
+
+ return base.extend({
+ pageObjects: async (
+ {
+ pageObjects,
+ page,
+ }: {
+ pageObjects: PageObjectsExtended;
+ page: ScoutPage;
+ },
+ use: (pageObjects: PageObjectsExtended) => Promise
+ ) => {
+ const extendedPageObjects = extendPOs(pageObjects, page);
+ await use(extendedPageObjects);
+ },
+ });
+};
+
+export const test = createTest<{ indexManagement: IndexManagement }>({
+ indexManagement: IndexManagement,
+});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index 2f8e7ec8ebb9e..fa18e18ef7f41 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -5,11 +5,15 @@
* 2.0.
*/
+/* eslint-disable max-classes-per-file */
+
import type { ScoutPage } from '@kbn/scout';
-export class IndexManagement {
+export class AbstractPageObject {
constructor(public readonly page: ScoutPage) {}
+}
+export class IndexManagement extends AbstractPageObject {
async goto() {
await this.page.gotoApp('management/data/index_management');
}
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
index 185059698a786..2ee06c7196760 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
@@ -11,7 +11,7 @@ export const CUSTOM_ROLES: Record = {
indexManagement: {
elasticsearch: {
// would be nice if this wasn't needed
- cluster: ['monitor'],
+ cluster: ['manage'],
indices: [
{
names: ['*'],
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
index c5c9998527a3a..890e0556e6209 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
@@ -7,12 +7,12 @@
import { expect } from '@kbn/scout';
import { test } from '../fixtures';
-import { CUSTOM_ROLES } from './custom_roles';
+// import { CUSTOM_ROLES } from './custom_roles';
test.describe('Home page', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects }) => {
- await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
- // await browserAuth.loginAsAdmin();
+ // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
+ await browserAuth.loginAsAdmin();
await pageObjects.indexManagement.goto();
});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 8bc303dd25c7d..5972f284e05da 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -152,11 +152,19 @@ test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, ()
await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
});
+ test.afterEach(async ({ esClient, log }) => {
+ try {
+ await esClient.indices.deleteIndexTemplate({ name: 'a-star' });
+ } catch (e) {
+ log.debug(
+ `Template cleanup failed for a-star: ${e instanceof Error ? e.message : String(e)}`
+ );
+ }
+ });
+
test('can preview index template that matches a_fake_index_pattern_that_wont_match_any_indices', async ({
page,
pageObjects,
- esClient,
- log,
}) => {
// Click Create Template button
await page.testSubj.locator('createTemplateButton').click();
@@ -209,21 +217,12 @@ test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, ()
await pageObjects.indexManagement.clickNextButton();
// Click preview tab
- await page.testSubj.locator('previewTab').click();
+ await page.testSubj.locator('previewTabBtn').click();
const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
expect(templatePreview).not.toContain('error');
await page.testSubj.locator('closeDetailsButton').click();
-
- // Cleanup
- try {
- await esClient.indices.deleteIndexTemplate({ name: 'a-star' });
- } catch (e) {
- log.debug(
- `Template cleanup failed for a-star: ${e instanceof Error ? e.message : String(e)}`
- );
- }
});
});
From e91f2c8a14ee3c533eaefb43415f8ce7658a69b1 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 20:03:59 -0600
Subject: [PATCH 20/41] type fix
---
.../index_management/test/scout/ui/fixtures/index.ts | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
index 77aa5168c5294..9472369f23d4f 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
@@ -58,9 +58,6 @@ export const createTest = function
) {
type PageObjectsExtended = PageObjectsExtensions & PageObjects;
- interface TestFixtures extends ScoutTestFixtures {
- pageObjects: PageObjectsExtended;
- }
function extendPOs(pageObjects: PageObjects, page: ScoutPage): PageObjectsExtended {
const initedLazyPageObjects = Object.keys(pageObjectClassMap).reduce<
@@ -76,7 +73,12 @@ export const createTest = function ({
+ return base.extend<
+ ScoutTestFixtures & {
+ pageObjects: PageObjectsExtended;
+ },
+ ScoutWorkerFixtures
+ >({
pageObjects: async (
{
pageObjects,
From d43f4d5ccce1498203c95999f4ac36f98f3a10db Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Fri, 14 Nov 2025 22:32:14 -0600
Subject: [PATCH 21/41] remove comments
---
.../home/index_templates_tab.helpers.ts | 1 -
.../test/scout/ui/fixtures/index.ts | 40 -------------------
2 files changed, 41 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts
index abf985a3529e1..dbdcbac4de945 100644
--- a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts
+++ b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts
@@ -40,7 +40,6 @@ const createActions = (testBed: TestBed) => {
const selectDetailsTab = async (
tab: 'summary' | 'settings' | 'mappings' | 'aliases' | 'preview'
) => {
- // const tabs = ['summary', 'settings', 'mappings', 'aliases', 'preview'];
const tabTestDataSubj = `${tab}TabBtn` as TestSubjects;
await act(async () => {
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
index 9472369f23d4f..3545563d298b9 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
@@ -12,46 +12,6 @@ import { createLazyPageObject } from '@kbn/scout';
import type { AbstractPageObject } from './page_objects/index_management_page';
import { IndexManagement } from './page_objects/index_management_page';
-// import type { IndexManagementPageObjects } from './page_objects';
-// import { extendPageObjects } from './page_objects';
-
-/*
-interface IndexManagementPO {
- indexManagement: IndexManagement;
-}
-
-export type IndexManagementPageObjects = IndexManagementPO & PageObjects;
-
-export function extendPageObjects(
- pageObjects: PageObjects,
- page: ScoutPage
-): IndexManagementPageObjects {
- return {
- ...pageObjects,
- indexManagement: createLazyPageObject(IndexManagement, page),
- };
-}
-export interface ConsoleTestFixtures extends ScoutTestFixtures {
- pageObjects: IndexManagementPageObjects;
-}
-
-export const test = base.extend({
- pageObjects: async (
- {
- pageObjects,
- page,
- }: {
- pageObjects: IndexManagementPageObjects;
- page: ScoutPage;
- },
- use: (pageObjects: IndexManagementPageObjects) => Promise
- ) => {
- const extendedPageObjects = extendPageObjects(pageObjects, page);
- await use(extendedPageObjects);
- },
-});
-*/
-
type PageObjectClass = new (page: ScoutPage) => AbstractPageObject;
export const createTest = function >(
From 3e325579c1916d4ab0d13c99c11549717fcfdfeb Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Sun, 16 Nov 2025 20:53:49 -0600
Subject: [PATCH 22/41] improve user privs
---
.../index_management/test/scout/ui/tests/custom_roles.ts | 4 ++--
.../index_management/test/scout/ui/tests/home_page.spec.ts | 2 +-
.../test/scout/ui/tests/index_details_page.spec.ts | 2 +-
.../test/scout/ui/tests/index_template_wizard.spec.ts | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
index 2ee06c7196760..b77fa5f82f7c7 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
@@ -8,10 +8,10 @@
import type { KibanaRole } from '@kbn/scout';
export const CUSTOM_ROLES: Record = {
- indexManagement: {
+ indexManagementUser: {
elasticsearch: {
// would be nice if this wasn't needed
- cluster: ['manage'],
+ cluster: ['monitor', 'manage_index_templates', 'manage_enrich'],
indices: [
{
names: ['*'],
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
index 890e0556e6209..a2c33cf8011b3 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
@@ -11,7 +11,7 @@ import { test } from '../fixtures';
test.describe('Home page', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects }) => {
- // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
+ // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagementUser);
await browserAuth.loginAsAdmin();
await pageObjects.indexManagement.goto();
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
index e884c11586bda..a290dce2587ca 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
@@ -11,7 +11,7 @@ import { test } from '../fixtures';
test.describe('Index details page', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects }) => {
- // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
+ // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagementUser);
await browserAuth.loginAsAdmin();
await pageObjects.indexManagement.goto();
});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 5972f284e05da..961f8d90887a7 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -11,7 +11,7 @@ import { test } from '../fixtures';
test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects, page }) => {
- // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
+ // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagementUser);
await browserAuth.loginAsAdmin();
await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
// Click Create Template button
From 61aed88cb9154540694e23b28cd90b4f19cf2b58 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Sun, 16 Nov 2025 22:16:10 -0600
Subject: [PATCH 23/41] move some logic to pageObject to be shared
---
.../ui/fixtures/page_objects/index_management_page.ts | 10 +++++++++-
.../test/scout/ui/tests/index_details_page.spec.ts | 11 ++---------
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index fa18e18ef7f41..3e87453c5425c 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -7,7 +7,7 @@
/* eslint-disable max-classes-per-file */
-import type { ScoutPage } from '@kbn/scout';
+import { type ScoutPage, expect } from '@kbn/scout';
export class AbstractPageObject {
constructor(public readonly page: ScoutPage) {}
@@ -119,4 +119,12 @@ export class IndexManagement extends AbstractPageObject {
};
await this.page.testSubj.locator(tabMap[tab]).click();
}
+
+ indexDetailsPage = {
+ expectIndexDetailsPageIsLoaded: async () => {
+ await expect(this.page.testSubj.locator('indexDetailsTab-overview')).toBeVisible();
+ await expect(this.page.testSubj.locator('indexDetailsContent')).toBeVisible();
+ await expect(this.page.testSubj.locator('indexDetailsBackToIndicesButton')).toBeVisible();
+ },
+ };
}
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
index a290dce2587ca..77ed553e53535 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
@@ -5,7 +5,6 @@
* 2.0.
*/
-import { expect } from '@kbn/scout';
import { test } from '../fixtures';
// import { CUSTOM_ROLES } from './custom_roles';
@@ -16,11 +15,7 @@ test.describe('Index details page', { tag: ['@ess'] }, () => {
await pageObjects.indexManagement.goto();
});
- test('Navigates to the index details page from the home page', async ({
- pageObjects,
- log,
- page,
- }) => {
+ test('Navigates to the index details page from the home page', async ({ pageObjects, log }) => {
await log.debug('Navigating to the index details page');
// Display hidden indices to have some rows in the indices table
@@ -30,8 +25,6 @@ test.describe('Index details page', { tag: ['@ess'] }, () => {
await pageObjects.indexManagement.openIndexDetailsPage(0);
// Verify index details page is loaded
- await expect(page.testSubj.locator('indexDetailsTab-overview')).toBeVisible();
- await expect(page.testSubj.locator('indexDetailsContent')).toBeVisible();
- await expect(page.testSubj.locator('indexDetailsBackToIndicesButton')).toBeVisible();
+ await pageObjects.indexManagement.indexDetailsPage.expectIndexDetailsPageIsLoaded();
});
});
From 77e24acc6149e58b692793846b8ba9574d7dba9b Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Sun, 16 Nov 2025 22:37:01 -0600
Subject: [PATCH 24/41] consolidate some logic into pageObject
---
.../page_objects/index_management_page.ts | 13 +++++++++
.../ui/tests/index_template_wizard.spec.ts | 28 ++++---------------
2 files changed, 19 insertions(+), 22 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index 3e87453c5425c..8e04742112bac 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -127,4 +127,17 @@ export class IndexManagement extends AbstractPageObject {
await expect(this.page.testSubj.locator('indexDetailsBackToIndicesButton')).toBeVisible();
},
};
+
+ indexTemplateWizard = {
+ completeStepOne: async () => {
+ await this.page.testSubj.locator('nameField').locator('input').fill('test-index-template');
+ await this.page.testSubj
+ .locator('indexPatternsField')
+ .locator('input')
+ .fill('test-index-pattern');
+
+ // Click Next button
+ await this.clickNextButton();
+ },
+ };
}
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 961f8d90887a7..07688bcc5c53a 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -38,20 +38,12 @@ test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
test('renders logistics (step 1)', async ({ page, pageObjects }) => {
// Verify step title
await expect(page.testSubj.locator('stepTitle')).toHaveText('Logistics');
-
- // Fill out required fields
- await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
});
test('renders component templates (step 2)', async ({ page, pageObjects }) => {
// Fill logistics step
- await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
- await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
// Verify empty prompt
await expect(page.testSubj.locator('emptyPrompt')).toBeVisible();
@@ -62,9 +54,7 @@ test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
test('renders index settings (step 3)', async ({ page, pageObjects }) => {
// Fill logistics step
- await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
- await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
// Skip component templates step
await pageObjects.indexManagement.clickNextButton();
@@ -83,9 +73,7 @@ test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
test('renders mappings (step 4)', async ({ page, pageObjects }) => {
// Fill logistics step
- await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
- await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
// Skip component templates and settings steps
await pageObjects.indexManagement.clickNextButton();
@@ -100,9 +88,7 @@ test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
test('renders aliases (step 5)', async ({ page, pageObjects }) => {
// Fill logistics step
- await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
- await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
// Skip component templates, settings, and mappings steps
await pageObjects.indexManagement.clickNextButton();
@@ -118,9 +104,7 @@ test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
test('renders review template (step 6)', async ({ page, pageObjects }) => {
// Fill logistics step
- await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
- await pageObjects.indexManagement.clickNextButton();
+ await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
// Skip all intermediate steps
await pageObjects.indexManagement.clickNextButton();
From 2256982f3eb47b953374a9c7c3e6826f2463dfe6 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Thu, 20 Nov 2025 00:47:47 -0600
Subject: [PATCH 25/41] better auth integration
---
.../test/scout/ui/fixtures/index.ts | 28 +++++++++++++++--
.../test/scout/ui/tests/custom_roles.ts | 30 -------------------
.../test/scout/ui/tests/home_page.spec.ts | 7 ++---
.../scout/ui/tests/index_details_page.spec.ts | 6 ++--
.../ui/tests/index_template_wizard.spec.ts | 6 ++--
5 files changed, 32 insertions(+), 45 deletions(-)
delete mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
index 3545563d298b9..1b7b0ab8e4348 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/index.ts
@@ -6,14 +6,24 @@
*/
import { test as base } from '@kbn/scout';
-import type { ScoutPage, ScoutTestFixtures, ScoutWorkerFixtures } from '@kbn/scout';
+import type {
+ ScoutPage,
+ ScoutTestFixtures,
+ ScoutWorkerFixtures,
+ BrowserAuthFixture,
+} from '@kbn/scout';
import type { PageObjects } from '@kbn/scout';
import { createLazyPageObject } from '@kbn/scout';
import type { AbstractPageObject } from './page_objects/index_management_page';
import { IndexManagement } from './page_objects/index_management_page';
+import { CUSTOM_ROLES } from './custom_roles';
type PageObjectClass = new (page: ScoutPage) => AbstractPageObject;
+export interface IndexManagementBrowserAuthFixture extends BrowserAuthFixture {
+ loginAsIndexManagementUser: () => Promise;
+}
+
export const createTest = function >(
pageObjectClassMap: Record
) {
@@ -37,7 +47,9 @@ export const createTest = function ({
pageObjects: async (
{
@@ -52,6 +64,18 @@ export const createTest = function Promise
+ ) => {
+ const loginAsIndexManagementUser = async () =>
+ browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagementUser);
+
+ await use({
+ ...browserAuth,
+ loginAsIndexManagementUser,
+ });
+ },
});
};
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
deleted file mode 100644
index b77fa5f82f7c7..0000000000000
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/custom_roles.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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 { KibanaRole } from '@kbn/scout';
-
-export const CUSTOM_ROLES: Record = {
- indexManagementUser: {
- elasticsearch: {
- // would be nice if this wasn't needed
- cluster: ['monitor', 'manage_index_templates', 'manage_enrich'],
- indices: [
- {
- names: ['*'],
- privileges: ['all'],
- },
- ],
- },
- kibana: [
- {
- base: ['read'],
- feature: {},
- spaces: ['*'],
- },
- ],
- },
-};
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
index a2c33cf8011b3..cd3c08f38baaa 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
@@ -7,13 +7,10 @@
import { expect } from '@kbn/scout';
import { test } from '../fixtures';
-// import { CUSTOM_ROLES } from './custom_roles';
test.describe('Home page', { tag: ['@ess'] }, () => {
- test.beforeEach(async ({ browserAuth, pageObjects }) => {
- // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagementUser);
- await browserAuth.loginAsAdmin();
-
+ test.beforeEach(async ({ pageObjects, browserAuth }) => {
+ await browserAuth.loginAsIndexManagementUser();
await pageObjects.indexManagement.goto();
});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
index 77ed553e53535..1ddd2dc68aadb 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_details_page.spec.ts
@@ -6,12 +6,10 @@
*/
import { test } from '../fixtures';
-// import { CUSTOM_ROLES } from './custom_roles';
test.describe('Index details page', { tag: ['@ess'] }, () => {
- test.beforeEach(async ({ browserAuth, pageObjects }) => {
- // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagementUser);
- await browserAuth.loginAsAdmin();
+ test.beforeEach(async ({ pageObjects, browserAuth }) => {
+ await browserAuth.loginAsIndexManagementUser();
await pageObjects.indexManagement.goto();
});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 07688bcc5c53a..654cf29d5d91c 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -7,12 +7,10 @@
import { expect } from '@kbn/scout';
import { test } from '../fixtures';
-// import { CUSTOM_ROLES } from './custom_roles';
test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
- test.beforeEach(async ({ browserAuth, pageObjects, page }) => {
- // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagementUser);
- await browserAuth.loginAsAdmin();
+ test.beforeEach(async ({ pageObjects, page, browserAuth }) => {
+ await browserAuth.loginAsIndexManagementUser();
await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
// Click Create Template button
await page.testSubj.locator('createTemplateButton').click();
From a4c85c0e00e6d38c9d70efd45b46248009bea268 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Thu, 20 Nov 2025 00:55:25 -0600
Subject: [PATCH 26/41] add custom role file
---
.../test/scout/ui/fixtures/custom_roles.ts | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/custom_roles.ts
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/custom_roles.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/custom_roles.ts
new file mode 100644
index 0000000000000..b77fa5f82f7c7
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/custom_roles.ts
@@ -0,0 +1,30 @@
+/*
+ * 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 { KibanaRole } from '@kbn/scout';
+
+export const CUSTOM_ROLES: Record = {
+ indexManagementUser: {
+ elasticsearch: {
+ // would be nice if this wasn't needed
+ cluster: ['monitor', 'manage_index_templates', 'manage_enrich'],
+ indices: [
+ {
+ names: ['*'],
+ privileges: ['all'],
+ },
+ ],
+ },
+ kibana: [
+ {
+ base: ['read'],
+ feature: {},
+ spaces: ['*'],
+ },
+ ],
+ },
+};
From 4599facf23803eaaca80ccfc74e6abe27f50e116 Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Tue, 25 Nov 2025 03:02:17 +0000
Subject: [PATCH 27/41] Changes from node scripts/regenerate_moon_projects.js
--update
---
x-pack/platform/packages/shared/kbn-evals/moon.yml | 1 +
.../packages/shared/onechat/kbn-evals-suite-onechat/moon.yml | 1 +
x-pack/platform/plugins/shared/index_management/moon.yml | 1 +
3 files changed, 3 insertions(+)
diff --git a/x-pack/platform/packages/shared/kbn-evals/moon.yml b/x-pack/platform/packages/shared/kbn-evals/moon.yml
index 446644cf07d57..4275a7a991462 100644
--- a/x-pack/platform/packages/shared/kbn-evals/moon.yml
+++ b/x-pack/platform/packages/shared/kbn-evals/moon.yml
@@ -33,6 +33,7 @@ dependsOn:
- '@kbn/std'
- '@kbn/test'
- '@kbn/inference-prompt-utils'
+ - '@kbn/tracing-utils'
tags:
- test-helper
- package
diff --git a/x-pack/platform/packages/shared/onechat/kbn-evals-suite-onechat/moon.yml b/x-pack/platform/packages/shared/onechat/kbn-evals-suite-onechat/moon.yml
index 8c7fabec4b6a9..349a6078823af 100644
--- a/x-pack/platform/packages/shared/onechat/kbn-evals-suite-onechat/moon.yml
+++ b/x-pack/platform/packages/shared/onechat/kbn-evals-suite-onechat/moon.yml
@@ -22,6 +22,7 @@ dependsOn:
- '@kbn/onechat-common'
- '@kbn/tooling-log'
- '@kbn/core'
+ - '@kbn/scout'
tags:
- functional-tests
- package
diff --git a/x-pack/platform/plugins/shared/index_management/moon.yml b/x-pack/platform/plugins/shared/index_management/moon.yml
index e95accdbd32cf..ea7967d15b106 100644
--- a/x-pack/platform/plugins/shared/index_management/moon.yml
+++ b/x-pack/platform/plugins/shared/index_management/moon.yml
@@ -72,6 +72,7 @@ dependsOn:
- '@kbn/upgrade-assistant-pkg-common'
- '@kbn/failure-store-modal'
- '@kbn/react-query'
+ - '@kbn/scout'
tags:
- plugin
- prod
From 92f6cbb833aad55dbc088f8871a53e1bf75fe4a0 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Mon, 24 Nov 2025 22:28:17 -0600
Subject: [PATCH 28/41] use correct user for tests
---
.../test/scout/ui/tests/index_template_wizard.spec.ts | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 654cf29d5d91c..0484b5b610a05 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -129,8 +129,7 @@ test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects }) => {
- // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
- await browserAuth.loginAsAdmin();
+ await browserAuth.loginAsIndexManagementUser();
await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
});
@@ -210,8 +209,7 @@ test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, ()
test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ browserAuth, pageObjects, page }) => {
- // await browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagement);
- await browserAuth.loginAsAdmin();
+ await browserAuth.loginAsIndexManagementUser();
await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
// Click Create Template button
From c75d6aa0f00a11e01d04ff45086bc973d6b61c71 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Tue, 25 Nov 2025 00:28:05 -0600
Subject: [PATCH 29/41] fix FTR tests
---
.../index_management/index_templates_tab/index_template_tab.ts | 3 +--
.../test_suites/management/index_management/index_templates.ts | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts b/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
index 3fa29ca06911c..c00e2d6852f51 100644
--- a/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
+++ b/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
@@ -140,8 +140,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
// Navigate to Mappings
await testSubjects.click('formWizardStep-3');
await pageObjects.header.waitUntilLoadingHasFinished();
- const mappingTabs = await testSubjects.findAll('formTab');
- await mappingTabs[3].click();
+ await testSubjects.click('fieldsTab');
// Modify timestamp format
await testSubjects.click('comboBoxClearButton');
diff --git a/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts b/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts
index 6dbc821d50f10..8a3daa144b9c3 100644
--- a/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts
+++ b/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts
@@ -176,8 +176,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
// Navigate to Mappings
await testSubjects.click('formWizardStep-3');
await pageObjects.header.waitUntilLoadingHasFinished();
- const mappingTabs = await testSubjects.findAll('formTab');
- await mappingTabs[3].click();
+ await testSubjects.click('fieldsTab');
// Modify timestamp format
await testSubjects.click('comboBoxClearButton');
From fbb31c422fad72f60ea0ee5df3cb9022b8e83475 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Wed, 26 Nov 2025 00:46:47 -0600
Subject: [PATCH 30/41] fix FTR, improve scout tests
---
.../page_objects/index_management_page.ts | 16 +--
.../test/scout/ui/tests/home_page.spec.ts | 23 ++--
.../ui/tests/index_template_wizard.spec.ts | 108 ----------------
.../index_template_wizard_mappings.spec.ts | 117 ++++++++++++++++++
.../index_templates_tab/index_template_tab.ts | 6 +-
.../index_management/index_templates.ts | 6 +-
6 files changed, 137 insertions(+), 139 deletions(-)
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index 8e04742112bac..b140735291aac 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -38,31 +38,23 @@ export class IndexManagement extends AbstractPageObject {
}
async setCreateIndexName(value: string) {
- const nameField = this.page.testSubj.locator('createIndexNameFieldText');
- await nameField.waitFor({ state: 'visible' });
- await nameField.fill(value);
+ await this.page.testSubj.fill('createIndexNameFieldText', value);
}
async setCreateIndexMode(value: string) {
- const modeField = this.page.testSubj.locator('indexModeField');
- await modeField.waitFor({ state: 'visible' });
- await modeField.click();
+ await this.page.testSubj.click('indexModeField');
await this.page.testSubj.locator(`indexMode${value}Option`).click();
}
async clickCreateIndexSaveButton() {
const saveButton = this.page.testSubj.locator('createIndexSaveButton');
- await saveButton.waitFor({ state: 'visible' });
await saveButton.click();
// Wait for modal to close
await saveButton.waitFor({ state: 'hidden', timeout: 30000 });
}
- async expectIndexToExist(indexName: string) {
- // Wait for the table to be visible
- const table = this.page.locator('table');
- await table.waitFor({ state: 'visible' });
- this.page.getByText(indexName);
+ async indexLinkVisible(indexName: string) {
+ return this.page.getByRole('button').getByText(indexName).isVisible();
}
async toggleHiddenIndices() {
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
index cd3c08f38baaa..695a192612625 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
@@ -8,12 +8,22 @@
import { expect } from '@kbn/scout';
import { test } from '../fixtures';
+const testIndexName = `index-test-${Math.random()}`;
+
test.describe('Home page', { tag: ['@ess'] }, () => {
test.beforeEach(async ({ pageObjects, browserAuth }) => {
await browserAuth.loginAsIndexManagementUser();
await pageObjects.indexManagement.goto();
});
+ test.afterAll(async ({ esClient }) => {
+ try {
+ await esClient.indices.delete({ index: testIndexName });
+ } catch (e: any) {
+ log.debug(`Index cleanup failed for ${testIndexName}: ${e.message}`);
+ }
+ });
+
test('Loads the app and renders the indices tab by default', async ({
pageObjects,
log,
@@ -43,21 +53,12 @@ test.describe('Home page', { tag: ['@ess'] }, () => {
await expect(page.testSubj.locator('indexTable')).toBeVisible();
});
- test('Indices - can create an index', async ({ pageObjects, esClient, log }) => {
- const testIndexName = `index-test-${Math.random()}`;
-
+ test('Indices - can create an index', async ({ pageObjects }) => {
await pageObjects.indexManagement.clickCreateIndexButton();
await pageObjects.indexManagement.setCreateIndexName(testIndexName);
await pageObjects.indexManagement.setCreateIndexMode('Lookup');
await pageObjects.indexManagement.clickCreateIndexSaveButton();
- await pageObjects.indexManagement.expectIndexToExist(testIndexName);
-
- // Cleanup
- try {
- await esClient.indices.delete({ index: testIndexName });
- } catch (e: any) {
- log.debug(`Index cleanup failed for ${testIndexName}: ${e.message}`);
- }
+ expect(await pageObjects.indexManagement.indexLinkVisible(testIndexName)).toBe(true);
});
test('Data streams - renders the data streams tab', async ({ pageObjects, page }) => {
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 0484b5b610a05..210eed13ff61e 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -206,111 +206,3 @@ test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, ()
await page.testSubj.locator('closeDetailsButton').click();
});
});
-
-test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () => {
- test.beforeEach(async ({ browserAuth, pageObjects, page }) => {
- await browserAuth.loginAsIndexManagementUser();
- await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
-
- // Click Create Template button
- await page.testSubj.locator('createTemplateButton').click();
-
- // Fill out required fields
- await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
-
- // Go to Mappings step
- await page.testSubj.locator('formWizardStep-3').click();
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
- });
-
- test.afterEach(async ({ esClient, log }) => {
- try {
- await esClient.indices.deleteIndexTemplate({ name: 'test-index-template' });
- } catch (e) {
- log.debug(
- `Template cleanup failed in mappings test: ${e instanceof Error ? e.message : String(e)}`
- );
- }
- });
-
- test("clearing up the Numeric subtype dropdown doesn't break the page", async ({
- page,
- pageObjects,
- }) => {
- // Add a mapping field
- // Select Numeric type
- await pageObjects.indexManagement.setComboBox('fieldType', 'Numeric');
-
- // Clear up subtype dropdown
- await page.testSubj.locator('fieldSubType').click();
- await page.keyboard.press('Backspace');
-
- // Verify that elements are still visible
- await expect(page.testSubj.locator('addFieldButton')).toBeVisible();
- await expect(page.testSubj.locator('fieldType')).toBeVisible();
- await expect(page.testSubj.locator('fieldSubType')).toBeVisible();
- await expect(page.testSubj.locator('nextButton')).toBeVisible();
- });
-
- test("clearing up the Range subtype dropdown doesn't break the page", async ({
- page,
- pageObjects,
- }) => {
- // Add a mapping field
- // Select Range type
- await pageObjects.indexManagement.setComboBox('fieldType', 'Range');
-
- // Clear up subtype dropdown
- await page.testSubj.locator('fieldSubType').click();
- await page.keyboard.press('Backspace');
-
- // Verify that elements are still visible
- await expect(page.testSubj.locator('addFieldButton')).toBeVisible();
- await expect(page.testSubj.locator('fieldType')).toBeVisible();
- await expect(page.testSubj.locator('fieldSubType')).toBeVisible();
- await expect(page.testSubj.locator('nextButton')).toBeVisible();
- });
-
- test("advanced options tab doesn't add default values to request by default", async ({
- page,
- pageObjects,
- log,
- }) => {
- await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
- await page.testSubj.locator('previewIndexTemplate').click();
- const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
-
- log.debug(`Template preview text: ${templatePreview}`);
-
- // All advanced options should not be part of the request
- expect(templatePreview).not.toContain('"dynamic"');
- expect(templatePreview).not.toContain('"subobjects"');
- expect(templatePreview).not.toContain('"dynamic_date_formats"');
- expect(templatePreview).not.toContain('"date_detection"');
- expect(templatePreview).not.toContain('"numeric_detection"');
- });
-
- test('advanced options tab adds the set values to the request', async ({
- page,
- pageObjects,
- log,
- }) => {
- await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
-
- // Toggle the subobjects field to false
- await page.testSubj.locator('subobjectsToggle').click();
-
- await page.testSubj.locator('previewIndexTemplate').click();
- const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
-
- log.debug(`Template preview text: ${templatePreview}`);
-
- // Only the subobjects option should be part of the request
- expect(templatePreview).toContain('"subobjects": false');
- expect(templatePreview).not.toContain('"dynamic"');
- expect(templatePreview).not.toContain('"dynamic_date_formats"');
- expect(templatePreview).not.toContain('"date_detection"');
- expect(templatePreview).not.toContain('"numeric_detection"');
- });
-});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
new file mode 100644
index 0000000000000..b67d9efa86383
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
@@ -0,0 +1,117 @@
+/*
+ * 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 { expect } from '@kbn/scout';
+import { test } from '../fixtures';
+
+test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () => {
+ test.beforeEach(async ({ browserAuth, pageObjects, page }) => {
+ await browserAuth.loginAsIndexManagementUser();
+ await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
+
+ // Click Create Template button
+ await page.testSubj.locator('createTemplateButton').click();
+
+ // Fill out required fields
+ await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
+
+ // Go to Mappings step
+ await page.testSubj.locator('formWizardStep-3').click();
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
+ });
+
+ test.afterEach(async ({ esClient, log }) => {
+ try {
+ await esClient.indices.deleteIndexTemplate({ name: 'test-index-template' });
+ } catch (e) {
+ log.debug(
+ `Template cleanup failed in mappings test: ${e instanceof Error ? e.message : String(e)}`
+ );
+ }
+ });
+
+ test("clearing up the Numeric subtype dropdown doesn't break the page", async ({
+ page,
+ pageObjects,
+ }) => {
+ // Add a mapping field
+ // Select Numeric type
+ await pageObjects.indexManagement.setComboBox('fieldType', 'Numeric');
+
+ // Clear up subtype dropdown
+ await page.testSubj.locator('fieldSubType').click();
+ await page.keyboard.press('Backspace');
+
+ // Verify that elements are still visible
+ await expect(page.testSubj.locator('addFieldButton')).toBeVisible();
+ await expect(page.testSubj.locator('fieldType')).toBeVisible();
+ await expect(page.testSubj.locator('fieldSubType')).toBeVisible();
+ await expect(page.testSubj.locator('nextButton')).toBeVisible();
+ });
+
+ test("clearing up the Range subtype dropdown doesn't break the page", async ({
+ page,
+ pageObjects,
+ }) => {
+ // Add a mapping field
+ // Select Range type
+ await pageObjects.indexManagement.setComboBox('fieldType', 'Range');
+
+ // Clear up subtype dropdown
+ await page.testSubj.locator('fieldSubType').click();
+ await page.keyboard.press('Backspace');
+
+ // Verify that elements are still visible
+ await expect(page.testSubj.locator('addFieldButton')).toBeVisible();
+ await expect(page.testSubj.locator('fieldType')).toBeVisible();
+ await expect(page.testSubj.locator('fieldSubType')).toBeVisible();
+ await expect(page.testSubj.locator('nextButton')).toBeVisible();
+ });
+
+ test("advanced options tab doesn't add default values to request by default", async ({
+ page,
+ pageObjects,
+ log,
+ }) => {
+ await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
+ await page.testSubj.locator('previewIndexTemplate').click();
+ const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
+
+ log.debug(`Template preview text: ${templatePreview}`);
+
+ // All advanced options should not be part of the request
+ expect(templatePreview).not.toContain('"dynamic"');
+ expect(templatePreview).not.toContain('"subobjects"');
+ expect(templatePreview).not.toContain('"dynamic_date_formats"');
+ expect(templatePreview).not.toContain('"date_detection"');
+ expect(templatePreview).not.toContain('"numeric_detection"');
+ });
+
+ test('advanced options tab adds the set values to the request', async ({
+ page,
+ pageObjects,
+ log,
+ }) => {
+ await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
+
+ // Toggle the subobjects field to false
+ await page.testSubj.locator('subobjectsToggle').click();
+
+ await page.testSubj.locator('previewIndexTemplate').click();
+ const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
+
+ log.debug(`Template preview text: ${templatePreview}`);
+
+ // Only the subobjects option should be part of the request
+ expect(templatePreview).toContain('"subobjects": false');
+ expect(templatePreview).not.toContain('"dynamic"');
+ expect(templatePreview).not.toContain('"dynamic_date_formats"');
+ expect(templatePreview).not.toContain('"date_detection"');
+ expect(templatePreview).not.toContain('"numeric_detection"');
+ });
+});
diff --git a/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts b/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
index c00e2d6852f51..3c941de2b4ded 100644
--- a/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
+++ b/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
@@ -158,10 +158,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await pageObjects.indexManagement.clickNextButton();
await pageObjects.header.waitUntilLoadingHasFinished();
- const flyoutTabs = await testSubjects.findAll('tab');
-
// Verify Index Settings
- await flyoutTabs[1].click();
+ await testSubjects.click('settingsTabBtn');
await pageObjects.header.waitUntilLoadingHasFinished();
expect(await testSubjects.exists('settingsTabContent')).to.be(true);
const settingsTabContent = await testSubjects.getVisibleText('settingsTabContent');
@@ -179,7 +177,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
// Verify Mappings
- await flyoutTabs[2].click();
+ await testSubjects.click('mappingsTabBtn');
await pageObjects.header.waitUntilLoadingHasFinished();
expect(await testSubjects.exists('mappingsTabContent')).to.be(true);
const mappingsTabContent = await testSubjects.getVisibleText('mappingsTabContent');
diff --git a/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts b/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts
index 8a3daa144b9c3..33abe6f2c145e 100644
--- a/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts
+++ b/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts
@@ -194,10 +194,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await pageObjects.indexManagement.clickNextButton();
await pageObjects.header.waitUntilLoadingHasFinished();
- const flyoutTabs = await testSubjects.findAll('tab');
-
// Verify Index Settings
- await flyoutTabs[1].click();
+ await testSubjects.click('settingsTabBtn');
await pageObjects.header.waitUntilLoadingHasFinished();
expect(await testSubjects.exists('settingsTabContent')).to.be(true);
const settingsTabContent = await testSubjects.getVisibleText('settingsTabContent');
@@ -215,7 +213,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
// Verify Mappings
- await flyoutTabs[2].click();
+ await testSubjects.click('mappingsTabBtn');
await pageObjects.header.waitUntilLoadingHasFinished();
expect(await testSubjects.exists('mappingsTabContent')).to.be(true);
const mappingsTabContent = await testSubjects.getVisibleText('mappingsTabContent');
From f0675461ab27f0c3da025f11c1c622bd3436580b Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Wed, 26 Nov 2025 01:16:14 -0600
Subject: [PATCH 31/41] type fix
---
.../index_management/test/scout/ui/tests/home_page.spec.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
index 695a192612625..769c87c68b47c 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
@@ -16,7 +16,7 @@ test.describe('Home page', { tag: ['@ess'] }, () => {
await pageObjects.indexManagement.goto();
});
- test.afterAll(async ({ esClient }) => {
+ test.afterAll(async ({ esClient, log }) => {
try {
await esClient.indices.delete({ index: testIndexName });
} catch (e: any) {
From 40a24de6f1961447c77284b0cb13abad52b91fdb Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Wed, 26 Nov 2025 01:28:34 -0600
Subject: [PATCH 32/41] scout test fixes
---
.../page_objects/index_management_page.ts | 1 -
.../ui/tests/index_template_wizard.spec.ts | 80 -----------------
.../index_template_wizard_preview.spec.ts | 89 +++++++++++++++++++
3 files changed, 89 insertions(+), 81 deletions(-)
create mode 100644 x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index b140735291aac..7ad538df25fb1 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -128,7 +128,6 @@ export class IndexManagement extends AbstractPageObject {
.locator('input')
.fill('test-index-pattern');
- // Click Next button
await this.clickNextButton();
},
};
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index 210eed13ff61e..b8a80504f2ba0 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -126,83 +126,3 @@ test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
await pageObjects.indexManagement.clickNextButton();
});
});
-
-test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, () => {
- test.beforeEach(async ({ browserAuth, pageObjects }) => {
- await browserAuth.loginAsIndexManagementUser();
- await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
- });
-
- test.afterEach(async ({ esClient, log }) => {
- try {
- await esClient.indices.deleteIndexTemplate({ name: 'a-star' });
- } catch (e) {
- log.debug(
- `Template cleanup failed for a-star: ${e instanceof Error ? e.message : String(e)}`
- );
- }
- });
-
- test('can preview index template that matches a_fake_index_pattern_that_wont_match_any_indices', async ({
- page,
- pageObjects,
- }) => {
- // Click Create Template button
- await page.testSubj.locator('createTemplateButton').click();
- await expect(page.testSubj.locator('pageTitle')).toHaveText('Create template');
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Logistics');
-
- // Fill out required fields
- await page.testSubj.locator('nameField').locator('input').fill('a-star');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('a*');
- await page.testSubj.locator('priorityField').locator('input').fill('1000');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify empty prompt
- await expect(page.testSubj.locator('emptyPrompt')).toBeVisible();
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Index settings (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Aliases (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText("Review details for 'a-star'");
-
- // Verify that summary exists
- await expect(page.testSubj.locator('summaryTabContent')).toBeVisible();
-
- // Verify that index mode is set to "Standard"
- await expect(page.testSubj.locator('indexModeTitle')).toBeVisible();
- await expect(page.testSubj.locator('indexModeValue')).toHaveText('Standard');
-
- // Click Create template
- await pageObjects.indexManagement.clickNextButton();
-
- // Click preview tab
- await page.testSubj.locator('previewTabBtn').click();
-
- const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
- expect(templatePreview).not.toContain('error');
-
- await page.testSubj.locator('closeDetailsButton').click();
- });
-});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts
new file mode 100644
index 0000000000000..2bc229a76cfd5
--- /dev/null
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts
@@ -0,0 +1,89 @@
+/*
+ * 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 { expect } from '@kbn/scout';
+import { test } from '../fixtures';
+
+test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, () => {
+ test.beforeEach(async ({ browserAuth, pageObjects }) => {
+ await browserAuth.loginAsIndexManagementUser();
+ await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
+ });
+
+ test.afterEach(async ({ esClient, log }) => {
+ try {
+ await esClient.indices.deleteIndexTemplate({ name: 'a-star' });
+ } catch (e) {
+ log.debug(
+ `Template cleanup failed for a-star: ${e instanceof Error ? e.message : String(e)}`
+ );
+ }
+ });
+
+ test('can preview index template that matches a_fake_index_pattern_that_wont_match_any_indices', async ({
+ page,
+ pageObjects,
+ }) => {
+ // Click Create Template button
+ await page.testSubj.locator('createTemplateButton').click();
+ await expect(page.testSubj.locator('pageTitle')).toHaveText('Create template');
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Logistics');
+
+ // Fill out required fields
+ await page.testSubj.locator('nameField').locator('input').fill('a-star');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('a*');
+ await page.testSubj.locator('priorityField').locator('input').fill('1000');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify empty prompt
+ await expect(page.testSubj.locator('emptyPrompt')).toBeVisible();
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Index settings (optional)');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Aliases (optional)');
+
+ // Click Next button
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Verify step title
+ await expect(page.testSubj.locator('stepTitle')).toHaveText("Review details for 'a-star'");
+
+ // Verify that summary exists
+ await expect(page.testSubj.locator('summaryTabContent')).toBeVisible();
+
+ // Verify that index mode is set to "Standard"
+ await expect(page.testSubj.locator('indexModeTitle')).toBeVisible();
+ await expect(page.testSubj.locator('indexModeValue')).toHaveText('Standard');
+
+ // Click Create template
+ await pageObjects.indexManagement.clickNextButton();
+
+ // Click preview tab
+ await page.testSubj.locator('previewTabBtn').click();
+
+ const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
+ expect(templatePreview).not.toContain('error');
+
+ await page.testSubj.locator('closeDetailsButton').click();
+ });
+});
From 0ec2588d49c7c4a5e08f4d4a66b007e357a6d1a0 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Wed, 26 Nov 2025 13:52:43 -0600
Subject: [PATCH 33/41] fix scout test
---
.../ui/fixtures/page_objects/index_management_page.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index 7ad538df25fb1..31d23428c6171 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -54,7 +54,9 @@ export class IndexManagement extends AbstractPageObject {
}
async indexLinkVisible(indexName: string) {
- return this.page.getByRole('button').getByText(indexName).isVisible();
+ const indexButton = this.page.getByRole('button').getByText(indexName);
+ await indexButton.waitFor({ state: 'visible', timeout: 30000 }); // necessary since this can be slow in CI
+ return indexButton.isVisible();
}
async toggleHiddenIndices() {
@@ -98,9 +100,7 @@ export class IndexManagement extends AbstractPageObject {
await input.fill(value);
// Wait for and click the option
- const option = this.page.locator(`[role="option"]`).filter({ hasText: value });
- await option.waitFor({ state: 'visible' });
- await option.click();
+ await this.page.locator(`[role="option"]`).filter({ hasText: value }).click();
}
async changeMappingsEditorTab(tab: 'fields' | 'advancedOptions' | 'templates') {
From ec76d4a6a3afb66c798d6aa4f22913f79fa6e697 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Wed, 26 Nov 2025 14:35:58 -0600
Subject: [PATCH 34/41] type fix, scout test fix
---
.../__jest__/client_integration/helpers/test_subjects.ts | 2 +-
.../test/scout/ui/tests/index_template_wizard_mappings.spec.ts | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/helpers/test_subjects.ts b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/helpers/test_subjects.ts
index 60edb5ba55a2a..fa2ab6e79bb11 100644
--- a/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/helpers/test_subjects.ts
+++ b/x-pack/platform/plugins/shared/index_management/__jest__/client_integration/helpers/test_subjects.ts
@@ -123,5 +123,5 @@ export type TestSubjects =
| 'settingsTabBtn'
| 'mappingsTabBtn'
| 'aliasesTabBtn'
- | 'previewTabBtn';
+ | 'previewTabBtn'
| 'configureFailureStoreButton';
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
index b67d9efa86383..b3d3cba8788cd 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
@@ -40,6 +40,7 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
pageObjects,
}) => {
// Add a mapping field
+ await page.testSubj.locator('addFieldButton').click();
// Select Numeric type
await pageObjects.indexManagement.setComboBox('fieldType', 'Numeric');
@@ -59,6 +60,7 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
pageObjects,
}) => {
// Add a mapping field
+ await page.testSubj.locator('addFieldButton').click();
// Select Range type
await pageObjects.indexManagement.setComboBox('fieldType', 'Range');
From cb982b538da07e268202765a1d64821b7d57e2b8 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Wed, 26 Nov 2025 16:25:40 -0600
Subject: [PATCH 35/41] fix add button ref
---
.../scout/ui/tests/index_template_wizard_mappings.spec.ts | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
index b3d3cba8788cd..baffeb22dbdb7 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
@@ -40,7 +40,8 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
pageObjects,
}) => {
// Add a mapping field
- await page.testSubj.locator('addFieldButton').click();
+ // await page.pause();
+ await page.testSubj.locator('addButton').click();
// Select Numeric type
await pageObjects.indexManagement.setComboBox('fieldType', 'Numeric');
@@ -60,7 +61,7 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
pageObjects,
}) => {
// Add a mapping field
- await page.testSubj.locator('addFieldButton').click();
+ await page.testSubj.locator('addButton').click();
// Select Range type
await pageObjects.indexManagement.setComboBox('fieldType', 'Range');
From eca0e255df849cb1998fe28b05b50825cceaf250 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Wed, 26 Nov 2025 20:56:45 -0600
Subject: [PATCH 36/41] fix functional test
---
.../index_management/index_templates_tab/index_template_tab.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts b/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
index 3c941de2b4ded..a6316ed206049 100644
--- a/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
+++ b/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
@@ -140,7 +140,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
// Navigate to Mappings
await testSubjects.click('formWizardStep-3');
await pageObjects.header.waitUntilLoadingHasFinished();
- await testSubjects.click('fieldsTab');
+ await testSubjects.click('advancedOptionsTab');
// Modify timestamp format
await testSubjects.click('comboBoxClearButton');
From adbf566fe7624cf1cf618d1e527d55444c7e7bda Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Thu, 27 Nov 2025 00:42:48 -0600
Subject: [PATCH 37/41] test fixes
---
.../index_management/index_templates_tab/index_template_tab.ts | 3 +--
.../test_suites/management/index_management/index_templates.ts | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts b/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
index a6316ed206049..4f9ac204dd370 100644
--- a/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
+++ b/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
@@ -194,8 +194,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
// Navigate to Mappings
await testSubjects.click('formWizardStep-3');
await pageObjects.header.waitUntilLoadingHasFinished();
- const mappingTabs = await testSubjects.findAll('formTab');
- await mappingTabs[3].click();
+ (await testSubjects.find('advancedOptionsTab')).click();
// Modify source
await testSubjects.click('sourceValueField');
diff --git a/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts b/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts
index 33abe6f2c145e..bba604253755e 100644
--- a/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts
+++ b/x-pack/platform/test/serverless/functional/test_suites/management/index_management/index_templates.ts
@@ -176,7 +176,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
// Navigate to Mappings
await testSubjects.click('formWizardStep-3');
await pageObjects.header.waitUntilLoadingHasFinished();
- await testSubjects.click('fieldsTab');
+ await testSubjects.click('advancedOptionsTab');
// Modify timestamp format
await testSubjects.click('comboBoxClearButton');
From c950dc4137f3b73f3ca282bd7813cbba0351b1af Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Thu, 27 Nov 2025 01:41:27 -0600
Subject: [PATCH 38/41] add missing await
---
.../index_management/index_templates_tab/index_template_tab.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts b/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
index 4f9ac204dd370..3bd4a7ec2da3f 100644
--- a/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
+++ b/x-pack/platform/test/functional/apps/index_management/index_templates_tab/index_template_tab.ts
@@ -194,7 +194,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
// Navigate to Mappings
await testSubjects.click('formWizardStep-3');
await pageObjects.header.waitUntilLoadingHasFinished();
- (await testSubjects.find('advancedOptionsTab')).click();
+ await (await testSubjects.find('advancedOptionsTab')).click();
// Modify source
await testSubjects.click('sourceValueField');
From 21af96e3c823ce440a5ce261dd27ff943f17a401 Mon Sep 17 00:00:00 2001
From: Karen Grigoryan
Date: Mon, 1 Dec 2025 17:48:30 +0100
Subject: [PATCH 39/41] fix: remove debug comment and clarify test behavior
- Removed commented-out page.pause() debug code
- Added clarifying comment explaining why addButton click was removed:
the Create Field form is already open by default when mappings are empty
---
.../scout/ui/tests/index_template_wizard_mappings.spec.ts | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
index baffeb22dbdb7..8f198e41bd6c4 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
@@ -39,9 +39,7 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
page,
pageObjects,
}) => {
- // Add a mapping field
- // await page.pause();
- await page.testSubj.locator('addButton').click();
+ // The Create Field form is already open by default when mappings are empty
// Select Numeric type
await pageObjects.indexManagement.setComboBox('fieldType', 'Numeric');
@@ -60,8 +58,7 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
page,
pageObjects,
}) => {
- // Add a mapping field
- await page.testSubj.locator('addButton').click();
+ // The Create Field form is already open by default when mappings are empty
// Select Range type
await pageObjects.indexManagement.setComboBox('fieldType', 'Range');
From e7e4ab0df5770800c190190ec435cd00b4d1051d Mon Sep 17 00:00:00 2001
From: Karen Grigoryan
Date: Tue, 2 Dec 2025 14:07:47 +0100
Subject: [PATCH 40/41] refactor: use test.step for wizard tests and
EuiFieldTextWrapper
- Refactor index_template_wizard.spec.ts to use test.step instead of
separate test blocks for better efficiency and failure reporting
- Refactor index_template_wizard_preview.spec.ts to use test.step
for improved readability
- Use EuiFieldTextWrapper in indexTemplateWizard.completeStepOne
---
.../page_objects/index_management_page.ts | 14 +-
.../ui/tests/index_template_wizard.spec.ts | 152 ++++++------------
.../index_template_wizard_preview.spec.ts | 113 ++++++-------
3 files changed, 106 insertions(+), 173 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index 31d23428c6171..c963ee486d4e7 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -7,7 +7,7 @@
/* eslint-disable max-classes-per-file */
-import { type ScoutPage, expect } from '@kbn/scout';
+import { type ScoutPage, expect, EuiFieldTextWrapper } from '@kbn/scout';
export class AbstractPageObject {
constructor(public readonly page: ScoutPage) {}
@@ -122,11 +122,13 @@ export class IndexManagement extends AbstractPageObject {
indexTemplateWizard = {
completeStepOne: async () => {
- await this.page.testSubj.locator('nameField').locator('input').fill('test-index-template');
- await this.page.testSubj
- .locator('indexPatternsField')
- .locator('input')
- .fill('test-index-pattern');
+ const nameField = new EuiFieldTextWrapper(this.page, { dataTestSubj: 'nameField' });
+ await nameField.fill('test-index-template');
+
+ const indexPatternsField = new EuiFieldTextWrapper(this.page, {
+ dataTestSubj: 'indexPatternsField',
+ });
+ await indexPatternsField.fill('test-index-pattern');
await this.clickNextButton();
},
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
index b8a80504f2ba0..8fed11f25349a 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard.spec.ts
@@ -9,13 +9,6 @@ import { expect } from '@kbn/scout';
import { test } from '../fixtures';
test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
- test.beforeEach(async ({ pageObjects, page, browserAuth }) => {
- await browserAuth.loginAsIndexManagementUser();
- await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
- // Click Create Template button
- await page.testSubj.locator('createTemplateButton').click();
- });
-
test.afterEach(async ({ esClient, log }) => {
try {
await esClient.indices.deleteIndexTemplate({ name: 'test-index-template' });
@@ -28,101 +21,56 @@ test.describe('Index template wizard - Create', { tag: ['@ess'] }, () => {
}
});
- test('should set the correct page title', async ({ page }) => {
- await expect(page.testSubj.locator('pageTitle')).toBeVisible();
- await expect(page.testSubj.locator('pageTitle')).toHaveText('Create template');
- });
-
- test('renders logistics (step 1)', async ({ page, pageObjects }) => {
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Logistics');
- await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
- });
-
- test('renders component templates (step 2)', async ({ page, pageObjects }) => {
- // Fill logistics step
- await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
-
- // Verify empty prompt
- await expect(page.testSubj.locator('emptyPrompt')).toBeVisible();
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
- });
-
- test('renders index settings (step 3)', async ({ page, pageObjects }) => {
- // Fill logistics step
- await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
-
- // Skip component templates step
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Index settings (optional)');
-
- // Verify that index mode callout is displayed
- await expect(page.testSubj.locator('indexModeCallout')).toHaveText(
- 'The index.mode setting has been set to Standard within the Logistics step. Any changes to index.mode set on this page will be overwritten by the Logistics selection.'
- );
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
- });
-
- test('renders mappings (step 4)', async ({ page, pageObjects }) => {
- // Fill logistics step
- await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
-
- // Skip component templates and settings steps
- await pageObjects.indexManagement.clickNextButton();
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
- });
-
- test('renders aliases (step 5)', async ({ page, pageObjects }) => {
- // Fill logistics step
- await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
-
- // Skip component templates, settings, and mappings steps
- await pageObjects.indexManagement.clickNextButton();
- await pageObjects.indexManagement.clickNextButton();
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Aliases (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
- });
-
- test('renders review template (step 6)', async ({ page, pageObjects }) => {
- // Fill logistics step
- await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
-
- // Skip all intermediate steps
- await pageObjects.indexManagement.clickNextButton();
- await pageObjects.indexManagement.clickNextButton();
- await pageObjects.indexManagement.clickNextButton();
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText(
- "Review details for 'test-index-template'"
- );
-
- // Verify that summary exists
- await expect(page.testSubj.locator('summaryTabContent')).toBeVisible();
-
- // Verify that index mode is set to "Standard"
- await expect(page.testSubj.locator('indexModeTitle')).toBeVisible();
- await expect(page.testSubj.locator('indexModeValue')).toHaveText('Standard');
+ test('can walk through all wizard steps and create a template', async ({
+ page,
+ pageObjects,
+ browserAuth,
+ }) => {
+ await browserAuth.loginAsIndexManagementUser();
+ await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
+ await page.testSubj.locator('createTemplateButton').click();
- // Click Create template
- await pageObjects.indexManagement.clickNextButton();
+ await test.step('verify page title', async () => {
+ await expect(page.testSubj.locator('pageTitle')).toBeVisible();
+ await expect(page.testSubj.locator('pageTitle')).toHaveText('Create template');
+ });
+
+ await test.step('1: Logistics', async () => {
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Logistics');
+ await pageObjects.indexManagement.indexTemplateWizard.completeStepOne();
+ });
+
+ await test.step('2: Component templates', async () => {
+ await expect(page.testSubj.locator('emptyPrompt')).toBeVisible();
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ await test.step('3: Index settings', async () => {
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Index settings (optional)');
+ await expect(page.testSubj.locator('indexModeCallout')).toHaveText(
+ 'The index.mode setting has been set to Standard within the Logistics step. Any changes to index.mode set on this page will be overwritten by the Logistics selection.'
+ );
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ await test.step('4: Mappings', async () => {
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ await test.step('5: Aliases', async () => {
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Aliases (optional)');
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ await test.step('6: Review and create template', async () => {
+ await expect(page.testSubj.locator('stepTitle')).toHaveText(
+ "Review details for 'test-index-template'"
+ );
+ await expect(page.testSubj.locator('summaryTabContent')).toBeVisible();
+ await expect(page.testSubj.locator('indexModeTitle')).toBeVisible();
+ await expect(page.testSubj.locator('indexModeValue')).toHaveText('Standard');
+ await pageObjects.indexManagement.clickNextButton();
+ });
});
});
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts
index 2bc229a76cfd5..abb428765bc31 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts
@@ -9,11 +9,6 @@ import { expect } from '@kbn/scout';
import { test } from '../fixtures';
test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, () => {
- test.beforeEach(async ({ browserAuth, pageObjects }) => {
- await browserAuth.loginAsIndexManagementUser();
- await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
- });
-
test.afterEach(async ({ esClient, log }) => {
try {
await esClient.indices.deleteIndexTemplate({ name: 'a-star' });
@@ -24,66 +19,54 @@ test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, ()
}
});
- test('can preview index template that matches a_fake_index_pattern_that_wont_match_any_indices', async ({
- page,
- pageObjects,
- }) => {
- // Click Create Template button
- await page.testSubj.locator('createTemplateButton').click();
- await expect(page.testSubj.locator('pageTitle')).toHaveText('Create template');
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Logistics');
-
- // Fill out required fields
- await page.testSubj.locator('nameField').locator('input').fill('a-star');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('a*');
- await page.testSubj.locator('priorityField').locator('input').fill('1000');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify empty prompt
- await expect(page.testSubj.locator('emptyPrompt')).toBeVisible();
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Index settings (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText('Aliases (optional)');
-
- // Click Next button
- await pageObjects.indexManagement.clickNextButton();
-
- // Verify step title
- await expect(page.testSubj.locator('stepTitle')).toHaveText("Review details for 'a-star'");
-
- // Verify that summary exists
- await expect(page.testSubj.locator('summaryTabContent')).toBeVisible();
-
- // Verify that index mode is set to "Standard"
- await expect(page.testSubj.locator('indexModeTitle')).toBeVisible();
- await expect(page.testSubj.locator('indexModeValue')).toHaveText('Standard');
-
- // Click Create template
- await pageObjects.indexManagement.clickNextButton();
-
- // Click preview tab
- await page.testSubj.locator('previewTabBtn').click();
-
- const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
- expect(templatePreview).not.toContain('error');
+ test('can create and preview an index template', async ({ page, pageObjects, browserAuth }) => {
+ await browserAuth.loginAsIndexManagementUser();
+ await pageObjects.indexManagement.navigateToIndexManagementTab('templates');
- await page.testSubj.locator('closeDetailsButton').click();
+ await test.step('open wizard and fill logistics', async () => {
+ await page.testSubj.locator('createTemplateButton').click();
+ await expect(page.testSubj.locator('pageTitle')).toHaveText('Create template');
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Logistics');
+
+ await page.testSubj.locator('nameField').locator('input').fill('a-star');
+ await page.testSubj.locator('indexPatternsField').locator('input').fill('a*');
+ await page.testSubj.locator('priorityField').locator('input').fill('1000');
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ await test.step('skip component templates', async () => {
+ await expect(page.testSubj.locator('emptyPrompt')).toBeVisible();
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ await test.step('skip index settings', async () => {
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Index settings (optional)');
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ await test.step('skip mappings', async () => {
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Mappings (optional)');
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ await test.step('skip aliases', async () => {
+ await expect(page.testSubj.locator('stepTitle')).toHaveText('Aliases (optional)');
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ await test.step('review and create template', async () => {
+ await expect(page.testSubj.locator('stepTitle')).toHaveText("Review details for 'a-star'");
+ await expect(page.testSubj.locator('summaryTabContent')).toBeVisible();
+ await expect(page.testSubj.locator('indexModeTitle')).toBeVisible();
+ await expect(page.testSubj.locator('indexModeValue')).toHaveText('Standard');
+ await pageObjects.indexManagement.clickNextButton();
+ });
+
+ await test.step('preview template and verify no errors', async () => {
+ await page.testSubj.locator('previewTabBtn').click();
+ const templatePreview = await page.testSubj.locator('simulateTemplatePreview').textContent();
+ expect(templatePreview).not.toContain('error');
+ await page.testSubj.locator('closeDetailsButton').click();
+ });
});
});
From 968d9f426f72f559ddffd55f6503498f881f7da7 Mon Sep 17 00:00:00 2001
From: Karen Grigoryan
Date: Tue, 2 Dec 2025 15:58:26 +0100
Subject: [PATCH 41/41] refactor: use web-first assertions and EUI wrappers per
best practices
- Replace waitFor({ state: 'hidden' }) with expect().toBeHidden()
- Replace waitFor({ state: 'visible' }) with expect().toBeVisible()
- Change indexLinkVisible to indexLink returning locator for caller assertions
- Update test to use web-first assertion for index visibility check
- Use EuiFieldTextWrapper for text input fields in mappings and preview tests
---
.../page_objects/index_management_page.ts | 25 +++++++++++++------
.../test/scout/ui/tests/home_page.spec.ts | 4 ++-
.../index_template_wizard_mappings.spec.ts | 12 ++++++---
.../index_template_wizard_preview.spec.ts | 13 +++++++---
4 files changed, 37 insertions(+), 17 deletions(-)
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
index c963ee486d4e7..689ee99c10a78 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/fixtures/page_objects/index_management_page.ts
@@ -49,14 +49,17 @@ export class IndexManagement extends AbstractPageObject {
async clickCreateIndexSaveButton() {
const saveButton = this.page.testSubj.locator('createIndexSaveButton');
await saveButton.click();
- // Wait for modal to close
- await saveButton.waitFor({ state: 'hidden', timeout: 30000 });
+ // Wait for modal to close using web-first assertion
+ await expect(saveButton).toBeHidden({ timeout: 30000 });
}
- async indexLinkVisible(indexName: string) {
- const indexButton = this.page.getByRole('button').getByText(indexName);
- await indexButton.waitFor({ state: 'visible', timeout: 30000 }); // necessary since this can be slow in CI
- return indexButton.isVisible();
+ /**
+ * Returns locator for index link - caller should use web-first assertions.
+ * Note: Consider using extended timeout as this can be slow in CI environments.
+ * Example: await expect(pageObjects.indexManagement.indexLink(name)).toBeVisible({ timeout: 30000 });
+ */
+ indexLink(indexName: string) {
+ return this.page.getByRole('button').getByText(indexName);
}
async toggleHiddenIndices() {
@@ -69,8 +72,8 @@ export class IndexManagement extends AbstractPageObject {
// eslint-disable-next-line playwright/no-nth-methods
await indexLinks.nth(indexOfRow).click();
- // Wait for index details page to load
- await this.page.testSubj.locator('indexDetailsHeader').waitFor({ state: 'visible' });
+ // Wait for index details page to load using web-first assertion
+ await expect(this.page.testSubj.locator('indexDetailsHeader')).toBeVisible();
}
async navigateToIndexManagementTab(
@@ -91,6 +94,12 @@ export class IndexManagement extends AbstractPageObject {
await this.page.testSubj.locator('nextButton').click();
}
+ /**
+ * Custom combobox interaction for non-clearable comboboxes.
+ * Note: Cannot use EuiComboBoxWrapper here because the fieldType combobox
+ * has isClearable={false} (in type_parameter.tsx), and EuiComboBoxWrapper.selectSingleOption()
+ * attempts to clear() first, which fails when trying to click the non-existent comboBoxClearButton.
+ */
async setComboBox(testSubject: string, value: string) {
const comboBox = this.page.testSubj.locator(testSubject);
await comboBox.click();
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
index 769c87c68b47c..49a02452ce3f4 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/home_page.spec.ts
@@ -58,7 +58,9 @@ test.describe('Home page', { tag: ['@ess'] }, () => {
await pageObjects.indexManagement.setCreateIndexName(testIndexName);
await pageObjects.indexManagement.setCreateIndexMode('Lookup');
await pageObjects.indexManagement.clickCreateIndexSaveButton();
- expect(await pageObjects.indexManagement.indexLinkVisible(testIndexName)).toBe(true);
+ await expect(pageObjects.indexManagement.indexLink(testIndexName)).toBeVisible({
+ timeout: 30000,
+ });
});
test('Data streams - renders the data streams tab', async ({ pageObjects, page }) => {
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
index 8f198e41bd6c4..150bda219b6a2 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_mappings.spec.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { expect } from '@kbn/scout';
+import { expect, EuiFieldTextWrapper } from '@kbn/scout';
import { test } from '../fixtures';
test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () => {
@@ -16,9 +16,13 @@ test.describe('Index template wizard - Mappings step', { tag: ['@ess'] }, () =>
// Click Create Template button
await page.testSubj.locator('createTemplateButton').click();
- // Fill out required fields
- await page.testSubj.locator('nameField').locator('input').fill('test-index-template');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('test-index-pattern');
+ // Fill out required fields using EUI wrapper
+ const nameField = new EuiFieldTextWrapper(page, { dataTestSubj: 'nameField' });
+ await nameField.fill('test-index-template');
+ const indexPatternsField = new EuiFieldTextWrapper(page, {
+ dataTestSubj: 'indexPatternsField',
+ });
+ await indexPatternsField.fill('test-index-pattern');
// Go to Mappings step
await page.testSubj.locator('formWizardStep-3').click();
diff --git a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts
index abb428765bc31..d484a3056cb44 100644
--- a/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts
+++ b/x-pack/platform/plugins/shared/index_management/test/scout/ui/tests/index_template_wizard_preview.spec.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { expect } from '@kbn/scout';
+import { expect, EuiFieldTextWrapper } from '@kbn/scout';
import { test } from '../fixtures';
test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, () => {
@@ -28,9 +28,14 @@ test.describe('Index template wizard - Preview template', { tag: ['@ess'] }, ()
await expect(page.testSubj.locator('pageTitle')).toHaveText('Create template');
await expect(page.testSubj.locator('stepTitle')).toHaveText('Logistics');
- await page.testSubj.locator('nameField').locator('input').fill('a-star');
- await page.testSubj.locator('indexPatternsField').locator('input').fill('a*');
- await page.testSubj.locator('priorityField').locator('input').fill('1000');
+ const nameField = new EuiFieldTextWrapper(page, { dataTestSubj: 'nameField' });
+ await nameField.fill('a-star');
+ const indexPatternsField = new EuiFieldTextWrapper(page, {
+ dataTestSubj: 'indexPatternsField',
+ });
+ await indexPatternsField.fill('a*');
+ const priorityField = new EuiFieldTextWrapper(page, { dataTestSubj: 'priorityField' });
+ await priorityField.fill('1000');
await pageObjects.indexManagement.clickNextButton();
});