mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
chore(streams): add scout test for wired and classic stream (#220295)
This commit is contained in:
parent
a4940f5a78
commit
9650da839f
18 changed files with 501 additions and 4 deletions
|
@ -7,4 +7,5 @@ ui_tests:
|
|||
- observability_onboarding
|
||||
- painless_lab
|
||||
- security_solution
|
||||
- streams_app
|
||||
disabled:
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
|
||||
import { coreWorkerFixtures } from '../core_fixtures';
|
||||
import { FleetApiService, getFleetApiHelper } from './fleet';
|
||||
import { StreamsApiService, getStreamsApiService } from './streams';
|
||||
|
||||
export interface ApiServicesFixture {
|
||||
fleet: FleetApiService;
|
||||
streams: StreamsApiService;
|
||||
// add more services here
|
||||
}
|
||||
|
||||
|
@ -26,6 +28,7 @@ export const apiServicesFixture = coreWorkerFixtures.extend<
|
|||
async ({ kbnClient, log }, use) => {
|
||||
const services = {
|
||||
fleet: getFleetApiHelper(log, kbnClient),
|
||||
streams: getStreamsApiService({ kbnClient, log }),
|
||||
};
|
||||
|
||||
log.serviceLoaded('apiServices');
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { KbnClient, ScoutLogger, measurePerformanceAsync } from '../../../../../common';
|
||||
import { ScoutParallelWorkerFixtures } from '../../../parallel_run_fixtures';
|
||||
|
||||
export interface StreamsApiService {
|
||||
enable: () => Promise<void>;
|
||||
disable: () => Promise<void>;
|
||||
}
|
||||
|
||||
export const getStreamsApiService = ({
|
||||
kbnClient,
|
||||
log,
|
||||
scoutSpace,
|
||||
}: {
|
||||
kbnClient: KbnClient;
|
||||
log: ScoutLogger;
|
||||
scoutSpace?: ScoutParallelWorkerFixtures['scoutSpace'];
|
||||
}): StreamsApiService => {
|
||||
const basePath = scoutSpace?.id ? `/s/${scoutSpace?.id}` : '';
|
||||
|
||||
return {
|
||||
enable: async () => {
|
||||
await measurePerformanceAsync(log, 'streamsApi.enable', async () => {
|
||||
await kbnClient.request({
|
||||
method: 'POST',
|
||||
path: `${basePath}/api/streams/_enable`,
|
||||
});
|
||||
});
|
||||
},
|
||||
disable: async () => {
|
||||
await measurePerformanceAsync(log, 'streamsApi.disable', async () => {
|
||||
await kbnClient.request({
|
||||
method: 'POST',
|
||||
path: `${basePath}/api/streams/_disable`,
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
|
@ -170,6 +170,7 @@ export function RetentionMetadata({
|
|||
</EuiFlexGroup>
|
||||
}
|
||||
button={contextualMenu}
|
||||
dataTestSubj="streamsAppRetentionMetadataRetentionPeriod"
|
||||
/>
|
||||
<EuiHorizontalRule margin="s" />
|
||||
<MetadataRow
|
||||
|
@ -238,14 +239,21 @@ function MetadataRow({
|
|||
value,
|
||||
tip,
|
||||
button,
|
||||
dataTestSubj,
|
||||
}: {
|
||||
metadata: string;
|
||||
value: ReactNode;
|
||||
tip?: string;
|
||||
button?: ReactNode;
|
||||
dataTestSubj?: string;
|
||||
}) {
|
||||
return (
|
||||
<EuiFlexGroup alignItems="center" gutterSize="xl" responsive={false}>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
gutterSize="xl"
|
||||
responsive={false}
|
||||
data-test-subj={dataTestSubj}
|
||||
>
|
||||
<EuiFlexItem grow={1}>
|
||||
<EuiFlexGroup gutterSize="xs" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
|
|
|
@ -207,6 +207,7 @@ export function AddDashboardFlyout({
|
|||
loading={dashboardSuggestionsFetch.loading}
|
||||
selectedDashboards={selectedDashboards}
|
||||
setSelectedDashboards={setSelectedDashboards}
|
||||
dataTestSubj="streamsAppAddDashboardFlyoutDashboardsTable"
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlyoutBody>
|
||||
|
|
|
@ -27,6 +27,7 @@ export function DashboardsTable({
|
|||
setSelectedDashboards,
|
||||
loading,
|
||||
entityId,
|
||||
dataTestSubj,
|
||||
}: {
|
||||
entityId?: string;
|
||||
loading: boolean;
|
||||
|
@ -34,6 +35,7 @@ export function DashboardsTable({
|
|||
compact?: boolean;
|
||||
selectedDashboards?: SanitizedDashboardAsset[];
|
||||
setSelectedDashboards?: (dashboards: SanitizedDashboardAsset[]) => void;
|
||||
dataTestSubj?: string;
|
||||
}) {
|
||||
const {
|
||||
core: { application },
|
||||
|
@ -58,7 +60,7 @@ export function DashboardsTable({
|
|||
}),
|
||||
render: (_, { title, id }) => (
|
||||
<EuiLink
|
||||
data-test-subj="streamsAppColumnsLink"
|
||||
data-test-subj="streamsAppDashboardColumnsLink"
|
||||
onClick={() => {
|
||||
if (entityId) {
|
||||
telemetryClient.trackAssetClick({
|
||||
|
@ -117,6 +119,7 @@ export function DashboardsTable({
|
|||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem grow={false} />
|
||||
<EuiBasicTable
|
||||
data-test-subj={dataTestSubj}
|
||||
columns={columns}
|
||||
itemId="id"
|
||||
items={items}
|
||||
|
|
|
@ -210,6 +210,7 @@ export function StreamDetailDashboardsView({
|
|||
loading={dashboardsFetch.loading}
|
||||
selectedDashboards={selectedDashboards}
|
||||
setSelectedDashboards={canLinkAssets ? setSelectedDashboards : undefined}
|
||||
dataTestSubj="streamsAppStreamDetailDashboardsTable"
|
||||
/>
|
||||
{definition && isAddDashboardFlyoutOpen ? (
|
||||
<AddDashboardFlyout
|
||||
|
|
|
@ -26,6 +26,7 @@ export function StreamsEmptyPrompt() {
|
|||
|
||||
return (
|
||||
<EuiEmptyPrompt
|
||||
data-test-subj="streamsEmptyPrompt"
|
||||
icon={<AssetImage type="noResults" />}
|
||||
title={
|
||||
<h2>
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
"typings/**/*",
|
||||
"public/**/*.json",
|
||||
"server/**/*",
|
||||
".storybook/**/*"
|
||||
".storybook/**/*",
|
||||
"ui_tests/**/*"
|
||||
],
|
||||
"exclude": ["target/**/*", ".storybook/**/*.js"],
|
||||
"kbn_references": [
|
||||
|
@ -68,6 +69,7 @@
|
|||
"@kbn/ingest-pipelines-plugin",
|
||||
"@kbn/deeplinks-observability",
|
||||
"@kbn/content-packs-schema",
|
||||
"@kbn/charts-theme"
|
||||
"@kbn/charts-theme",
|
||||
"@kbn/scout"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
## How to run tests
|
||||
|
||||
First start the servers:
|
||||
|
||||
```bash
|
||||
// ESS
|
||||
node scripts/scout.js start-server --stateful
|
||||
|
||||
// Serverless
|
||||
node scripts/scout.js start-server --serverless=[es|oblt|security]
|
||||
```
|
||||
|
||||
Then you can run the tests in another terminal:
|
||||
|
||||
Some tests are designed to run sequentially:
|
||||
|
||||
```bash
|
||||
// ESS
|
||||
npx playwright test --config x-pack/platform/plugins/shared/streams_app/ui_tests/playwright.config.ts --project=local --grep @ess
|
||||
|
||||
// Serverless
|
||||
npx playwright test --config x-pack/platform/plugins/shared/streams_app/ui_tests/playwright.config.ts --project=local --grep @svlOblt
|
||||
```
|
||||
|
||||
Test results are available in `x-pack/platform/plugins/shared/streams_app/ui_tests/output`
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export const KBN_ARCHIVES = {
|
||||
DASHBOARD: 'x-pack/test/functional/fixtures/kbn_archiver/dashboard/simple.json',
|
||||
};
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 { ScoutPage, ScoutTestFixtures, ScoutWorkerFixtures, test as baseTest } from '@kbn/scout';
|
||||
import { StreamsPageObjects, extendPageObjects } from './page_objects';
|
||||
|
||||
export interface StreamsTestFixtures extends ScoutTestFixtures {
|
||||
pageObjects: StreamsPageObjects;
|
||||
}
|
||||
|
||||
export const test = baseTest.extend<StreamsTestFixtures, ScoutWorkerFixtures>({
|
||||
pageObjects: async (
|
||||
{
|
||||
pageObjects,
|
||||
page,
|
||||
}: {
|
||||
pageObjects: StreamsPageObjects;
|
||||
page: ScoutPage;
|
||||
},
|
||||
use: (pageObjects: StreamsPageObjects) => Promise<void>
|
||||
) => {
|
||||
const extendedPageObjects = extendPageObjects(pageObjects, page);
|
||||
await use(extendedPageObjects);
|
||||
},
|
||||
});
|
||||
|
||||
export * as testData from './constants';
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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 { PageObjects, ScoutPage, createLazyPageObject } from '@kbn/scout';
|
||||
import { StreamsApp } from './streams_app';
|
||||
|
||||
export interface StreamsPageObjects extends PageObjects {
|
||||
streams: StreamsApp;
|
||||
}
|
||||
|
||||
export function extendPageObjects(pageObjects: PageObjects, page: ScoutPage): StreamsPageObjects {
|
||||
return {
|
||||
...pageObjects,
|
||||
streams: createLazyPageObject(StreamsApp, page),
|
||||
};
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 { ScoutPage, expect } from '@kbn/scout';
|
||||
|
||||
export class StreamsApp {
|
||||
constructor(private readonly page: ScoutPage) {}
|
||||
|
||||
async goto() {
|
||||
await this.page.gotoApp('streams');
|
||||
await expect(this.page.getByText('StreamsTechnical Preview')).toBeVisible();
|
||||
}
|
||||
|
||||
async gotoStreamsFromBreadcrumb() {
|
||||
await this.page
|
||||
.getByTestId('breadcrumbs')
|
||||
.getByRole('link', { name: 'Streams', exact: true })
|
||||
.click();
|
||||
}
|
||||
|
||||
async gotoStream(stream: string) {
|
||||
const last = await this.page.getByTestId('breadcrumb last').textContent();
|
||||
if (last !== 'Streams') {
|
||||
await this.gotoStreamsFromBreadcrumb();
|
||||
}
|
||||
await this.page.getByRole('link', { name: stream, exact: true }).click();
|
||||
}
|
||||
|
||||
async gotoStreamDashboard(stream: string) {
|
||||
await this.gotoStream(stream);
|
||||
await this.page.getByRole('tab', { name: 'Dashboards' }).click();
|
||||
}
|
||||
|
||||
async gotoManageStream(stream: string) {
|
||||
this.gotoStream(stream);
|
||||
await this.page.getByRole('link', { name: 'Manage stream' }).click();
|
||||
}
|
||||
|
||||
async gotoCreateChildStream(parent: string) {
|
||||
await this.gotoManageStream(parent);
|
||||
await this.page.getByRole('button', { name: 'Create child stream' }).click();
|
||||
}
|
||||
|
||||
async gotoDataRetentionTab(stream: string) {
|
||||
await this.gotoManageStream(stream);
|
||||
await this.page.getByRole('tab', { name: 'Data retention' }).click();
|
||||
}
|
||||
|
||||
async gotoExtractFieldTab(stream: string) {
|
||||
await this.gotoManageStream(stream);
|
||||
await this.page.getByRole('tab', { name: 'Extract field' }).click();
|
||||
}
|
||||
|
||||
async gotoSchemaEditorTab(stream: string) {
|
||||
await this.gotoManageStream(stream);
|
||||
await this.page.getByRole('tab', { name: 'Schema editor' }).click();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default createPlaywrightConfig({
|
||||
testDir: './tests',
|
||||
});
|
|
@ -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 { testData, test } from '../fixtures';
|
||||
|
||||
const DATA_STREAM_NAME = 'my-data-stream';
|
||||
|
||||
test.describe('Classic Streams', { tag: ['@ess', '@svlOblt'] }, () => {
|
||||
test.beforeEach(async ({ kbnClient, esClient, browserAuth, pageObjects }) => {
|
||||
await kbnClient.importExport.load(testData.KBN_ARCHIVES.DASHBOARD);
|
||||
await esClient.indices.putIndexTemplate({
|
||||
name: 'my-index-template',
|
||||
index_patterns: [`${DATA_STREAM_NAME}*`],
|
||||
data_stream: {},
|
||||
priority: 500,
|
||||
template: {
|
||||
lifecycle: {
|
||||
data_retention: '7d',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await esClient.indices.createDataStream({
|
||||
name: DATA_STREAM_NAME,
|
||||
});
|
||||
|
||||
await esClient.index({
|
||||
index: DATA_STREAM_NAME,
|
||||
document: {
|
||||
'@timestamp': '2025-05-01T00:00:00.000Z',
|
||||
message: 'GET /search HTTP/1.1 200 1070000',
|
||||
'agent.name': 'nginx',
|
||||
},
|
||||
refresh: 'wait_for',
|
||||
});
|
||||
await browserAuth.loginAsAdmin();
|
||||
await pageObjects.streams.goto();
|
||||
});
|
||||
|
||||
test.afterAll(async ({ kbnClient, esClient, apiServices }) => {
|
||||
await esClient.indices.deleteDataStream({ name: DATA_STREAM_NAME });
|
||||
await esClient.indices.deleteIndexTemplate({
|
||||
name: 'my-index-template',
|
||||
});
|
||||
await kbnClient.savedObjects.cleanStandardList();
|
||||
});
|
||||
|
||||
test('full flow', async ({ page, esClient, pageObjects }) => {
|
||||
// Update data retention
|
||||
await pageObjects.streams.gotoDataRetentionTab(DATA_STREAM_NAME);
|
||||
|
||||
await page.getByRole('button', { name: 'Edit data retention' }).click();
|
||||
await page.getByRole('button', { name: 'Set specific retention days' }).click();
|
||||
await page.getByTestId('streamsAppDslModalDaysField').fill('30');
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await expect(
|
||||
page.getByTestId('streamsAppRetentionMetadataRetentionPeriod').getByText('30d')
|
||||
).toBeVisible();
|
||||
await page.getByTestId('toastCloseButton').click();
|
||||
|
||||
// Update field extraction
|
||||
await pageObjects.streams.gotoExtractFieldTab(DATA_STREAM_NAME);
|
||||
await page.getByText('Add a processor').click();
|
||||
|
||||
await page.locator('input[name="field"]').fill('message');
|
||||
await page
|
||||
.locator('input[name="patterns\\.0\\.value"]')
|
||||
.fill('%{WORD:method} %{URIPATH:request}');
|
||||
await page.getByRole('button', { name: 'Add processor' }).click();
|
||||
await page.getByRole('button', { name: 'Save changes' }).click();
|
||||
|
||||
await expect(page.getByText("Stream's processors updated")).toBeVisible();
|
||||
await page.getByTestId('toastCloseButton').click();
|
||||
|
||||
// Add dashboard
|
||||
await pageObjects.streams.gotoStreamDashboard(DATA_STREAM_NAME);
|
||||
await page.getByRole('button', { name: 'Add a dashboard' }).click();
|
||||
await expect(
|
||||
page
|
||||
.getByTestId('streamsAppAddDashboardFlyoutDashboardsTable')
|
||||
.getByRole('button', { name: 'Some Dashboard' })
|
||||
).toBeVisible();
|
||||
// eslint-disable-next-line playwright/no-nth-methods
|
||||
await page.getByRole('cell', { name: 'Select row' }).locator('div').first().click();
|
||||
await page.getByRole('button', { name: 'Add dashboard' }).click();
|
||||
await expect(
|
||||
page
|
||||
.getByTestId('streamsAppStreamDetailDashboardsTable')
|
||||
.getByTestId('streamsAppDashboardColumnsLink')
|
||||
).toHaveText('Some Dashboard');
|
||||
|
||||
// remove dashboard
|
||||
await page
|
||||
.getByTestId('streamsAppStreamDetailDashboardsTable')
|
||||
.getByRole('cell', { name: 'Select row' })
|
||||
.locator('div')
|
||||
// eslint-disable-next-line playwright/no-nth-methods
|
||||
.first()
|
||||
.click();
|
||||
|
||||
await page.getByRole('button', { name: 'Unlink selected' }).click();
|
||||
await expect(
|
||||
page.getByTestId('streamsAppStreamDetailDashboardsTable').getByText('No items found')
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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 { testData, test } from '../fixtures';
|
||||
|
||||
test.describe('Wired Streams', { tag: ['@ess', '@svlOblt'] }, () => {
|
||||
test.beforeEach(async ({ apiServices, kbnClient, browserAuth, pageObjects }) => {
|
||||
await kbnClient.importExport.load(testData.KBN_ARCHIVES.DASHBOARD);
|
||||
await apiServices.streams.enable();
|
||||
await browserAuth.loginAsAdmin();
|
||||
await pageObjects.streams.goto();
|
||||
});
|
||||
|
||||
test.afterAll(async ({ kbnClient, apiServices }) => {
|
||||
await apiServices.streams.disable();
|
||||
await kbnClient.savedObjects.cleanStandardList();
|
||||
});
|
||||
|
||||
test('full flow', async ({ page, esClient, pageObjects }) => {
|
||||
await pageObjects.streams.gotoCreateChildStream('logs');
|
||||
|
||||
await page.getByLabel('Stream name').fill('logs.nginx');
|
||||
await page.getByPlaceholder('Field').fill('agent.name');
|
||||
await page.getByPlaceholder('Value').fill('nginx');
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await expect(page.getByRole('link', { name: 'logs.nginx', exact: true })).toBeVisible();
|
||||
await page.getByTestId('toastCloseButton').click();
|
||||
|
||||
// Update "logs.nginx" data retention
|
||||
await pageObjects.streams.gotoDataRetentionTab('logs.nginx');
|
||||
await page.getByRole('button', { name: 'Edit data retention' }).click();
|
||||
await page.getByRole('button', { name: 'Set specific retention days' }).click();
|
||||
await page.getByTestId('streamsAppDslModalDaysField').fill('7');
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await expect(
|
||||
page.getByTestId('streamsAppRetentionMetadataRetentionPeriod').getByText('7d')
|
||||
).toBeVisible();
|
||||
await page.getByTestId('toastCloseButton').click();
|
||||
|
||||
// Update "logs.nginx" processing
|
||||
await esClient.index({
|
||||
index: 'logs',
|
||||
document: {
|
||||
'@timestamp': '2025-05-01T00:00:00.000Z',
|
||||
message: JSON.stringify({
|
||||
'log.level': 'info',
|
||||
'log.logger': 'nginx',
|
||||
message: 'GET /search HTTP/1.1 200 1070000',
|
||||
}),
|
||||
'agent.name': 'nginx',
|
||||
'other.field': 'important',
|
||||
},
|
||||
refresh: 'wait_for',
|
||||
});
|
||||
|
||||
await pageObjects.streams.gotoExtractFieldTab('logs.nginx');
|
||||
await page.getByText('Add a processor').click();
|
||||
|
||||
await page.locator('input[name="field"]').fill('message');
|
||||
await page
|
||||
.locator('input[name="patterns\\.0\\.value"]')
|
||||
.fill('%{WORD:method} %{URIPATH:request}');
|
||||
await page.getByRole('button', { name: 'Add processor' }).click();
|
||||
await page.getByRole('button', { name: 'Save changes' }).click();
|
||||
await expect(page.getByText("Stream's processors updated")).toBeVisible();
|
||||
await page.getByTestId('toastCloseButton').click();
|
||||
|
||||
// Update "logs.nginx" mapping
|
||||
await pageObjects.streams.gotoSchemaEditorTab('logs.nginx');
|
||||
|
||||
await page
|
||||
.getByRole('row', { name: 'agent.name ----- ----- logs.' })
|
||||
.getByLabel('Open actions menu')
|
||||
.click();
|
||||
await page
|
||||
.getByRole('row', { name: 'agent.name ----- ----- logs.' })
|
||||
.getByLabel('Open actions menu')
|
||||
.click();
|
||||
await page.getByRole('button', { name: 'Map field' }).click();
|
||||
await page.getByRole('combobox').selectOption('keyword');
|
||||
await page.getByRole('button', { name: 'Save changes' }).click();
|
||||
await page.getByRole('heading', { name: 'agent.name' }).waitFor({ state: 'hidden' });
|
||||
|
||||
await expect(page.getByText('Mapped', { exact: true })).toBeVisible();
|
||||
await page.getByTestId('toastCloseButton').click();
|
||||
|
||||
// Add dashboard
|
||||
await pageObjects.streams.gotoStreamDashboard('logs.nginx');
|
||||
await page.getByRole('button', { name: 'Add a dashboard' }).click();
|
||||
await expect(
|
||||
page
|
||||
.getByTestId('streamsAppAddDashboardFlyoutDashboardsTable')
|
||||
.getByRole('button', { name: 'Some Dashboard' })
|
||||
).toBeVisible();
|
||||
// eslint-disable-next-line playwright/no-nth-methods
|
||||
await page.getByRole('cell', { name: 'Select row' }).locator('div').first().click();
|
||||
await page.getByRole('button', { name: 'Add dashboard' }).click();
|
||||
await expect(
|
||||
page
|
||||
.getByTestId('streamsAppStreamDetailDashboardsTable')
|
||||
.getByTestId('streamsAppDashboardColumnsLink')
|
||||
).toHaveText('Some Dashboard');
|
||||
|
||||
// remove dashboard
|
||||
await page
|
||||
.getByTestId('streamsAppStreamDetailDashboardsTable')
|
||||
.getByRole('cell', { name: 'Select row' })
|
||||
.locator('div')
|
||||
// eslint-disable-next-line playwright/no-nth-methods
|
||||
.first()
|
||||
.click();
|
||||
|
||||
await page.getByRole('button', { name: 'Unlink selected' }).click();
|
||||
await expect(
|
||||
page.getByTestId('streamsAppStreamDetailDashboardsTable').getByText('No items found')
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"attributes": {
|
||||
"controlGroupInput": {
|
||||
"chainingSystem": "HIERARCHICAL",
|
||||
"controlStyle": "oneLine",
|
||||
"ignoreParentSettingsJSON": "{\"ignoreFilters\":false,\"ignoreQuery\":false,\"ignoreTimerange\":false,\"ignoreValidations\":false}",
|
||||
"panelsJSON": "{}",
|
||||
"showApplySelections": false
|
||||
},
|
||||
"description": "Some dashboard",
|
||||
"kibanaSavedObjectMeta": {
|
||||
"searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"kuery\"}}"
|
||||
},
|
||||
"optionsJSON": "{\"useMargins\":true,\"syncColors\":false,\"syncCursor\":true,\"syncTooltips\":false,\"hidePanelTitles\":false}",
|
||||
"panelsJSON": "[]",
|
||||
"timeRestore": false,
|
||||
"title": "Some Dashboard",
|
||||
"version": 3
|
||||
},
|
||||
"coreMigrationVersion": "8.8.0",
|
||||
"created_at": "2025-05-09T14:33:00.927Z",
|
||||
"created_by": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0",
|
||||
"id": "a1395240-bc20-4cc7-8559-349d049622d2",
|
||||
"managed": false,
|
||||
"references": [
|
||||
{
|
||||
"id": "64b8958c-e914-48ff-a31d-fc51227093b8",
|
||||
"name": "tag-ref-64b8958c-e914-48ff-a31d-fc51227093b8",
|
||||
"type": "tag"
|
||||
}
|
||||
],
|
||||
"type": "dashboard",
|
||||
"typeMigrationVersion": "10.2.0",
|
||||
"updated_at": "2025-05-09T14:33:00.927Z",
|
||||
"version": "WzE2LDFd"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue