Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
29857d9
[Lens] Init scout
mariairiartef Jan 20, 2026
b0d1874
[Lens] Add initial test fixtures and tests for Lens functionality
mariairiartef Jan 20, 2026
ff30b78
Add test dashboard
mariairiartef Jan 26, 2026
a0a41c3
Merge branch 'main' into lens/init-scout
mariairiartef Jan 26, 2026
9c505ea
Add dashboard app methods: switchToEditMode and openInLineEditor
mariairiartef Jan 26, 2026
ba56fa7
Changes from node scripts/lint_ts_projects --fix
kibanamachine Jan 26, 2026
d95df24
Fix eslint issue
mariairiartef Jan 26, 2026
a2fc983
Fix typo
mariairiartef Jan 27, 2026
e93e84f
Update readme file
mariairiartef Jan 27, 2026
8a414ac
Remove unnecessary wait for edit button visibility in DashboardApp
mariairiartef Jan 29, 2026
7cc9b0e
Move LensApp to share page objects folder
mariairiartef Jan 29, 2026
a9081a2
Update openInlineEditor method name
mariairiartef Jan 29, 2026
ff7897c
Skip Lens ES|QL test until issue 2740 is resolved
mariairiartef Jan 29, 2026
0988a18
Merge branch 'main' into lens/init-scout
mariairiartef Jan 29, 2026
5a78469
Fix typo
mariairiartef Feb 3, 2026
a74e3b4
Merge branch 'main' into lens/init-scout
mariairiartef Feb 3, 2026
6775615
Unskip test and set feature flag via core plugin api
mariairiartef Feb 4, 2026
c2b5f5d
Remove journey
mariairiartef Feb 4, 2026
309aec8
Merge branch 'main' into lens/init-scout
mariairiartef Feb 4, 2026
f53a308
Merge branch 'main' into lens/init-scout
mariairiartef Feb 4, 2026
c026ca7
Merge branch 'main' into lens/init-scout
mariairiartef Feb 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .buildkite/scout_ci_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ plugins:
- transform
- fleet
- entity_store
- lens
disabled:

packages:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,22 @@ export class DashboardApp {

throw new Error(`Timeout waiting for ${expectedCount} elements matching ${options.selector}`);
}

async switchToEditMode() {
const isInEditMode = await this.page.testSubj.isVisible('dashboardViewOnlyMode');
if (!isInEditMode) {
await this.page.testSubj.click('dashboardEditMode');
await this.page.testSubj.waitForSelector('embeddablePanelDragHandle', { state: 'visible' });
}
}

