From 1c5942b7f055982ea8868638f1469574593145aa Mon Sep 17 00:00:00 2001 From: Hugo Oshiro Date: Tue, 28 Jan 2025 16:59:56 +0100 Subject: [PATCH 1/7] Create Plugin: Extend the playwright config file --- .../common/.config/playwright.config.ts | 53 +++++++++++++++++++ .../templates/common/playwright.config | 44 ++------------- 2 files changed, 57 insertions(+), 40 deletions(-) create mode 100644 packages/create-plugin/templates/common/.config/playwright.config.ts diff --git a/packages/create-plugin/templates/common/.config/playwright.config.ts b/packages/create-plugin/templates/common/.config/playwright.config.ts new file mode 100644 index 0000000000..f17fb278e6 --- /dev/null +++ b/packages/create-plugin/templates/common/.config/playwright.config.ts @@ -0,0 +1,53 @@ +import type { PluginOptions } from '@grafana/plugin-e2e'; +import { devices, PlaywrightTestConfig } from '@playwright/test'; +import { dirname } from 'node:path'; + +const pluginE2eAuth = `${dirname(require.resolve('@grafana/plugin-e2e'))}/auth`; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default { + testDir: './tests', + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: process.env.GRAFANA_URL || 'http://localhost:3000', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + + /* Configure projects for major browsers */ + projects: [ + // 1. Login to Grafana and store the cookie on disk for use in other tests. + { + name: 'auth', + testDir: pluginE2eAuth, + testMatch: [/.*\.js/], + }, + // 2. Run tests in Google Chrome. Every test will start authenticated as admin user. + { + name: 'chromium', + use: { ...devices['Desktop Chrome'], storageState: 'playwright/.auth/admin.json' }, + dependencies: ['auth'], + }, + ], + +} as PlaywrightTestConfig; diff --git a/packages/create-plugin/templates/common/playwright.config b/packages/create-plugin/templates/common/playwright.config index ae15fc0c7b..19e4e21415 100644 --- a/packages/create-plugin/templates/common/playwright.config +++ b/packages/create-plugin/templates/common/playwright.config @@ -1,8 +1,6 @@ import type { PluginOptions } from '@grafana/plugin-e2e'; -import { defineConfig, devices } from '@playwright/test'; -import { dirname } from 'node:path'; - -const pluginE2eAuth = `${dirname(require.resolve('@grafana/plugin-e2e'))}/auth`; +import { defineConfig } from '@playwright/test'; +import baseDefineConfig from './.config/playwright.config'; /** * Read environment variables from file. @@ -14,40 +12,6 @@ const pluginE2eAuth = `${dirname(require.resolve('@grafana/plugin-e2e'))}/auth`; * See https://playwright.dev/docs/test-configuration. */ export default defineConfig({ - testDir: './tests', - /* Run tests in files in parallel */ - fullyParallel: true, - /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, - /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, - /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: 'html', - /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ - use: { - /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: process.env.GRAFANA_URL || 'http://localhost:3000', - - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', - }, - - /* Configure projects for major browsers */ - projects: [ - // 1. Login to Grafana and store the cookie on disk for use in other tests. - { - name: 'auth', - testDir: pluginE2eAuth, - testMatch: [/.*\.js/], - }, - // 2. Run tests in Google Chrome. Every test will start authenticated as admin user. - { - name: 'chromium', - use: { ...devices['Desktop Chrome'], storageState: 'playwright/.auth/admin.json' }, - dependencies: ['auth'], - }, - ], - + ...baseDefineConfig, + // Add your own configuration here }); From d89fd598ba2d652c690785cf4959499a2e26c713 Mon Sep 17 00:00:00 2001 From: Hugo Oshiro Date: Mon, 3 Feb 2025 12:13:41 +0100 Subject: [PATCH 2/7] Changes from CR --- .../common/.config/playwright.config.ts | 19 ++++++++++--------- .../templates/common/playwright.config | 5 ++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/create-plugin/templates/common/.config/playwright.config.ts b/packages/create-plugin/templates/common/.config/playwright.config.ts index f17fb278e6..6c183b9bf4 100644 --- a/packages/create-plugin/templates/common/.config/playwright.config.ts +++ b/packages/create-plugin/templates/common/.config/playwright.config.ts @@ -1,19 +1,20 @@ +/* + * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ + * + * In order to extend the configuration follow the steps in + * https://grafana.com/developers/plugin-tools/get-started/set-up-development-environment#extend-the-playwright-config + */ + import type { PluginOptions } from '@grafana/plugin-e2e'; -import { devices, PlaywrightTestConfig } from '@playwright/test'; +import { defineConfig, devices } from '@playwright/test'; import { dirname } from 'node:path'; const pluginE2eAuth = `${dirname(require.resolve('@grafana/plugin-e2e'))}/auth`; -/** - * Read environment variables from file. - * https://github.com/motdotla/dotenv - */ -// require('dotenv').config(); - /** * See https://playwright.dev/docs/test-configuration. */ -export default { +export default defineConfig({ testDir: './tests', /* Run tests in files in parallel */ fullyParallel: true, @@ -50,4 +51,4 @@ export default { }, ], -} as PlaywrightTestConfig; +}); diff --git a/packages/create-plugin/templates/common/playwright.config b/packages/create-plugin/templates/common/playwright.config index 19e4e21415..ebb38c8512 100644 --- a/packages/create-plugin/templates/common/playwright.config +++ b/packages/create-plugin/templates/common/playwright.config @@ -1,6 +1,6 @@ import type { PluginOptions } from '@grafana/plugin-e2e'; import { defineConfig } from '@playwright/test'; -import baseDefineConfig from './.config/playwright.config'; +import baseConfig from './.config/playwright.config'; /** * Read environment variables from file. @@ -11,7 +11,6 @@ import baseDefineConfig from './.config/playwright.config'; /** * See https://playwright.dev/docs/test-configuration. */ -export default defineConfig({ - ...baseDefineConfig, +export default defineConfig(baseConfig, { // Add your own configuration here }); From f6d19c82432adc7fdbaa165a4bea3869175706eb Mon Sep 17 00:00:00 2001 From: Hugo Oshiro Date: Wed, 19 Feb 2025 09:57:00 +0100 Subject: [PATCH 3/7] Adjust with changes from main --- .../templates/common/.config/playwright.config.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/create-plugin/templates/common/.config/playwright.config.ts b/packages/create-plugin/templates/common/.config/playwright.config.ts index 6c183b9bf4..7d6681ce13 100644 --- a/packages/create-plugin/templates/common/.config/playwright.config.ts +++ b/packages/create-plugin/templates/common/.config/playwright.config.ts @@ -1,9 +1,9 @@ /* - * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ - * - * In order to extend the configuration follow the steps in - * https://grafana.com/developers/plugin-tools/get-started/set-up-development-environment#extend-the-playwright-config - */ + * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ + * + * In order to extend the configuration follow the steps in + * https://grafana.com/developers/plugin-tools/get-started/set-up-development-environment#extend-the-playwright-config + */ import type { PluginOptions } from '@grafana/plugin-e2e'; import { defineConfig, devices } from '@playwright/test'; @@ -22,8 +22,6 @@ export default defineConfig({ forbidOnly: !!process.env.CI, /* Retry on CI only */ retries: process.env.CI ? 2 : 0, - /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: 'html', /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ @@ -50,5 +48,4 @@ export default defineConfig({ dependencies: ['auth'], }, ], - }); From 012d9abdedb937421a2c556da5fca70de8d3b0a9 Mon Sep 17 00:00:00 2001 From: Hugo Oshiro Date: Fri, 9 May 2025 11:41:27 +0200 Subject: [PATCH 4/7] Update playwright config --- .../templates/common/.config/playwright.config.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/create-plugin/templates/common/.config/playwright.config.ts b/packages/create-plugin/templates/common/.config/playwright.config.ts index 7d6681ce13..390a72f10f 100644 --- a/packages/create-plugin/templates/common/.config/playwright.config.ts +++ b/packages/create-plugin/templates/common/.config/playwright.config.ts @@ -44,7 +44,10 @@ export default defineConfig({ // 2. Run tests in Google Chrome. Every test will start authenticated as admin user. { name: 'chromium', - use: { ...devices['Desktop Chrome'], storageState: 'playwright/.auth/admin.json' }, + use: { + ...devices['Desktop Chrome'], + storageState: 'playwright/.auth/admin.json', + }, dependencies: ['auth'], }, ], From b32dfd8475d591481de1daff6f843b9198fa4455 Mon Sep 17 00:00:00 2001 From: Hugo Oshiro Date: Mon, 12 May 2025 17:55:39 +0200 Subject: [PATCH 5/7] Update docs --- .../docs/e2e-test-a-plugin/authentication.md | 35 +++++++-------- .../docs/e2e-test-a-plugin/feature-toggles.md | 7 +-- .../migrate-from-grafana-e2e.md | 7 +-- .../set-up-development-environment.mdx | 44 +++++++++++++++++++ 4 files changed, 69 insertions(+), 24 deletions(-) diff --git a/docusaurus/docs/e2e-test-a-plugin/authentication.md b/docusaurus/docs/e2e-test-a-plugin/authentication.md index 522ef7eb05..31d2abbc3b 100644 --- a/docusaurus/docs/e2e-test-a-plugin/authentication.md +++ b/docusaurus/docs/e2e-test-a-plugin/authentication.md @@ -26,14 +26,13 @@ In the following example, there's a [setup project](https://playwright.dev/docs/ The second project, `run-tests`, runs all tests in the `./tests` directory. This project reuses the authentication state from the `auth` project. As a consequence, login only happens once, and all tests in the `run-tests` project start already authenticated. ```ts title="playwright.config.ts" -import { dirname } from 'path'; -import { defineConfig, devices } from '@playwright/test'; +import type { PluginOptions } from '@grafana/plugin-e2e'; +import { defineConfig } from '@playwright/test'; +import baseConfig from './.config/playwright.config'; -const pluginE2eAuth = `${dirname(require.resolve('@grafana/plugin-e2e'))}/auth`; - -export default defineConfig({ - ... - projects: [ +export default defineConfig(baseConfig, { + projects: [ + ...baseConfig.projects!, { name: 'auth', testDir: pluginE2eAuth, @@ -48,7 +47,7 @@ export default defineConfig({ storageState: 'playwright/.auth/admin.json', }, dependencies: ['auth'], - } + }, ], }); ``` @@ -60,14 +59,14 @@ If your plugin uses RBAC, you may want to write tests that verify that certain p The `@grafana/plugin-e2e` tool lets you define users with roles in the Playwright config file. In the following example, a new user with the role `Viewer` is created in the `createViewerUserAndAuthenticate` setup project. In the next project, authentication state for the user with the viewer role is reused when running the tests. Note that tests that are specific for the `Viewer` role have been added to a dedicated `testDir`. ```ts title="playwright.config.ts" -import { dirname } from 'path'; -import { defineConfig, devices } from '@playwright/test'; - -const pluginE2eAuth = `${dirname(require.resolve('@grafana/plugin-e2e'))}/auth`; +import type { PluginOptions } from '@grafana/plugin-e2e'; +import { defineConfig } from '@playwright/test'; +import baseConfig from './.config/playwright.config'; -export default defineConfig({ +export default defineConfig(baseConfig, { ... projects: [ + ...baseConfig.projects!, { name: 'createViewerUserAndAuthenticate', testDir: pluginE2eAuth, @@ -100,12 +99,11 @@ export default defineConfig({ When a `user` is defined in a setup project (like in the RBAC example above) `plugin-e2e` will use the Grafana HTTP API to create the user account. This action requires elevated permissions, so by default the server administrator credentials `admin:admin` will be used. If the end-to-end tests are targeting the [development environment](../get-started/set-up-development-environment.mdx) scaffolded with `create-plugin`, this will work fine. However for other test environments the server administrator password may be different. In that case, we search for GRAFANA_ADMIN_USER and GRAFANA_ADMIN_PASSWORD environment variables. Additionally you can provide the correct credentials by setting `grafanaAPICredentials` in the global options. ```ts title="playwright.config.ts" -import { dirname } from 'path'; -import { defineConfig, devices } from '@playwright/test'; - -const pluginE2eAuth = `${dirname(require.resolve('@grafana/plugin-e2e'))}/auth`; +import type { PluginOptions } from '@grafana/plugin-e2e'; +import { defineConfig } from '@playwright/test'; +import baseConfig from './.config/playwright.config'; -export default defineConfig({ +export default defineConfig(baseConfig, { testDir: './tests', use: { baseURL: process.env.GRAFANA_URL || 'http://localhost:3000', @@ -115,6 +113,7 @@ export default defineConfig({ }, }, projects: [ + ...baseConfig.projects!, ... ] }) diff --git a/docusaurus/docs/e2e-test-a-plugin/feature-toggles.md b/docusaurus/docs/e2e-test-a-plugin/feature-toggles.md index 18c217110a..c59744f19f 100644 --- a/docusaurus/docs/e2e-test-a-plugin/feature-toggles.md +++ b/docusaurus/docs/e2e-test-a-plugin/feature-toggles.md @@ -27,10 +27,11 @@ The `@grafana/plugin-e2e` tool allows you to override the frontend feature toggl ```typescript // playwright.config.ts -import { defineConfig, devices } from '@playwright/test'; -import { PluginOptions } from '@grafana/plugin-e2e'; +import type { PluginOptions } from '@grafana/plugin-e2e'; +import { defineConfig } from '@playwright/test'; +import baseConfig from './.config/playwright.config'; -export default defineConfig({ +export default defineConfig(baseConfig, { testDir: './tests', reporter: 'html', use: { diff --git a/docusaurus/docs/e2e-test-a-plugin/migrate-from-grafana-e2e.md b/docusaurus/docs/e2e-test-a-plugin/migrate-from-grafana-e2e.md index 30ab4161c9..cd5118c69b 100644 --- a/docusaurus/docs/e2e-test-a-plugin/migrate-from-grafana-e2e.md +++ b/docusaurus/docs/e2e-test-a-plugin/migrate-from-grafana-e2e.md @@ -58,15 +58,16 @@ Open the Playwright config file that was generated when Playwright was installed Your Playwright config should have the following project configuration: ```ts title="playwright.config.ts" -import { dirname } from 'path'; -import { defineConfig, devices } from '@playwright/test'; import type { PluginOptions } from '@grafana/plugin-e2e'; +import { defineConfig } from '@playwright/test'; +import baseConfig from './.config/playwright.config'; const pluginE2eAuth = `${dirname(require.resolve('@grafana/plugin-e2e'))}/auth`; -export default defineConfig({ +export default defineConfig(baseConfig, { ... projects: [ + ...baseConfig.projects!, { name: 'auth', testDir: pluginE2eAuth, diff --git a/docusaurus/docs/get-started/set-up-development-environment.mdx b/docusaurus/docs/get-started/set-up-development-environment.mdx index 3a263789a1..d04be0d54f 100644 --- a/docusaurus/docs/get-started/set-up-development-environment.mdx +++ b/docusaurus/docs/get-started/set-up-development-environment.mdx @@ -441,3 +441,47 @@ Update the `scripts` in the `package.json` to use the extended Webpack configura -"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development", +"dev": "webpack -w -c ./webpack.config.ts --env development", ``` + +### Extend the Playwright config + +To extend the Playwright configuration, edit the `playwright.config.ts` file in the project root: + +```ts title="playwright.config.ts" + +export default defineConfig(baseConfig, { + projects: [ + ...baseConfig.projects!, + { + // Firefox example + name: 'firefox', + use: { ...devices['Desktop Firefox'], storageState: 'playwright/.auth/admin.json' }, + dependencies: ['auth'], + }, + // Add your custom project here... + ], + // Add your custom config here... +}); +``` + +note that the projects array has to be explicity destructured to merge the `baseConfig` projects (defined in `.config/`) with your custom projects. If you don't do this, the default projects will be replaced by your custom ones. + +Another alternative is to use `webpacka-merge` to merge the base config with your custom config: + +```ts title="playwright.config.ts" +import { merge } from 'webpack-merge'; +import defaultConfig from './.config/playwright.config'; + +const config = merge(baseConfig, { + projects: [ + { + name: 'firefox', + use: { ...devices['Desktop Firefox'], storageState: 'playwright/.auth/admin.json' }, + dependencies: ['auth'], + }, + // Add your custom project here... + ], + // Add your custom config here... +}); + +export default defineConfig(baseConfig); +``` From 02dc7b01036413c285a72a6596d3e9a5542eb88c Mon Sep 17 00:00:00 2001 From: Hugo Oshiro Date: Wed, 14 May 2025 12:16:16 +0200 Subject: [PATCH 6/7] Revert file to main version --- .../tests/as-admin-user/app/app-config/appConfig.spec.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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 260799f6b2..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,9 +16,6 @@ test('should wait for plugin config settings API to respond', async ({ gotoAppCo ); const response = configPage.waitForSettingsResponse(); - await page - .getByRole('button', { name: /Disable|Enable/i }) - .first() - .click(); + await page.getByRole('button', { name: /Disable|Enable/i }).first().click(); await expect(response).toBeOK(); }); From 3e91f7ebd8ba68d592d210c2532797728483173d Mon Sep 17 00:00:00 2001 From: Hugo Oshiro Date: Mon, 7 Jul 2025 12:09:21 +0200 Subject: [PATCH 7/7] Add instructions on how to extend the playwright config --- .../set-up-development-environment.mdx | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/docusaurus/docs/get-started/set-up-development-environment.mdx b/docusaurus/docs/get-started/set-up-development-environment.mdx index 0abccf1bec..d360da70fe 100644 --- a/docusaurus/docs/get-started/set-up-development-environment.mdx +++ b/docusaurus/docs/get-started/set-up-development-environment.mdx @@ -267,3 +267,44 @@ jobs: ##### Main stats artifact could not be found If you see this warning during bundle size workflow runs it means that the workflow failed to find the github artifact that contains the main branch stats file. The file can be generated by either merging a PR to main, pushing a commit to main, or manually running the workflow with workflow_dispatch. + +### Extend the Playwright config + +To extend the Playwright configuration, edit the `playwright.config.ts` file in the project root: + +```ts title="playwright.config.ts" +export default defineConfig(baseConfig, { + projects: [ + ...baseConfig.projects!, + { + // Firefox example + name: 'firefox', + use: { ...devices['Desktop Firefox'], storageState: 'playwright/.auth/admin.json' }, + dependencies: ['auth'], + }, + // Add your custom project here... + ], + // Add your custom config here... +}); +``` + +note that the projects array has to be explicity destructured to merge the `baseConfig` projects (defined in `.config/`) with your custom projects. If you don't do this, the default projects will be replaced by your custom ones. + +Another alternative is to use `webpacka-merge` to merge the base config with your custom config: + +```ts title="playwright.config.ts" +import { merge } from 'webpack-merge'; +import defaultConfig from './.config/playwright.config'; +const config = merge(baseConfig, { + projects: [ + { + name: 'firefox', + use: { ...devices['Desktop Firefox'], storageState: 'playwright/.auth/admin.json' }, + dependencies: ['auth'], + }, + // Add your custom project here... + ], + // Add your custom config here... +}); +export default defineConfig(baseConfig); +```