From 6008d261f72d9ae723e94f970f208cee4e7dcab4 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Fri, 3 Apr 2026 18:48:32 -0500 Subject: [PATCH] add playwright layout --- .gitignore | 6 +++- angular.json | 18 +++++++++- config.yaml | 5 +++ e2e/example.spec.ts | 15 ++++++++ e2e/modules.spec.ts | 7 ++++ e2e/tsconfig.json | 4 +++ package-lock.json | 83 +++++++++++++++++++++++++++++++++++++++++++- package.json | 3 ++ playwright.config.ts | 77 ++++++++++++++++++++++++++++++++++++++++ 9 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 config.yaml create mode 100644 e2e/example.spec.ts create mode 100644 e2e/modules.spec.ts create mode 100644 e2e/tsconfig.json create mode 100644 playwright.config.ts diff --git a/.gitignore b/.gitignore index c271c63..1de547a 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,8 @@ __screenshots__/ .DS_Store Thumbs.db -*.schema.json \ No newline at end of file +*.schema.json +# Playwright +/test-results/ +/playwright-report/ +/playwright/.cache/ diff --git a/angular.json b/angular.json index 52c838d..8869de4 100644 --- a/angular.json +++ b/angular.json @@ -2,7 +2,9 @@ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { - "packageManager": "npm" + "packageManager": "npm", + "analytics": false, + "schematicCollections": ["@schematics/angular", "playwright-ng-schematics"] }, "newProjectRoot": "projects", "projects": { @@ -64,6 +66,20 @@ }, "test": { "builder": "@angular/build:unit-test" + }, + "e2e": { + "builder": "playwright-ng-schematics:playwright", + "options": { + "devServerTarget": "webui:serve" + }, + "configurations": { + "production": { + "devServerTarget": "webui:serve:production" + }, + "development": { + "devServerTarget": "webui:serve:development" + } + } } } } diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..33a2955 --- /dev/null +++ b/config.yaml @@ -0,0 +1,5 @@ +api: + enabled: true + port: 8080 +modules: [] +routes: [] \ No newline at end of file diff --git a/e2e/example.spec.ts b/e2e/example.spec.ts new file mode 100644 index 0000000..2f97aca --- /dev/null +++ b/e2e/example.spec.ts @@ -0,0 +1,15 @@ +import { expect, test } from '@playwright/test'; + +test.beforeEach(async ({page})=>{ + await page.goto('/') + await expect(page.locator('div').nth(2)).toContainClass('bg-green-400'); +}) + + +test('has title', async ({ page }) => { + await page.goto('/'); + // Expect a title "to contain" a substring. + await expect(page).toHaveTitle(/Showbridge/); +}); + + diff --git a/e2e/modules.spec.ts b/e2e/modules.spec.ts new file mode 100644 index 0000000..55d27d8 --- /dev/null +++ b/e2e/modules.spec.ts @@ -0,0 +1,7 @@ +import { expect, test } from '@playwright/test' + +test('add module', async ({ page }) => { + await page.goto('/'); + await page.locator('app-module-list').getByText('add').click(); + await page.getByRole('menuitem', { name: 'HTTP Server' }).click(); +}) \ No newline at end of file diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json new file mode 100644 index 0000000..5197ce2 --- /dev/null +++ b/e2e/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../tsconfig.json", + "include": ["./**/*.ts"] +} diff --git a/package-lock.json b/package-lock.json index 00309a4..455751e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,10 +28,12 @@ "@angular/cli": "21.2.5", "@angular/compiler-cli": "21.2.6", "@angular/material": "21.2.4", + "@playwright/test": "1.59.1", "@tailwindcss/postcss": "4.2.2", "@types/js-yaml": "4.0.9", "@types/lodash-es": "4.17.12", "jsdom": "29.0.1", + "playwright-ng-schematics": "^21.0.9", "postcss": "8.5.8", "prettier": "3.8.1", "tailwindcss": "4.2.2", @@ -3240,6 +3242,22 @@ "license": "MIT", "optional": true }, + "node_modules/@playwright/test": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz", + "integrity": "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.59.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.0.0-rc.4", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.4.tgz", @@ -4901,7 +4919,6 @@ "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "readdirp": "^5.0.0" }, @@ -7730,6 +7747,70 @@ "node": ">=16.20.0" } }, + "node_modules/playwright": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz", + "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.59.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.59.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz", + "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright-ng-schematics": { + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/playwright-ng-schematics/-/playwright-ng-schematics-21.0.9.tgz", + "integrity": "sha512-PlWSk4qcolfqrOpzbTCaHM2a7mjmrdKQLk13qXWJ8H4o++EHEbJmyq7lyBJ2JNi9Ynsw1Po+4+wYMA/6UQl9VA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@angular-devkit/architect": ">= 0.2100.0 < 0.2200.0", + "@angular-devkit/core": "^21.0.0", + "@angular-devkit/schematics": "^21.0.0" + }, + "peerDependencies": { + "@angular-devkit/architect": ">= 0.2100.0 < 0.2200.0", + "@angular-devkit/core": "^21.0.0", + "@angular-devkit/schematics": "^21.0.0" + } + }, + "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/postcss": { "version": "8.5.8", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", diff --git a/package.json b/package.json index 8694866..b45fe0a 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", + "e2e": "ng e2e", "format:write": "prettier ./ --write" }, "prettier": { @@ -46,10 +47,12 @@ "@angular/cli": "21.2.5", "@angular/compiler-cli": "21.2.6", "@angular/material": "21.2.4", + "@playwright/test": "1.59.1", "@tailwindcss/postcss": "4.2.2", "@types/js-yaml": "4.0.9", "@types/lodash-es": "4.17.12", "jsdom": "29.0.1", + "playwright-ng-schematics": "^21.0.9", "postcss": "8.5.8", "prettier": "3.8.1", "tailwindcss": "4.2.2", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..6b8ddac --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,77 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './e2e', + /* 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', + webServer: [ + { + name: "showbridge", + command: "showbridge --config config.yaml", + url: "http://localhost:8080/health", + timeout: 10000 + } + ], + /* 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['PLAYWRIGHT_TEST_BASE_URL'] ?? 'http://localhost:4200', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + + { + 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' }, + // }, + ], +});