async openInlineEditor(id: string) {
// Hover over the panel to show action buttons
const embeddableSelector = `[data-test-embeddable-id="${id}"]`;
await this.page.locator(embeddableSelector).hover();

// Wait for the edit button to appear and click it
const editVisualizationConfigurationSelector = `[data-test-subj="hover-actions-${id}"] [data-test-subj="embeddablePanelAction-editPanel"]`;
await this.page.locator(editVisualizationConfigurationSelector).click();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { RenderablePage } from './renderable_page';
import { Toasts } from './toasts';
import { createLazyPageObject } from './utils';
import { Inspector } from './inspector';
import { LensApp } from './lens_app';

export interface PageObjectsFixtures {
page: ScoutPage;
Expand All @@ -37,6 +38,7 @@ export interface PageObjects {
collapsibleNav: CollapsibleNav;
toasts: Toasts;
inspector: Inspector;
lens: LensApp;
}

/**
Expand All @@ -56,6 +58,7 @@ export function createCorePageObjects(fixtures: PageObjectsFixtures): PageObject
collapsibleNav: createLazyPageObject(CollapsibleNav, fixtures.page, fixtures.config),
toasts: createLazyPageObject(Toasts, fixtures.page),
inspector: createLazyPageObject(Inspector, fixtures.page),
lens: createLazyPageObject(LensApp, fixtures.page),
// Add new page objects here
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import type { ScoutPage } from '..';

export class LensApp {
Copy link
Copy Markdown
Member

@csr csr Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey! Just a heads up, my PR #249233 is also adding a Lens object. Expect to see some changes in this page object if my PR is merged after yours (I'm hoping that's the case so you don't have to go through merge conflict resolution).

constructor(private readonly page: ScoutPage) {}

Comment thread
dmlemeshko marked this conversation as resolved.
getConvertToEsqlButton() {
return this.page.getByRole('button', { name: 'Convert to ES|QL' });
}

getConvertToEsqModal() {
return this.page.getByTestId('lnsConvertToEsqlModal');
}

getConvertToEsqModalConfirmButton() {
return this.page.getByTestId('confirmModalConfirmButton');
}
}
2 changes: 2 additions & 0 deletions x-pack/platform/plugins/shared/lens/moon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ dependsOn:
- '@kbn/controls-constants'
- '@kbn/core-base-browser-mocks'
- '@kbn/react-kibana-context-env'
- '@kbn/scout'
tags:
- plugin
- prod
Expand All @@ -162,6 +163,7 @@ fileGroups:
- common/**/*
- public/**/*
- server/**/*
- test/scout/**/*
- '!target/**/*'
tasks:
jest:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ export const ConvertToEsqlModal: React.FunctionComponent<{
defaultMessage: 'Switch to query mode',
})}
confirmButtonDisabled={!isConfirmButtonEnabled}
data-test-subj="lnsConvertToEsqlModal"
>
<p>
{i18n.translate('xpack.lens.config.queryModeDescription', {
Expand Down
15 changes: 15 additions & 0 deletions x-pack/platform/plugins/shared/lens/test/scout/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Lens Scout tests

This directory contains Scout tests for the Lens plugin.

## Running the tests

### Run server
```
node scripts/scout.js start-server --stateful
```

### Run tests
```
npx playwright test --project local --grep @ess --config x-pack/platform/plugins/shared/lens/test/scout/ui/ --ui
```
Comment thread
mariairiartef marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"attributes": {
"allowHidden": false,
"fieldAttrs": "{}",
"fieldFormatMap": "{}",
"fields": "[]",
"name": "logstash-*",
"runtimeFieldMap": "{}",
"sourceFilters": "[]",
"timeFieldName": "@timestamp",
"title": "logstash-*"
},
"coreMigrationVersion": "8.8.0",
"created_at": "2026-01-23T15:58:55.175Z",
"created_by": "u_EWATCHX9oIEsmcXj8aA1FkcaY3DE-XEpsiGTjrR2PmM_0",
"id": "7d4752fe-05bd-4472-9bcb-fb347412f558",
"managed": false,
"references": [],
"type": "index-pattern",
"typeMigrationVersion": "8.0.0",
"updated_at": "2026-01-23T15:58:55.175Z",
"updated_by": "u_EWATCHX9oIEsmcXj8aA1FkcaY3DE-XEpsiGTjrR2PmM_0",
"version": "WzI4LDFd"
}

{
"accessControl": {
"accessMode": "default",
"owner": "u_EWATCHX9oIEsmcXj8aA1FkcaY3DE-XEpsiGTjrR2PmM_0"
},
"attributes": {
"controlGroupInput": {
"panelsJSON": "{}"
},
"description": "",
"kibanaSavedObjectMeta": {
"searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"}}"
},
"optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true,\"autoApplyFilters\":true,\"syncColors\":false,\"syncCursor\":true,\"syncTooltips\":false}",
"panelsJSON": "[{\"type\":\"lens\",\"embeddableConfig\":{\"enhancements\":{\"dynamicActions\":{\"events\":[]}},\"syncColors\":false,\"syncCursor\":true,\"syncTooltips\":false,\"filters\":[],\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"attributes\":{\"title\":\"\",\"visualizationType\":\"lnsMetric\",\"type\":\"lens\",\"references\":[{\"type\":\"index-pattern\",\"id\":\"7d4752fe-05bd-4472-9bcb-fb347412f558\",\"name\":\"indexpattern-datasource-layer-956270fb-67f2-4b48-a24d-333a205a1993\"}],\"state\":{\"visualization\":{\"layerId\":\"956270fb-67f2-4b48-a24d-333a205a1993\",\"layerType\":\"data\",\"metricAccessor\":\"940aaabc-f1f5-4a45-8d44-0dfeee27ee7a\",\"maxAccessor\":\"14999fb7-ede6-49d8-9ebd-eba41ae6e780\",\"showBar\":true,\"secondaryTrend\":{\"type\":\"none\"},\"secondaryLabelPosition\":\"before\"},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[],\"datasourceStates\":{\"formBased\":{\"layers\":{\"956270fb-67f2-4b48-a24d-333a205a1993\":{\"columns\":{\"940aaabc-f1f5-4a45-8d44-0dfeee27ee7a\":{\"label\":\"Average of bytes\",\"dataType\":\"number\",\"operationType\":\"average\",\"sourceField\":\"bytes\",\"isBucketed\":false,\"params\":{\"emptyAsNull\":true}},\"14999fb7-ede6-49d8-9ebd-eba41ae6e780\":{\"label\":\"Static value: 10000\",\"dataType\":\"number\",\"operationType\":\"static_value\",\"isBucketed\":false,\"params\":{\"value\":\"10000\",\"emptyAsNull\":true},\"references\":[]}},\"columnOrder\":[\"940aaabc-f1f5-4a45-8d44-0dfeee27ee7a\",\"14999fb7-ede6-49d8-9ebd-eba41ae6e780\"],\"incompleteColumns\":{},\"sampling\":1}}},\"indexpattern\":{\"layers\":{}},\"textBased\":{\"layers\":{}}},\"internalReferences\":[],\"adHocDataViews\":{}},\"version\":1}},\"panelIndex\":\"fb4626b8-d8ce-42d3-913a-081af94cfb51\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"fb4626b8-d8ce-42d3-913a-081af94cfb51\"}}]",
"timeRestore": false,
"title": "ES|QL Conversion Dashboard"
},
"coreMigrationVersion": "8.8.0",
"created_at": "2026-01-23T16:04:55.656Z",
"created_by": "u_EWATCHX9oIEsmcXj8aA1FkcaY3DE-XEpsiGTjrR2PmM_0",
"id": "3cda479c-8797-4492-99f4-2259e1377f85",
"managed": false,
"references": [
{
"id": "7d4752fe-05bd-4472-9bcb-fb347412f558",
"name": "fb4626b8-d8ce-42d3-913a-081af94cfb51:indexpattern-datasource-layer-956270fb-67f2-4b48-a24d-333a205a1993",
"type": "index-pattern"
}
],
"type": "dashboard",
"typeMigrationVersion": "10.3.0",
"updated_at": "2026-01-23T16:04:55.656Z",
"updated_by": "u_EWATCHX9oIEsmcXj8aA1FkcaY3DE-XEpsiGTjrR2PmM_0",
"version": "WzM0LDFd"
}

