Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
c354e7e
home_page test port
mattkime Nov 13, 2025
36d966a
home_page test port
mattkime Nov 13, 2025
f3b3140
Changes from node scripts/lint_ts_projects --fix
kibanamachine Nov 13, 2025
e7f7760
fix lint issues
mattkime Nov 13, 2025
b32f61f
fix lint issues
mattkime Nov 13, 2025
57f2ef8
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine Nov 13, 2025
e320a3a
make data-test-subj's unique
mattkime Nov 13, 2025
7810316
Merge branch 'main' into index_mgmnt_playwright
mattkime Nov 14, 2025
738b1a8
Merge branch 'unique_create_index_btn_data_test_subj' into index_mgmn…
mattkime Nov 14, 2025
a5cea1b
Merge branch 'main' into index_mgmnt_playwright
mattkime Nov 14, 2025
277213c
functional test fixes
mattkime Nov 14, 2025
5784169
Merge branch 'index_mgmnt_playwright' of github.com:elastic/kibana in…
mattkime Nov 14, 2025
5c2671b
remove page.pause
mattkime Nov 14, 2025
e6538db
fix jest tests
mattkime Nov 14, 2025
ed6f186
remove FTR tests that were ported
mattkime Nov 14, 2025
3b9ec72
cleanup and refer to tabs by dataTestSubj instead of position
mattkime Nov 14, 2025
6e7b8dc
use custom role
mattkime Nov 14, 2025
fe5c014
use custom role
mattkime Nov 14, 2025
6014af9
remove todo
mattkime Nov 14, 2025
e499930
await promise
mattkime Nov 14, 2025
30f5383
fix jest test
mattkime Nov 14, 2025
c43760d
type fix
mattkime Nov 14, 2025
12b0f03
scout test fixes
mattkime Nov 14, 2025
e91f2c8
type fix
mattkime Nov 15, 2025
d43f4d5
remove comments
mattkime Nov 15, 2025
3e32557
improve user privs
mattkime Nov 17, 2025
61aed88
move some logic to pageObject to be shared
mattkime Nov 17, 2025
77e24ac
consolidate some logic into pageObject
mattkime Nov 17, 2025
2395289
Merge branch 'main' into index_mgmnt_playwright
mattkime Nov 18, 2025
2256982
better auth integration
mattkime Nov 20, 2025
a4c85c0
add custom role file
mattkime Nov 20, 2025
deda9bc
Merge branch 'main' into index_mgmnt_playwright
mattkime Nov 24, 2025
1c4b63f
Merge branch 'main' into index_mgmnt_playwright
mattkime Nov 25, 2025
4599fac
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine Nov 25, 2025
92f6cbb
use correct user for tests
mattkime Nov 25, 2025
a577c55
Merge branch 'index_mgmnt_playwright' of github.com:elastic/kibana in…
mattkime Nov 25, 2025
c75d6aa
fix FTR tests
mattkime Nov 25, 2025
fbb31c4
fix FTR, improve scout tests
mattkime Nov 26, 2025
f067546
type fix
mattkime Nov 26, 2025
40a24de
scout test fixes
mattkime Nov 26, 2025
e2a58f5
Merge branch 'main' into index_mgmnt_playwright
mattkime Nov 26, 2025
0ec2588
fix scout test
mattkime Nov 26, 2025
ef64718
Merge branch 'index_mgmnt_playwright' of github.com:elastic/kibana in…
mattkime Nov 26, 2025
ec76d4a
type fix, scout test fix
mattkime Nov 26, 2025
cb982b5
fix add button ref
mattkime Nov 26, 2025
eca0e25
fix functional test
mattkime Nov 27, 2025
adbf566
test fixes
mattkime Nov 27, 2025
c950dc4
add missing await
mattkime Nov 27, 2025
253975a
Merge branch 'main' into index_mgmnt_playwright
mattkime Nov 27, 2025
732732b
Merge branch 'main' into index_mgmnt_playwright
kapral18 Dec 1, 2025
21af96e
fix: remove debug comment and clarify test behavior
kapral18 Dec 1, 2025
e7e4ab0
refactor: use test.step for wizard tests and EuiFieldTextWrapper
kapral18 Dec 2, 2025
968d9f4
refactor: use web-first assertions and EUI wrappers per best practices
kapral18 Dec 2, 2025
4a3ab2b
Merge branch 'main' into index_mgmnt_playwright
kapral18 Dec 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .buildkite/scout_ci_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins:
- apm
- console
- discover_enhanced
- index_management
- maps
- observability
- observability_onboarding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,9 @@ export type TestSubjects =
| 'clearIndicesSearch'
| 'usingMaxRetention'
| 'componentTemplatesLink'
| 'summaryTabBtn'
| 'settingsTabBtn'
| 'mappingsTabBtn'
| 'aliasesTabBtn'
| 'previewTabBtn'
| 'configureFailureStoreButton';
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ const createActions = (testBed: TestBed<TestSubjects>) => {
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 () => {
testBed.find('templateDetails.tab').at(tabs.indexOf(tab)).simulate('click');
testBed.find(tabTestDataSubj).simulate('click');
});
testBed.component.update();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -624,14 +624,11 @@ 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);
expect(exists('aliasesTabBtn')).toBe(true);
expect(exists('previewTabBtn')).toBe(true);

