From a79e20257315b4f82984cf570fd95b04399103fc Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Tue, 7 Oct 2025 13:52:31 -0700 Subject: [PATCH] working playwright example --- .github/workflows/playwright.yml | 27 +++++++ .gitignore | 7 ++ apps/desktop/desktop_native/Cargo.lock | 4 +- .../src/app/auth/login/example.play.spec.ts | 18 +++++ package-lock.json | 17 ++++ package.json | 1 + playwright.config.ts | 80 +++++++++++++++++++ tsconfig.eslint.json | 3 +- tsconfig.json | 3 +- 9 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/playwright.yml create mode 100644 apps/web/src/app/auth/login/example.play.spec.ts create mode 100644 playwright.config.ts diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 00000000000..bf4c8cbe16a --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,27 @@ +name: Playwright Tests +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: lts/* + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: npx playwright test + - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index 0f609335b63..e7b9b04b6f6 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,10 @@ apps/**/config/local.json # Nx .nx + +# Playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ +/playwright/.auth/ diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 55f474f2992..ca9965e5e18 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -2897,9 +2897,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b369d18893388b345804dc0007963c99b7d665ae71d275812d828c6f089640" +checksum = "cc198e42d9b7510827939c9a15f5062a0c913f3371d765977e586d2fe6c16f4a" dependencies = [ "bitflags", "core-foundation", diff --git a/apps/web/src/app/auth/login/example.play.spec.ts b/apps/web/src/app/auth/login/example.play.spec.ts new file mode 100644 index 00000000000..839cef5ca0a --- /dev/null +++ b/apps/web/src/app/auth/login/example.play.spec.ts @@ -0,0 +1,18 @@ +import { test, expect } from "@playwright/test"; + +test("has title", async ({ page }) => { + await page.goto("https://playwright.dev/"); + + // Expect a title "to contain" a substring. + await expect(page).toHaveTitle(/Playwright/); +}); + +test("get started link", async ({ page }) => { + await page.goto("https://playwright.dev/"); + + // Click the get started link. + await page.getByRole("link", { name: "Get started" }).click(); + + // Expects page to have a heading with the name of Installation. + await expect(page.getByRole("heading", { name: "Installation" })).toBeVisible(); +}); diff --git a/package-lock.json b/package-lock.json index 988af50965f..11a3968e023 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,6 +86,7 @@ "@eslint/compat": "1.2.9", "@lit-labs/signals": "0.1.2", "@ngtools/webpack": "19.2.14", + "@playwright/test": "1.56.0", "@storybook/addon-a11y": "8.6.12", "@storybook/addon-actions": "8.6.12", "@storybook/addon-designs": "8.2.1", @@ -11127,6 +11128,22 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@playwright/test": { + "version": "1.56.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.0.tgz", + "integrity": "sha512-Tzh95Twig7hUwwNe381/K3PggZBZblKUe2wv25oIpzWLr6Z0m4KgV1ZVIjnR6GM9ANEqjZD7XsZEa6JL/7YEgg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.56.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.34.8", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", diff --git a/package.json b/package.json index 3867d884a29..9fd29d53743 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "@eslint/compat": "1.2.9", "@lit-labs/signals": "0.1.2", "@ngtools/webpack": "19.2.14", + "@playwright/test": "1.56.0", "@storybook/addon-a11y": "8.6.12", "@storybook/addon-actions": "8.6.12", "@storybook/addon-designs": "8.2.1", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000000..560fdc4cef7 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,80 @@ +import { defineConfig, devices } from "@playwright/test"; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// import dotenv from 'dotenv'; +// import path from 'path'; +// dotenv.config({ path: path.resolve(__dirname, '.env') }); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: "./", + testMatch: ["**/*.play.spec.ts"], + /* 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: [ + { + 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' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + // webServer: { + // command: 'npm run start', + // url: 'http://localhost:3000', + // reuseExistingServer: !process.env.CI, + // }, +}); diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 34ee7e719c1..5dbfc5598fb 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -5,7 +5,8 @@ ".storybook/manager.js", ".storybook/test-runner.ts", ".storybook/format-args-for-code-snippet.ts", - "apps/browser/src/autofill/content/components/.lit-storybook/main.ts" + "apps/browser/src/autofill/content/components/.lit-storybook/main.ts", + "playwright.config.ts" ], "include": ["apps/**/*", "libs/**/*", "bitwarden_license/**/*", "scripts/**/*"], "exclude": ["**/build", "**/dist"] diff --git a/tsconfig.json b/tsconfig.json index 35200efa430..12140e3e354 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,8 @@ "libs/tools/send/**/src/**/*", "libs/dirt/card/src/**/*", "bitwarden_license/bit-web/src/**/*", - "bitwarden_license/bit-common/src/**/*" + "bitwarden_license/bit-common/src/**/*", + "playwright.config.ts" ], "exclude": [ "apps/web/src/**/*.spec.ts",