{
"excludedObjects": [],
"excludedObjectsCount": 0,
"exportedCount": 2,
"missingRefCount": 0,
"missingReferences": []
}
Original file line number Diff line number Diff line change
@@ -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',
});
Comment on lines +10 to +12
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Lens support Spaces, is it possible to consider running tests in space isolation and in parallel? It will be ~30-40% faster based on current metrics.

Original file line number Diff line number Diff line change
@@ -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 { expect } from '@kbn/scout';

import { test } from '@kbn/scout';

const ES_ARCHIVES = {
LOGSTASH: 'x-pack/platform/test/fixtures/es_archives/logstash_functional',
};

const DATA_VIEW_ID = {
LOGSTASH: 'logstash-*',
};

const LOGSTASH_IN_RANGE_DATES = {
from: 'Sep 19, 2015 @ 06:31:44.000',
to: 'Sep 23, 2015 @ 18:31:44.000',
};

const KBN_ARCHIVES = {
ESQL_CONVERSION_DASHBOARD:
'x-pack/platform/plugins/shared/lens/test/scout/ui/fixtures/esql_conversion_dashboard.json',
};
const ESQL_CONVERSION_DASHBOARD_TEST_ID = 'dashboardListingTitleLink-ES|QL-Conversion-Dashboard';
const METRIC_VISUALIZATION_ID = 'fb4626b8-d8ce-42d3-913a-081af94cfb51';

test.describe('Lens ES|QL', { tag: ['@ess'] }, () => {
test.beforeAll(async ({ esArchiver, kbnClient, uiSettings, apiServices }) => {
await apiServices.core.settings({
'feature_flags.overrides': {
'lens.enable_esql_conversion': 'true',
},
});
await esArchiver.loadIfNeeded(ES_ARCHIVES.LOGSTASH);
await kbnClient.importExport.load(KBN_ARCHIVES.ESQL_CONVERSION_DASHBOARD);
await uiSettings.set({
defaultIndex: DATA_VIEW_ID.LOGSTASH,
'dateFormat:tz': 'UTC',
'timepicker:timeDefaults': `{ "from": "${LOGSTASH_IN_RANGE_DATES.from}", "to": "${LOGSTASH_IN_RANGE_DATES.to}"}`,
});
});

test.afterAll(async ({ kbnClient, uiSettings }) => {
await uiSettings.unset('defaultIndex', 'dateFormat:tz', 'timepicker:timeDefaults');
await kbnClient.savedObjects.cleanStandardList();
});

test('should display ES|QL conversion modal', async ({ browserAuth, page, pageObjects }) => {
await browserAuth.loginAsPrivilegedUser();

const { dashboard, lens } = pageObjects;

// Navigate to the test dashboard
await dashboard.goto();
await page.getByTestId(ESQL_CONVERSION_DASHBOARD_TEST_ID).click();

// Verify dashboard loaded with the test visualization
await dashboard.waitForPanelsToLoad(1);

// Enter edit mode to access visualization actions
await dashboard.switchToEditMode();

await dashboard.openInlineEditor(METRIC_VISUALIZATION_ID);

await lens.getConvertToEsqlButton().click();

await expect(lens.getConvertToEsqModal()).toBeVisible();

await lens.getConvertToEsqModalConfirmButton().click();

await expect(lens.getConvertToEsqModal()).toBeHidden();

// TODO: Add conversion assertions once logic is implemented (https://github.com/elastic/kibana/pull/248078)
// For now, this test only verifies the UI flow up to modal interaction
});
});
10 changes: 9 additions & 1 deletion x-pack/platform/plugins/shared/lens/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
"compilerOptions": {
"outDir": "target/types"
},
"include": ["*.ts", "common/**/*", "public/**/*", "server/**/*", "../../../../../typings/**/*"],
"include": [
"*.ts",
"common/**/*",
"public/**/*",
"server/**/*",
"../../../../../typings/**/*",
"test/scout/**/*",
],
"kbn_references": [
"@kbn/spaces-plugin",
"@kbn/core",
Expand Down Expand Up @@ -137,6 +144,7 @@
"@kbn/controls-constants",
"@kbn/core-base-browser-mocks",
"@kbn/react-kibana-context-env",
"@kbn/scout",
],
"exclude": ["target/**/*"]
}
Loading