From 31386c44cb9e96570fd2af4e6d94e5c48a6b00bc Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Thu, 15 Feb 2024 17:29:36 +0100 Subject: [PATCH] test(e2e): replace cypress with playwright --- .gitignore | 7 +- cypress/integration/01-smoke.spec.ts | 10 --- package-lock.json | 109 +++++++++++++++++++++++++++ package.json | 3 + playwright.config.ts | 87 +++++++++++++++++++++ tests/example.spec.ts | 28 +++++++ 6 files changed, 233 insertions(+), 11 deletions(-) delete mode 100644 cypress/integration/01-smoke.spec.ts create mode 100644 playwright.config.ts create mode 100644 tests/example.spec.ts diff --git a/.gitignore b/.gitignore index df67443..43008d5 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,9 @@ e2e-results/ # Editor .idea -.eslintcache \ No newline at end of file +.eslintcache +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ +/playwright/.auth/ diff --git a/cypress/integration/01-smoke.spec.ts b/cypress/integration/01-smoke.spec.ts deleted file mode 100644 index ed0867d..0000000 --- a/cypress/integration/01-smoke.spec.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { e2e } from '@grafana/e2e'; - -e2e.scenario({ - describeName: 'Smoke test', - itName: 'Smoke test', - scenario: () => { - e2e.pages.Home.visit(); - e2e().contains('Welcome to Grafana').should('be.visible'); - }, -}); diff --git a/package-lock.json b/package-lock.json index 8dcea03..5cef9d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,9 @@ "@grafana/e2e": "9.5.3", "@grafana/e2e-selectors": "9.5.3", "@grafana/eslint-config": "^6.0.0", + "@grafana/plugin-e2e": "^0.12.0", "@grafana/tsconfig": "^1.2.0-rc1", + "@playwright/test": "^1.41.2", "@swc/core": "^1.3.90", "@swc/helpers": "^0.5.0", "@swc/jest": "^0.2.26", @@ -2677,6 +2679,68 @@ "web-vitals": "^3.1.1" } }, + "node_modules/@grafana/plugin-e2e": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@grafana/plugin-e2e/-/plugin-e2e-0.12.2.tgz", + "integrity": "sha512-C4NfrX+govEZRUB0FaTBpErebkjAR29p85eeoBOWYNJyigUjXMYu8VBG6Sx3MxAdClQDYdlY8y+82TWOdH7TmA==", + "dev": true, + "dependencies": { + "semver": "^7.5.4", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18 <=20" + }, + "peerDependencies": { + "@playwright/test": "^1.40.0" + } + }, + "node_modules/@grafana/plugin-e2e/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@grafana/plugin-e2e/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@grafana/plugin-e2e/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@grafana/plugin-e2e/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@grafana/runtime": { "version": "9.5.3", "resolved": "https://registry.npmjs.org/@grafana/runtime/-/runtime-9.5.3.tgz", @@ -4541,6 +4605,21 @@ "node": ">=14" } }, + "node_modules/@playwright/test": { + "version": "1.41.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.41.2.tgz", + "integrity": "sha512-qQB9h7KbibJzrDpkXkYvsmiDJK14FULCCZgEcoe2AvFAS64oCirWTwzTlAYEbKaRxWs5TFesE1Na6izMv3HfGg==", + "dev": true, + "dependencies": { + "playwright": "1.41.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@popperjs/core": { "version": "2.11.6", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", @@ -16652,6 +16731,36 @@ "node": ">=8" } }, + "node_modules/playwright": { + "version": "1.41.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.41.2.tgz", + "integrity": "sha512-v0bOa6H2GJChDL8pAeLa/LZC4feoAMbSQm1/jF/ySsWWoaNItvrMP7GEkvEEFyCTUYKMxjQKaTSg5up7nR6/8A==", + "dev": true, + "dependencies": { + "playwright-core": "1.41.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.41.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.41.2.tgz", + "integrity": "sha512-VaTvwCA4Y8kxEe+kfm2+uUUw5Lubf38RxF7FpBxLPmGe5sdNkSg5e3ChEigaGrX7qdqT3pt2m/98LiyvU2x6CA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/pngjs": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-2.3.1.tgz", diff --git a/package.json b/package.json index e100ed5..e1c8e0b 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development", "test": "jest --watch --onlyChanged", "test:ci": "jest --passWithNoTests --maxWorkers 4", + "test:playwright": "playwright test", "typecheck": "tsc --noEmit", "lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx .", "lint:fix": "npm run lint -- --fix", @@ -22,7 +23,9 @@ "@grafana/e2e": "9.5.3", "@grafana/e2e-selectors": "9.5.3", "@grafana/eslint-config": "^6.0.0", + "@grafana/plugin-e2e": "^0.12.0", "@grafana/tsconfig": "^1.2.0-rc1", + "@playwright/test": "^1.41.2", "@swc/core": "^1.3.90", "@swc/helpers": "^0.5.0", "@swc/jest": "^0.2.26", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..b0836c8 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,87 @@ +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 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: '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/], + }, + { + name: 'chromium', + use: { ...devices['Desktop Chrome'], storageState: 'playwright/.auth/user.json' }, + dependencies: ['auth'], + }, + + // { + // name: 'firefox', + // use: { ...devices['Desktop Firefox'] }, + // }, + + // { + // name: 'webkit', + // use: { ...devices['Desktop Safari'] }, + // }, + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + // { + // name: 'Google Chrome', + // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + // webServer: { + // command: 'docker compose up -d', + // url: 'http://127.0.0.1:3000', + // reuseExistingServer: !process.env.CI, + // }, +}); diff --git a/tests/example.spec.ts b/tests/example.spec.ts new file mode 100644 index 0000000..e3d4951 --- /dev/null +++ b/tests/example.spec.ts @@ -0,0 +1,28 @@ +import { test } from '@grafana/plugin-e2e'; + +test.describe.configure({ mode: 'parallel' }); + +test('add a traffic light panel to a new dashboard', async ({ panelEditPage, page }) => { + // @ts-expect-error - types currently set to union of core panel plugins + await panelEditPage.setVisualization('Traffic Light'); + await panelEditPage.setPanelTitle('Traffic light panel test'); + await panelEditPage.collapseSection('Traffic Light'); + +}); + +// test('open a clock panel in a provisioned dashboard and set time format to "12 hour"', async ({ +// selectors, +// page, +// request, +// grafanaVersion, +// readProvision, +// }) => { +// const dashboard = await readProvision({ filePath: 'provisioning/dashboards/panels.json' }); +// const args = { dashboard: { uid: dashboard.uid }, id: '5' }; +// const panelEditPage = await new PanelEditPage({ page, selectors, grafanaVersion, request }, args); +// await panelEditPage.goto(); +// await expect(panelEditPage.getVisualizationName()).toHaveText('Clock'); +// await panelEditPage.collapseSection('Clock'); +// await clickRadioButton(page, '12 Hour'); +// await expect(true).toBe(true); +// });