From 1116c004c566e37dc4c623878dba1560100bd0c7 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Tue, 22 Apr 2025 13:01:31 +0200 Subject: [PATCH 01/17] Wip --- package-lock.json | 126 +++++++++--------- .../templates/common/playwright.config | 4 - packages/plugin-e2e/playwright.config.ts | 6 - .../src/models/pages/GrafanaPage.ts | 2 +- .../app/app-config/appConfig.spec.ts | 2 +- .../queryEditor.integration.spec.ts | 2 + 6 files changed, 67 insertions(+), 75 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3a2d82d21..396d7ff0f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6821,22 +6821,6 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/@playwright/test": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz", - "integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright": "1.52.0" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@pnpm/config.env-replace": { "version": "1.1.0", "license": "MIT", @@ -24284,53 +24268,6 @@ "node": ">=4" } }, - "node_modules/playwright": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz", - "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright-core": "1.52.0" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/playwright-core": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz", - "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/playwright/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "license": "MIT", @@ -31891,6 +31828,22 @@ "@playwright/test": "^1.52.0" } }, + "packages/plugin-e2e/node_modules/@playwright/test": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz", + "integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.52.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "packages/plugin-e2e/node_modules/dotenv": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", @@ -31904,6 +31857,53 @@ "url": "https://dotenvx.com" } }, + "packages/plugin-e2e/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "packages/plugin-e2e/node_modules/playwright": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz", + "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.52.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "packages/plugin-e2e/node_modules/playwright-core": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz", + "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "packages/plugin-meta-extractor": { "name": "@grafana/plugin-meta-extractor", "version": "0.5.3", diff --git a/packages/create-plugin/templates/common/playwright.config b/packages/create-plugin/templates/common/playwright.config index c84567bfdb..9c8c609f60 100644 --- a/packages/create-plugin/templates/common/playwright.config +++ b/packages/create-plugin/templates/common/playwright.config @@ -46,10 +46,6 @@ export default defineConfig({ use: { ...devices['Desktop Chrome'], storageState: 'playwright/.auth/admin.json', - launchOptions: { - args: ['--disable-features=PlzDedicatedWorker'], // because https://github.com/microsoft/playwright/pull/34400 - }, - channel: 'chrome', }, dependencies: ['auth'], }, diff --git a/packages/plugin-e2e/playwright.config.ts b/packages/plugin-e2e/playwright.config.ts index 4621f52924..3addcbbfea 100644 --- a/packages/plugin-e2e/playwright.config.ts +++ b/packages/plugin-e2e/playwright.config.ts @@ -87,9 +87,6 @@ export default defineConfig({ testDir: './tests/as-admin-user', use: { ...devices['Desktop Chrome'], - launchOptions: { - args: ['--disable-features=PlzDedicatedWorker'], // because https://github.com/microsoft/playwright/pull/34400 - }, storageState: 'playwright/.auth/admin.json', viewport: { width: 1920, @@ -105,9 +102,6 @@ export default defineConfig({ testDir: './tests/as-viewer-user', use: { ...devices['Desktop Chrome'], - launchOptions: { - args: ['--disable-features=PlzDedicatedWorker'], // because https://github.com/microsoft/playwright/pull/34400 - }, storageState: 'playwright/.auth/viewer.json', channel: 'chrome', }, diff --git a/packages/plugin-e2e/src/models/pages/GrafanaPage.ts b/packages/plugin-e2e/src/models/pages/GrafanaPage.ts index 7603e2a231..59ea2e0c1d 100644 --- a/packages/plugin-e2e/src/models/pages/GrafanaPage.ts +++ b/packages/plugin-e2e/src/models/pages/GrafanaPage.ts @@ -19,7 +19,7 @@ export abstract class GrafanaPage { url += `?${queryParams.toString()}`; } await this.ctx.page.goto(url, { - waitUntil: 'networkidle', + waitUntil: 'load', ...this.pageArgs, ...options, }); diff --git a/packages/plugin-e2e/tests/as-admin-user/app/app-config/appConfig.spec.ts b/packages/plugin-e2e/tests/as-admin-user/app/app-config/appConfig.spec.ts index c8c069271a..e176a8b882 100644 --- a/packages/plugin-e2e/tests/as-admin-user/app/app-config/appConfig.spec.ts +++ b/packages/plugin-e2e/tests/as-admin-user/app/app-config/appConfig.spec.ts @@ -16,6 +16,6 @@ test('should wait for plugin config settings API to respond', async ({ gotoAppCo ); const response = configPage.waitForSettingsResponse(); - await page.getByRole('button', { name: 'Disable' }).first().click(); + await page.getByRole('button', { name: /Disable|Enable/i }).first().click(); await expect(response).toBeOK(); }); diff --git a/packages/plugin-e2e/tests/as-admin-user/datasource/query-editor/queryEditor.integration.spec.ts b/packages/plugin-e2e/tests/as-admin-user/datasource/query-editor/queryEditor.integration.spec.ts index 51eb8f9283..68316e8405 100644 --- a/packages/plugin-e2e/tests/as-admin-user/datasource/query-editor/queryEditor.integration.spec.ts +++ b/packages/plugin-e2e/tests/as-admin-user/datasource/query-editor/queryEditor.integration.spec.ts @@ -33,3 +33,5 @@ test('should be possible to load and execute an existing valid query', async ({ await expect(panelEditPage.refreshPanel()).toBeOK(); await expect(panelEditPage.panel.getErrorIcon()).not.toBeVisible(); }); + +// DEBUG=pw:browser From d357395cf928b5422dec7dd448cea2e7175e0810 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Tue, 22 Apr 2025 13:06:00 +0200 Subject: [PATCH 02/17] Wip --- package-lock.json | 127 +++++++++++++++++++++++----------------------- package.json | 1 + 2 files changed, 65 insertions(+), 63 deletions(-) diff --git a/package-lock.json b/package-lock.json index 396d7ff0f3..8e2cdc48a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "@auto-it/omit-commits": "11.3.0", "@auto-it/slack": "11.3.0", "@grafana/eslint-config": "^8.0.0", + "@playwright/test": "^1.52.0", "@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.1", @@ -6821,6 +6822,22 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@playwright/test": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz", + "integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.52.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@pnpm/config.env-replace": { "version": "1.1.0", "license": "MIT", @@ -24268,6 +24285,53 @@ "node": ">=4" } }, + "node_modules/playwright": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz", + "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.52.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz", + "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "license": "MIT", @@ -31828,22 +31892,6 @@ "@playwright/test": "^1.52.0" } }, - "packages/plugin-e2e/node_modules/@playwright/test": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz", - "integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright": "1.52.0" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, "packages/plugin-e2e/node_modules/dotenv": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", @@ -31857,53 +31905,6 @@ "url": "https://dotenvx.com" } }, - "packages/plugin-e2e/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "packages/plugin-e2e/node_modules/playwright": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz", - "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright-core": "1.52.0" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "packages/plugin-e2e/node_modules/playwright-core": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz", - "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, "packages/plugin-meta-extractor": { "name": "@grafana/plugin-meta-extractor", "version": "0.5.3", diff --git a/package.json b/package.json index 55bf79aba8..94a402c9f3 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@auto-it/omit-commits": "11.3.0", "@auto-it/slack": "11.3.0", "@grafana/eslint-config": "^8.0.0", + "@playwright/test": "^1.52.0", "@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.1", From b62a72b73b9b08afebebc2b9efd67dc4e8f1ac75 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Tue, 22 Apr 2025 15:58:29 +0200 Subject: [PATCH 03/17] Wip --- packages/plugin-e2e/src/models/pages/DashboardPage.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/plugin-e2e/src/models/pages/DashboardPage.ts b/packages/plugin-e2e/src/models/pages/DashboardPage.ts index 3446d67a20..ccb014a19a 100644 --- a/packages/plugin-e2e/src/models/pages/DashboardPage.ts +++ b/packages/plugin-e2e/src/models/pages/DashboardPage.ts @@ -94,9 +94,10 @@ export class DashboardPage extends GrafanaPage { await this.getByGrafanaSelector(components.NavToolbar.editDashboard.editButton).click(); } // on small screens, the toolbar buttons are hidden behind a "Show more items" button - const toolbarButtonsHidden = !scenesEnabled && !!(await this.ctx.page.getByLabel('Show more items').count()); + const showMoreItems = await this.ctx.page.getByLabel('Show more items'); + const toolbarButtonsHidden = !scenesEnabled && (await showMoreItems.count()) > 0; if (toolbarButtonsHidden) { - await this.ctx.page.getByLabel('Show more items').click(); + await showMoreItems.click(); } if (semver.gte(this.ctx.grafanaVersion, '9.5.0')) { From 69e67f03b2337c93824bf0369c1201d8dfc29edd Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Tue, 22 Apr 2025 16:42:25 +0200 Subject: [PATCH 04/17] Wip --- packages/plugin-e2e/src/models/components/DataSourcePicker.ts | 4 ++-- packages/plugin-e2e/src/models/pages/VariableEditPage.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/plugin-e2e/src/models/components/DataSourcePicker.ts b/packages/plugin-e2e/src/models/components/DataSourcePicker.ts index 4b0910fddf..0df58a4224 100644 --- a/packages/plugin-e2e/src/models/components/DataSourcePicker.ts +++ b/packages/plugin-e2e/src/models/components/DataSourcePicker.ts @@ -15,12 +15,12 @@ export class DataSourcePicker extends GrafanaPage { * Sets the data source picker to the provided name */ async set(name: string) { - let datasourcePicker = (this.root || this.ctx.page).getByTestId( + let datasourcePicker = await (this.root || this.ctx.page).getByTestId( this.ctx.selectors.components.DataSourcePicker.inputV2 ); if (semver.lt(this.ctx.grafanaVersion, '10.1.0')) { - datasourcePicker = this.getByGrafanaSelector(this.ctx.selectors.components.DataSourcePicker.container, { + datasourcePicker = await this.getByGrafanaSelector(this.ctx.selectors.components.DataSourcePicker.container, { root: this.root, }).locator('input'); } diff --git a/packages/plugin-e2e/src/models/pages/VariableEditPage.ts b/packages/plugin-e2e/src/models/pages/VariableEditPage.ts index f2dba860ac..fe6db5f52e 100644 --- a/packages/plugin-e2e/src/models/pages/VariableEditPage.ts +++ b/packages/plugin-e2e/src/models/pages/VariableEditPage.ts @@ -30,7 +30,7 @@ export class VariableEditPage extends GrafanaPage { // In versions before 9.2.0, the variable index is not part of the URL so there's no way to navigate to it directly. // Instead, we have to click the nth row in the variable list to navigate to the edit page for a given variable index. if (semver.lt(this.ctx.grafanaVersion, '9.2.0') && this.args.id) { - const list = this.getByGrafanaSelector(this.ctx.selectors.pages.Dashboard.Settings.Variables.List.table).locator( + const list = await this.getByGrafanaSelector(this.ctx.selectors.pages.Dashboard.Settings.Variables.List.table).locator( 'tbody tr' ); const variables = await list.all(); From 6a74eb01093b734cf1eb47e8a09c4fa74ef5fd48 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Wed, 23 Apr 2025 11:57:35 +0200 Subject: [PATCH 05/17] fix(plugin-e2e): assert variables table exists in grafana < 9.2.0 --- packages/plugin-e2e/playwright.config.ts | 6 ------ packages/plugin-e2e/src/models/pages/VariableEditPage.ts | 8 +++++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/plugin-e2e/playwright.config.ts b/packages/plugin-e2e/playwright.config.ts index 3addcbbfea..667c74014e 100644 --- a/packages/plugin-e2e/playwright.config.ts +++ b/packages/plugin-e2e/playwright.config.ts @@ -72,11 +72,7 @@ export default defineConfig({ testDir: './tests/as-admin-user', use: { ...devices['Desktop Chrome'], - launchOptions: { - args: ['--disable-features=PlzDedicatedWorker'], // because https://github.com/microsoft/playwright/pull/34400 - }, storageState: 'playwright/.auth/admin.json', - channel: 'chrome', }, dependencies: ['authenticate'], }, @@ -92,7 +88,6 @@ export default defineConfig({ width: 1920, height: 1080, }, - channel: 'chrome', }, dependencies: ['authenticate'], }, @@ -103,7 +98,6 @@ export default defineConfig({ use: { ...devices['Desktop Chrome'], storageState: 'playwright/.auth/viewer.json', - channel: 'chrome', }, dependencies: ['createUserAndAuthenticate'], }, diff --git a/packages/plugin-e2e/src/models/pages/VariableEditPage.ts b/packages/plugin-e2e/src/models/pages/VariableEditPage.ts index fe6db5f52e..10e552f6be 100644 --- a/packages/plugin-e2e/src/models/pages/VariableEditPage.ts +++ b/packages/plugin-e2e/src/models/pages/VariableEditPage.ts @@ -1,4 +1,5 @@ import * as semver from 'semver'; +import { expect } from '@playwright/test'; import { DashboardEditViewArgs, NavigateOptions, PluginTestCtx } from '../../types'; import { DataSourcePicker } from '../components/DataSourcePicker'; import { GrafanaPage } from './GrafanaPage'; @@ -30,9 +31,10 @@ export class VariableEditPage extends GrafanaPage { // In versions before 9.2.0, the variable index is not part of the URL so there's no way to navigate to it directly. // Instead, we have to click the nth row in the variable list to navigate to the edit page for a given variable index. if (semver.lt(this.ctx.grafanaVersion, '9.2.0') && this.args.id) { - const list = await this.getByGrafanaSelector(this.ctx.selectors.pages.Dashboard.Settings.Variables.List.table).locator( - 'tbody tr' - ); + const list = await this.getByGrafanaSelector( + this.ctx.selectors.pages.Dashboard.Settings.Variables.List.table + ).locator('tbody tr'); + await expect(list).toBeVisible(); const variables = await list.all(); await variables[Number(this.args.id)].click(); } From e01ecc0d70d0c659355edf330c73b6f30db7a7f7 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Wed, 23 Apr 2025 13:05:16 +0200 Subject: [PATCH 06/17] fix(plugin-e2e): another attempt at fixing the showMoreItems e2e test failures --- .../plugin-e2e/src/models/pages/DashboardPage.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/plugin-e2e/src/models/pages/DashboardPage.ts b/packages/plugin-e2e/src/models/pages/DashboardPage.ts index ccb014a19a..006bf5bdc4 100644 --- a/packages/plugin-e2e/src/models/pages/DashboardPage.ts +++ b/packages/plugin-e2e/src/models/pages/DashboardPage.ts @@ -94,10 +94,15 @@ export class DashboardPage extends GrafanaPage { await this.getByGrafanaSelector(components.NavToolbar.editDashboard.editButton).click(); } // on small screens, the toolbar buttons are hidden behind a "Show more items" button - const showMoreItems = await this.ctx.page.getByLabel('Show more items'); - const toolbarButtonsHidden = !scenesEnabled && (await showMoreItems.count()) > 0; - if (toolbarButtonsHidden) { - await showMoreItems.click(); + const viewportDimensions = await this.ctx.page.viewportSize(); + let toolbarButtonsHidden = false; + + if (viewportDimensions && viewportDimensions.width <= 620) { + const showMoreItems = await this.ctx.page.getByLabel('Show more items'); + toolbarButtonsHidden = !scenesEnabled && (await showMoreItems.count()) > 0; + if (toolbarButtonsHidden) { + await showMoreItems.click(); + } } if (semver.gte(this.ctx.grafanaVersion, '9.5.0')) { @@ -105,11 +110,13 @@ export class DashboardPage extends GrafanaPage { components.PageToolbar.itemButton(constants.PageToolBar.itemButtonTitle) ); toolbarButtonsHidden ? await addButton.last().click() : await addButton.click(); + await addButton.click(); await this.getByGrafanaSelector(pages.AddDashboard.itemButton(pages.AddDashboard.itemButtonAddViz)).click(); } else { if (this.dashboard?.uid) { const addPanelButton = this.getByGrafanaSelector(components.PageToolbar.item('Add panel')); toolbarButtonsHidden ? await addPanelButton.last().click() : await addPanelButton.click(); + await addPanelButton.click(); } await this.getByGrafanaSelector(pages.AddDashboard.addNewPanel).click(); } From d84f5e81e0b084dbe16b9041ed9cc59b186f541c Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Wed, 23 Apr 2025 13:08:27 +0200 Subject: [PATCH 07/17] chore(plugin-e2e): delete stray debug button clicks from dashboardpage --- packages/plugin-e2e/src/models/pages/DashboardPage.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/plugin-e2e/src/models/pages/DashboardPage.ts b/packages/plugin-e2e/src/models/pages/DashboardPage.ts index 006bf5bdc4..023befc1b4 100644 --- a/packages/plugin-e2e/src/models/pages/DashboardPage.ts +++ b/packages/plugin-e2e/src/models/pages/DashboardPage.ts @@ -110,13 +110,11 @@ export class DashboardPage extends GrafanaPage { components.PageToolbar.itemButton(constants.PageToolBar.itemButtonTitle) ); toolbarButtonsHidden ? await addButton.last().click() : await addButton.click(); - await addButton.click(); await this.getByGrafanaSelector(pages.AddDashboard.itemButton(pages.AddDashboard.itemButtonAddViz)).click(); } else { if (this.dashboard?.uid) { const addPanelButton = this.getByGrafanaSelector(components.PageToolbar.item('Add panel')); toolbarButtonsHidden ? await addPanelButton.last().click() : await addPanelButton.click(); - await addPanelButton.click(); } await this.getByGrafanaSelector(pages.AddDashboard.addNewPanel).click(); } From bddc3bbc9c4eeb6a0886d1ec6c784f721012fce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Wed, 23 Apr 2025 14:59:40 +0200 Subject: [PATCH 08/17] chore: fixes some flakiness --- .../src/models/pages/AlertRuleEditPage.ts | 22 ++++++++++++++++++- .../alerting/alerting.advancedMode.spec.ts | 2 +- .../alerting/alerting.basicMode.spec.ts | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts b/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts index 9eecb89d1c..10fbbe2506 100644 --- a/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts +++ b/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts @@ -2,7 +2,8 @@ import * as semver from 'semver'; import { AlertRuleArgs, NavigateOptions, PluginTestCtx, RequestOptions } from '../../types'; import { GrafanaPage } from './GrafanaPage'; import { AlertRuleQuery } from '../components/AlertRuleQuery'; - +import { expect } from '@playwright/test'; +import { isFeatureEnabled } from '../../fixtures/isFeatureToggleEnabled'; const QUERY_AND_EXPRESSION_STEP_ID = '2'; export class AlertRuleEditPage extends GrafanaPage { @@ -41,7 +42,26 @@ export class AlertRuleEditPage extends GrafanaPage { } async isAdvancedModeSupported() { + const alertingQueryAndExpressionsStepMode = await isFeatureEnabled( + this.ctx.page, + 'alertingQueryAndExpressionsStepMode' + ); + // why not check if alertingQueryAndExpressionsStepMode feature is enabled? then we'd have to update the code when the toggle is removed. + if (alertingQueryAndExpressionsStepMode) { + await expect( + this.getByGrafanaSelector( + this.ctx.selectors.components.AlertRules.stepAdvancedModeSwitch(QUERY_AND_EXPRESSION_STEP_ID) + ) + ).toBeVisible(); + } else { + await expect( + this.getByGrafanaSelector( + this.ctx.selectors.components.AlertRules.stepAdvancedModeSwitch(QUERY_AND_EXPRESSION_STEP_ID) + ) + ).not.toBeVisible(); + } + const count = await this.getByGrafanaSelector( this.ctx.selectors.components.AlertRules.stepAdvancedModeSwitch(QUERY_AND_EXPRESSION_STEP_ID) ).count(); diff --git a/packages/plugin-e2e/tests/as-admin-user/datasource/alerting/alerting.advancedMode.spec.ts b/packages/plugin-e2e/tests/as-admin-user/datasource/alerting/alerting.advancedMode.spec.ts index 6313ac86f4..e2187655ec 100644 --- a/packages/plugin-e2e/tests/as-admin-user/datasource/alerting/alerting.advancedMode.spec.ts +++ b/packages/plugin-e2e/tests/as-admin-user/datasource/alerting/alerting.advancedMode.spec.ts @@ -6,7 +6,7 @@ const skipMsg = 'Alerting rule test API are only compatible with Grafana 9.5.0 a test.describe('Test alert rule APIs', () => { test('advanced mode should be enabled', async ({ grafanaVersion, alertRuleEditPage }) => { test.skip(semver.lt(grafanaVersion, '11.6.0'), 'Advanced mode is not supported in Grafana versions < 11.6.0'); - expect(await alertRuleEditPage.isAdvancedModeSupported()).toBe(true); + await expect(alertRuleEditPage.advancedModeSwitch).toHaveCount(1); }); test('should be possible to enable advanced mode', async ({ grafanaVersion, alertRuleEditPage }) => { diff --git a/packages/plugin-e2e/tests/as-admin-user/datasource/alerting/alerting.basicMode.spec.ts b/packages/plugin-e2e/tests/as-admin-user/datasource/alerting/alerting.basicMode.spec.ts index eb93d38e60..9521e2b16d 100644 --- a/packages/plugin-e2e/tests/as-admin-user/datasource/alerting/alerting.basicMode.spec.ts +++ b/packages/plugin-e2e/tests/as-admin-user/datasource/alerting/alerting.basicMode.spec.ts @@ -6,7 +6,7 @@ test.use({ featureToggles: { alertingQueryAndExpressionsStepMode: false, alertin test.describe('Test alert rule APIs', () => { test('advanced mode should be disabled', async ({ grafanaVersion, alertRuleEditPage }) => { test.skip(semver.lt(grafanaVersion, '9.5.0'), skipMsg); - expect(await alertRuleEditPage.isAdvancedModeSupported()).toBe(false); + await expect(alertRuleEditPage.advancedModeSwitch).toHaveCount(0); }); }); From 9181b8c3346e9403691c5b74e0c37bc6c33cf3b8 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Wed, 23 Apr 2025 15:56:27 +0200 Subject: [PATCH 09/17] fix(plugin-e2e): wait for datasourcePicker to be visible before setting value --- .../plugin-e2e/src/models/components/DataSourcePicker.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/plugin-e2e/src/models/components/DataSourcePicker.ts b/packages/plugin-e2e/src/models/components/DataSourcePicker.ts index 0df58a4224..816a18708d 100644 --- a/packages/plugin-e2e/src/models/components/DataSourcePicker.ts +++ b/packages/plugin-e2e/src/models/components/DataSourcePicker.ts @@ -1,5 +1,5 @@ import * as semver from 'semver'; -import { Locator } from '@playwright/test'; +import { Locator, expect } from '@playwright/test'; import { PluginTestCtx } from '../../types'; import { GrafanaPage } from '../pages/GrafanaPage'; @@ -15,16 +15,17 @@ export class DataSourcePicker extends GrafanaPage { * Sets the data source picker to the provided name */ async set(name: string) { - let datasourcePicker = await (this.root || this.ctx.page).getByTestId( + let datasourcePicker = (this.root || this.ctx.page).getByTestId( this.ctx.selectors.components.DataSourcePicker.inputV2 ); if (semver.lt(this.ctx.grafanaVersion, '10.1.0')) { - datasourcePicker = await this.getByGrafanaSelector(this.ctx.selectors.components.DataSourcePicker.container, { + datasourcePicker = this.getByGrafanaSelector(this.ctx.selectors.components.DataSourcePicker.container, { root: this.root, }).locator('input'); } + await expect(datasourcePicker).toBeVisible(); await datasourcePicker.fill(name); // this is a hack to get the selection to work in 10.ish versions of Grafana. From 45e0ff7bb020cb254f3d4577a5baa0eb5f4801ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Thu, 24 Apr 2025 06:36:12 +0200 Subject: [PATCH 10/17] chore: cleaning up some redundant code --- .../src/models/pages/AlertRuleEditPage.ts | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts b/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts index 10fbbe2506..14e8a7fbdd 100644 --- a/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts +++ b/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts @@ -47,24 +47,13 @@ export class AlertRuleEditPage extends GrafanaPage { 'alertingQueryAndExpressionsStepMode' ); - // why not check if alertingQueryAndExpressionsStepMode feature is enabled? then we'd have to update the code when the toggle is removed. if (alertingQueryAndExpressionsStepMode) { - await expect( - this.getByGrafanaSelector( - this.ctx.selectors.components.AlertRules.stepAdvancedModeSwitch(QUERY_AND_EXPRESSION_STEP_ID) - ) - ).toBeVisible(); + await expect(this.advancedModeSwitch).toBeVisible(); } else { - await expect( - this.getByGrafanaSelector( - this.ctx.selectors.components.AlertRules.stepAdvancedModeSwitch(QUERY_AND_EXPRESSION_STEP_ID) - ) - ).not.toBeVisible(); + await expect(this.advancedModeSwitch).not.toBeVisible(); } - const count = await this.getByGrafanaSelector( - this.ctx.selectors.components.AlertRules.stepAdvancedModeSwitch(QUERY_AND_EXPRESSION_STEP_ID) - ).count(); + const count = await this.advancedModeSwitch.count(); return count > 0; } From 8806d0c90c030fff0921c7c6b9a028ac50b21995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Thu, 24 Apr 2025 07:24:21 +0200 Subject: [PATCH 11/17] hack: does this pass --- .../templates/app/src/components/App/App.test.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/create-plugin/templates/app/src/components/App/App.test.tsx b/packages/create-plugin/templates/app/src/components/App/App.test.tsx index 6d59f3a9e1..d7ffa6163c 100644 --- a/packages/create-plugin/templates/app/src/components/App/App.test.tsx +++ b/packages/create-plugin/templates/app/src/components/App/App.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { BrowserRouter } from 'react-router-dom'; import { AppRootProps, PluginType } from '@grafana/data'; -import { render, screen } from '@testing-library/react'; +import { render, waitFor } from '@testing-library/react'; import App from './App'; describe('Components/App', () => { @@ -26,12 +26,14 @@ describe('Components/App', () => { }); test('renders without an error"', async () => { - render( + const { findByText } = render( ); - expect(await screen.findByText(/this is page one./i)).toBeInTheDocument(); + await waitFor(async () => { + expect(await findByText(/this is page one./i)).toBeInTheDocument(); + }); }); }); From 30435e79d83eb40f829bfeb8094b686adc0bac79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Thu, 24 Apr 2025 07:32:44 +0200 Subject: [PATCH 12/17] chore: revert hack --- .../templates/app/src/components/App/App.test.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/create-plugin/templates/app/src/components/App/App.test.tsx b/packages/create-plugin/templates/app/src/components/App/App.test.tsx index d7ffa6163c..6d59f3a9e1 100644 --- a/packages/create-plugin/templates/app/src/components/App/App.test.tsx +++ b/packages/create-plugin/templates/app/src/components/App/App.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { BrowserRouter } from 'react-router-dom'; import { AppRootProps, PluginType } from '@grafana/data'; -import { render, waitFor } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import App from './App'; describe('Components/App', () => { @@ -26,14 +26,12 @@ describe('Components/App', () => { }); test('renders without an error"', async () => { - const { findByText } = render( + render( ); - await waitFor(async () => { - expect(await findByText(/this is page one./i)).toBeInTheDocument(); - }); + expect(await screen.findByText(/this is page one./i)).toBeInTheDocument(); }); }); From 56a26e6f358b2f62d745230ca8a90e4d47f2046e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Thu, 24 Apr 2025 07:45:14 +0200 Subject: [PATCH 13/17] hack: trying to pass this test --- .../templates/app/src/components/App/App.test.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/create-plugin/templates/app/src/components/App/App.test.tsx b/packages/create-plugin/templates/app/src/components/App/App.test.tsx index 6d59f3a9e1..41fbe45a3d 100644 --- a/packages/create-plugin/templates/app/src/components/App/App.test.tsx +++ b/packages/create-plugin/templates/app/src/components/App/App.test.tsx @@ -1,8 +1,9 @@ import React from 'react'; import { BrowserRouter } from 'react-router-dom'; import { AppRootProps, PluginType } from '@grafana/data'; -import { render, screen } from '@testing-library/react'; +import { render, waitFor } from '@testing-library/react'; import App from './App'; +import { testIds } from '../testIds'; describe('Components/App', () => { let props: AppRootProps; @@ -26,12 +27,13 @@ describe('Components/App', () => { }); test('renders without an error"', async () => { - render( + const { queryByTestId, findByText } = render( ); - expect(await screen.findByText(/this is page one./i)).toBeInTheDocument(); + await waitFor(() => expect(queryByTestId(testIds.pageOne.container)).toBeInTheDocument(), { timeout: 10000 }); + expect(await findByText(/this is page one./i)).toBeInTheDocument(); }); }); From c4dc9be2257af65a68822aee7744ac3a804b7361 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Thu, 24 Apr 2025 15:55:22 +0200 Subject: [PATCH 14/17] chore(plugin-e2e): remove debug comment from spec --- .../datasource/query-editor/queryEditor.integration.spec.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/plugin-e2e/tests/as-admin-user/datasource/query-editor/queryEditor.integration.spec.ts b/packages/plugin-e2e/tests/as-admin-user/datasource/query-editor/queryEditor.integration.spec.ts index 68316e8405..51eb8f9283 100644 --- a/packages/plugin-e2e/tests/as-admin-user/datasource/query-editor/queryEditor.integration.spec.ts +++ b/packages/plugin-e2e/tests/as-admin-user/datasource/query-editor/queryEditor.integration.spec.ts @@ -33,5 +33,3 @@ test('should be possible to load and execute an existing valid query', async ({ await expect(panelEditPage.refreshPanel()).toBeOK(); await expect(panelEditPage.panel.getErrorIcon()).not.toBeVisible(); }); - -// DEBUG=pw:browser From 232c6ffb04d086e7d9b432c61fb385d34bf83eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Fri, 25 Apr 2025 06:16:14 +0200 Subject: [PATCH 15/17] chore: updates after pr feedback --- .../plugin-e2e/src/models/pages/AlertRuleEditPage.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts b/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts index 14e8a7fbdd..b3f549bbec 100644 --- a/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts +++ b/packages/plugin-e2e/src/models/pages/AlertRuleEditPage.ts @@ -49,13 +49,13 @@ export class AlertRuleEditPage extends GrafanaPage { if (alertingQueryAndExpressionsStepMode) { await expect(this.advancedModeSwitch).toBeVisible(); - } else { - await expect(this.advancedModeSwitch).not.toBeVisible(); + await expect(this.advancedModeSwitch).toHaveCount(1); + return true; } - const count = await this.advancedModeSwitch.count(); - - return count > 0; + await expect(this.advancedModeSwitch).not.toBeVisible(); + await expect(this.advancedModeSwitch).toHaveCount(0); + return false; } /* From 49df38cfc29ceec1d65ee9bad2c801edb112a5a9 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Mon, 5 May 2025 13:10:42 +0200 Subject: [PATCH 16/17] revert(create-plugin): put back launchOptions and channel in playwright config --- packages/create-plugin/templates/common/playwright.config | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/create-plugin/templates/common/playwright.config b/packages/create-plugin/templates/common/playwright.config index 9c8c609f60..f56854266c 100644 --- a/packages/create-plugin/templates/common/playwright.config +++ b/packages/create-plugin/templates/common/playwright.config @@ -46,9 +46,13 @@ export default defineConfig({ use: { ...devices['Desktop Chrome'], storageState: 'playwright/.auth/admin.json', + launchOptions: { + args: ['--disable-features=PlzDedicatedWorker'], // because https://github.com/microsoft/playwright/pull/34400 + }, + channel: 'chrome', }, dependencies: ['auth'], }, ], -}); +}); \ No newline at end of file From 2d82ca0ae5c6075f0ad7a4d6c616b334622653bb Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Mon, 5 May 2025 13:12:02 +0200 Subject: [PATCH 17/17] Wip --- packages/create-plugin/templates/common/playwright.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-plugin/templates/common/playwright.config b/packages/create-plugin/templates/common/playwright.config index f56854266c..c84567bfdb 100644 --- a/packages/create-plugin/templates/common/playwright.config +++ b/packages/create-plugin/templates/common/playwright.config @@ -55,4 +55,4 @@ export default defineConfig({ }, ], -}); \ No newline at end of file +});