Skip to content

Create Plugin: Extend the playwright config file #1495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
35 changes: 17 additions & 18 deletions docusaurus/docs/e2e-test-a-plugin/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<PluginOptions>(baseConfig, {
projects: [
...baseConfig.projects!,
{
name: 'auth',
testDir: pluginE2eAuth,
Expand All @@ -48,7 +47,7 @@ export default defineConfig({
storageState: 'playwright/.auth/admin.json',
},
dependencies: ['auth'],
}
},
],
});
```
Expand All @@ -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<PluginOptions>({
export default defineConfig<PluginOptions>(baseConfig, {
...
projects: [
...baseConfig.projects!,
{
name: 'createViewerUserAndAuthenticate',
testDir: pluginE2eAuth,
Expand Down Expand Up @@ -100,12 +99,11 @@ export default defineConfig<PluginOptions>({
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<PluginOptions>({
export default defineConfig<PluginOptions>(baseConfig, {
testDir: './tests',
use: {
baseURL: process.env.GRAFANA_URL || 'http://localhost:3000',
Expand All @@ -115,6 +113,7 @@ export default defineConfig<PluginOptions>({
},
},
projects: [
...baseConfig.projects!,
...
]
})
Expand Down
7 changes: 4 additions & 3 deletions docusaurus/docs/e2e-test-a-plugin/feature-toggles.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<PluginOptions>({
export default defineConfig<PluginOptions>(baseConfig, {
testDir: './tests',
reporter: 'html',
use: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<PluginOptions>({
export default defineConfig<PluginOptions>(baseConfig, {
...
projects: [
...baseConfig.projects!,
{
name: 'auth',
testDir: pluginE2eAuth,
Expand Down
44 changes: 44 additions & 0 deletions docusaurus/docs/get-started/set-up-development-environment.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
```
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ export class ExampleDatasource
return undefined;
}
}

private getLogsSampleDataProvider(
request: DataQueryRequest<ExampleQuery>,
options?: LogsSampleOptions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* ⚠️⚠️⚠️ 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';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
import type { PluginOptions } from '@grafana/plugin-e2e';
/*
* ⚠️⚠️⚠️ 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';

If we decide to do this I think we should update the docs site in this PR too with instructions.

import { defineConfig, devices } from '@playwright/test';
import { dirname } from 'node:path';

const pluginE2eAuth = `${dirname(require.resolve('@grafana/plugin-e2e'))}/auth`;

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig<PluginOptions>({
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,
/* 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'],
},
],
});
46 changes: 4 additions & 42 deletions packages/create-plugin/templates/common/playwright.config
Original file line number Diff line number Diff line change
@@ -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 baseConfig from './.config/playwright.config';

/**
* Read environment variables from file.
Expand All @@ -13,42 +11,6 @@ const pluginE2eAuth = `${dirname(require.resolve('@grafana/plugin-e2e'))}/auth`;
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig<PluginOptions>({
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,
/* 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'],
},
],

export default defineConfig<PluginOptions>(baseConfig, {
// Add your own configuration here
});
Loading