// Summary tab should be initial active tab
expect(exists('summaryTab')).toBe(true);
Expand Down Expand Up @@ -671,15 +668,14 @@ describe('Index Templates tab', () => {
isLegacy: true,
});

const { actions, find, exists } = testBed;
const { actions, exists } = testBed;

httpRequestsMockHelpers.setLoadTemplateResponse(
templates[0].name,
templateWithNoOptionalFields
);
await actions.clickTemplateAt(0);

expect(find('templateDetails.tab').length).toBe(5);
expect(exists('summaryTab')).toBe(true);

// Navigate and verify callout message per tab
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,21 +390,14 @@ describe('<TemplateCreate />', () => {
});

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);
});
Expand All @@ -418,7 +411,10 @@ describe('<TemplateCreate />', () => {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,6 @@ export type TestSubjects =
| 'valueDataRetentionField'
| 'formWizardStep-5'
| 'lifecycleValue'
| 'mappingsEditor.formTab'
| 'mappingsEditor.advancedConfiguration.sizeEnabledToggle'
| 'previewIndexTemplate';
| 'previewIndexTemplate'
| 'advancedOptionsTab';
1 change: 1 addition & 0 deletions x-pack/platform/plugins/shared/index_management/moon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ dependsOn:
- '@kbn/upgrade-assistant-pkg-common'
- '@kbn/failure-store-modal'
- '@kbn/react-query'
- '@kbn/scout'
tags:
- plugin
- prod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,9 @@ const createActions = (testBed: TestBed<TestSubjects>) => {
// --- 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}"`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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',
]);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export const MappingsEditor = React.memo(
<EuiTab
onClick={() => changeTab('fields')}
isSelected={selectedTab === 'fields'}
data-test-subj="formTab"
data-test-subj="fieldsTab"
>
{i18n.translate('xpack.idxMgmt.mappingsEditor.fieldsTabLabel', {
defaultMessage: 'Mapped fields',
Expand All @@ -193,7 +193,7 @@ export const MappingsEditor = React.memo(
<EuiTab
onClick={() => changeTab('runtimeFields')}
isSelected={selectedTab === 'runtimeFields'}
data-test-subj="formTab"
data-test-subj="runtimeTab"
>
{i18n.translate('xpack.idxMgmt.mappingsEditor.runtimeFieldsTabLabel', {
defaultMessage: 'Runtime fields',
Expand All @@ -202,7 +202,7 @@ export const MappingsEditor = React.memo(
<EuiTab
onClick={() => changeTab('templates')}
isSelected={selectedTab === 'templates'}
data-test-subj="formTab"
data-test-subj="templatesTab"
>
{i18n.translate('xpack.idxMgmt.mappingsEditor.templatesTabLabel', {
defaultMessage: 'Dynamic templates',
Expand All @@ -211,7 +211,7 @@ export const MappingsEditor = React.memo(
<EuiTab
onClick={() => changeTab('advanced')}
isSelected={selectedTab === 'advanced'}
data-test-subj="formTab"
data-test-subj="advancedOptionsTab"
>
{i18n.translate('xpack.idxMgmt.mappingsEditor.advancedTabLabel', {
defaultMessage: 'Advanced options',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,13 @@ export const NoMatch = ({
/>
</p>
}
actions={<CreateIndexButton loadIndices={loadIndices} share={share} />}
actions={
<CreateIndexButton
loadIndices={loadIndices}
share={share}
dataTestSubj="createIndexButtonEmptyList"
/>
}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,35 @@ const TABS = [
name: i18n.translate('xpack.idxMgmt.templateDetails.summaryTabTitle', {
defaultMessage: 'Summary',
}),
dataTestSubj: 'summaryTabBtn',
},
{
id: SETTINGS_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.settingsTabTitle', {
defaultMessage: 'Settings',
}),
dataTestSubj: 'settingsTabBtn',
},
{
id: MAPPINGS_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.mappingsTabTitle', {
defaultMessage: 'Mappings',
}),
dataTestSubj: 'mappingsTabBtn',
},
{
id: ALIASES_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.aliasesTabTitle', {
defaultMessage: 'Aliases',
}),
dataTestSubj: 'aliasesTabBtn',
},
{
id: PREVIEW_TAB_ID,
name: i18n.translate('xpack.idxMgmt.templateDetails.previewTabTitle', {
defaultMessage: 'Preview',
}),
dataTestSubj: 'previewTabBtn',
},
];

Expand Down Expand Up @@ -217,7 +222,7 @@ export const TemplateDetailsContent = ({
}}
isSelected={tab.id === activeTab}
key={tab.id}
data-test-subj="tab"
data-test-subj={tab.dataTestSubj}
>
{tab.name}
</EuiTab>
Expand Down
Original file line number Diff line number Diff line change
@@ -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<string, KibanaRole> = {
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: ['*'],
},
],
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* 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,
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<void>;
}

export const createTest = function <PageObjectsExtensions = Record<string, AbstractPageObject>>(
pageObjectClassMap: Record<string, PageObjectClass>
) {
type PageObjectsExtended = PageObjectsExtensions & PageObjects;

function extendPOs(pageObjects: PageObjects, page: ScoutPage): PageObjectsExtended {
const initedLazyPageObjects = Object.keys(pageObjectClassMap).reduce<
Record<string, AbstractPageObject>
>((col, value) => {
col[value] = createLazyPageObject(pageObjectClassMap[value], page);
return col;
}, {});

return {
...initedLazyPageObjects,
...pageObjects,
} as PageObjectsExtended;
}

return base.extend<
ScoutTestFixtures & {
pageObjects: PageObjectsExtended;
},
ScoutWorkerFixtures & {
browserAuth: IndexManagementBrowserAuthFixture;
}
>({
pageObjects: async (
{
pageObjects,
page,
}: {
pageObjects: PageObjectsExtended;
page: ScoutPage;
},
use: (pageObjects: PageObjectsExtended) => Promise<void>
) => {
const extendedPageObjects = extendPOs(pageObjects, page);
await use(extendedPageObjects);
},
browserAuth: async (
{ browserAuth }: { browserAuth: BrowserAuthFixture },
use: (browserAuth: IndexManagementBrowserAuthFixture) => Promise<void>
) => {
const loginAsIndexManagementUser = async () =>
browserAuth.loginWithCustomRole(CUSTOM_ROLES.indexManagementUser);

await use({
...browserAuth,
loginAsIndexManagementUser,
});
},
});
};

export const test = createTest<{ indexManagement: IndexManagement }>({
indexManagement: IndexManagement,
});
Original file line number Diff line number Diff line change
@@ -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),
};
}
Loading