From f2686f9509a084c3b101be9dcdcf8e53b454ed16 Mon Sep 17 00:00:00 2001 From: Wes Date: Wed, 21 Aug 2024 08:21:23 -0700 Subject: [PATCH] chore: add console e2e testing with playwright (#2462) Fixes #2416 --- .github/workflows/ci.yml | 2 + Justfile | 5 +- frontend/.gitignore | 6 +- frontend/biome.json | 4 +- frontend/package-lock.json | 100 +++++++++++++++++- frontend/package.json | 11 +- frontend/playwright.config.ts | 43 ++++++++ frontend/src/layout/navigation/Navigation.tsx | 1 + frontend/tests/deployment.spec.ts | 14 +++ frontend/tests/deployments.spec.ts | 10 ++ frontend/tests/events.spec.ts | 7 ++ frontend/tests/ftl-test.ts | 17 +++ frontend/tests/verb.spec.ts | 23 ++++ 13 files changed, 232 insertions(+), 11 deletions(-) create mode 100644 frontend/playwright.config.ts create mode 100644 frontend/tests/deployment.spec.ts create mode 100644 frontend/tests/deployments.spec.ts create mode 100644 frontend/tests/events.spec.ts create mode 100644 frontend/tests/ftl-test.ts create mode 100644 frontend/tests/verb.spec.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ea3c1cda8..42ccc308d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,6 +136,8 @@ jobs: run: npm run lint - name: Console Build run: just build-frontend + - name: Console Test + run: just test-frontend extension: name: VSCode Extension runs-on: ubuntu-latest diff --git a/Justfile b/Justfile index 355402b84e..a586bc4a22 100644 --- a/Justfile +++ b/Justfile @@ -153,6 +153,9 @@ test-scripts: GIT_AUTHOR_EMAIL="no-reply@tbd.email" \ scripts/tests/test-ensure-frozen-migrations.sh +test-frontend: build-frontend + @cd frontend && npx playwright install --with-deps && npm run test + # Lint the frontend lint-frontend: build-frontend @cd frontend && npm run lint && tsc @@ -233,4 +236,4 @@ grafana-stop: storybook: #!/bin/bash - cd frontend && npm run storybook \ No newline at end of file + cd frontend && npm run storybook diff --git a/frontend/.gitignore b/frontend/.gitignore index be9ab76552..b10090e384 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -23,4 +23,8 @@ dist-ssr *.sln *.sw? */.parcel-cache -*storybook.log \ No newline at end of file +*storybook.log +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/frontend/biome.json b/frontend/biome.json index dd011beec1..ab7cde5926 100644 --- a/frontend/biome.json +++ b/frontend/biome.json @@ -18,14 +18,14 @@ "noArrayIndexKey": "off" } }, - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx", "src/**/*.cjs", "src/**/*.mjs"], + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx", "src/**/*.cjs", "src/**/*.mjs", "tests/**/*.ts"], "ignore": ["./node_modules", "./dist", "./src/protos"] }, "formatter": { "indentStyle": "space", "indentWidth": 2, "lineWidth": 160, - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx", "src/**/*.cjs", "src/**/*.mjs"], + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx", "src/**/*.cjs", "src/**/*.mjs", "tests/**/*.ts"], "ignore": ["./node_modules", "./dist", "./src/protos"] }, "javascript": { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 39c31da20b..00a924c5cb 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -40,6 +40,7 @@ "devDependencies": { "@biomejs/biome": "1.8.3", "@chromatic-com/storybook": "^1.6.1", + "@playwright/test": "^1.46.1", "@storybook/addon-essentials": "^8.2.7", "@storybook/addon-interactions": "^8.2.7", "@storybook/addon-links": "^8.2.7", @@ -51,6 +52,7 @@ "@storybook/react-vite": "^8.2.7", "@storybook/test": "^8.2.7", "@tanstack/eslint-plugin-query": "^5.51.15", + "@types/node": "^22.4.1", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", "buffer": "^6.0.3", @@ -3434,6 +3436,22 @@ "node": ">=14" } }, + "node_modules/@playwright/test": { + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.46.1.tgz", + "integrity": "sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.46.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@radix-ui/number": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", @@ -7153,11 +7171,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", - "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "version": "22.4.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.1.tgz", + "integrity": "sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg==", + "devOptional": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/node-fetch": { @@ -7170,6 +7190,13 @@ "form-data": "^4.0.0" } }, + "node_modules/@types/node/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "devOptional": true, + "license": "MIT" + }, "node_modules/@types/pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -8555,6 +8582,21 @@ "@lezer/common": "^1.0.3" } }, + "node_modules/codemirror-json-schema/node_modules/@types/node": { + "version": "20.16.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.1.tgz", + "integrity": "sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/codemirror-json-schema/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, "node_modules/codemirror-json5": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/codemirror-json5/-/codemirror-json5-1.0.3.tgz", @@ -12917,6 +12959,53 @@ "pathe": "^1.1.2" } }, + "node_modules/playwright": { + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.1.tgz", + "integrity": "sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.46.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.1.tgz", + "integrity": "sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==", + "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/polished": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", @@ -15639,7 +15728,8 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", diff --git a/frontend/package.json b/frontend/package.json index 8962178749..63f38fbb74 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,13 +10,18 @@ "dev": "vite", "lint": "biome check .", "lint:fix": "biome format . --write", + "test": "playwright test", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" }, "lint-staged": { - "*.(js|cjs|tsx|ts)": ["npm run lint:fix"] + "*.(js|cjs|tsx|ts)": [ + "npm run lint:fix" + ] }, - "browserslist": ["> 2%"], + "browserslist": [ + "> 2%" + ], "source": "index.html", "dependencies": { "@bufbuild/protoc-gen-es": "1.10.0", @@ -51,6 +56,7 @@ "devDependencies": { "@biomejs/biome": "1.8.3", "@chromatic-com/storybook": "^1.6.1", + "@playwright/test": "^1.46.1", "@storybook/addon-essentials": "^8.2.7", "@storybook/addon-interactions": "^8.2.7", "@storybook/addon-links": "^8.2.7", @@ -62,6 +68,7 @@ "@storybook/react-vite": "^8.2.7", "@storybook/test": "^8.2.7", "@tanstack/eslint-plugin-query": "^5.51.15", + "@types/node": "^22.4.1", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", "buffer": "^6.0.3", diff --git a/frontend/playwright.config.ts b/frontend/playwright.config.ts new file mode 100644 index 0000000000..844a9331ca --- /dev/null +++ b/frontend/playwright.config.ts @@ -0,0 +1,43 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './tests', + 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: 'html', + use: { + baseURL: 'http://localhost:8892', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + ], + webServer: { + command: 'ftl dev --recreate', + url: 'http://localhost:8892', + reuseExistingServer: true, + }, +}); diff --git a/frontend/src/layout/navigation/Navigation.tsx b/frontend/src/layout/navigation/Navigation.tsx index 8aae20f8bd..ea2bb82b2c 100644 --- a/frontend/src/layout/navigation/Navigation.tsx +++ b/frontend/src/layout/navigation/Navigation.tsx @@ -73,6 +73,7 @@ export const Navigation = ({ {item.name} {['/modules', '/deployments'].includes(item.href) && (