From fd5d8b1367f2726a451f40054f22c0eea09573c4 Mon Sep 17 00:00:00 2001 From: Huw Wilkins Date: Tue, 25 Feb 2025 12:06:42 +1100 Subject: [PATCH] playwright --- .github/workflows/actions.yml | 7 +++ .github/workflows/coverage.yml | 1 + .github/workflows/jimm.yml | 26 +++++++++-- .github/workflows/test.yml | 1 + .github/workflows/tics-coverage.yml | 1 + .gitignore | 6 +++ e2e/example.spec.ts | 22 +++++++++ package.json | 1 + playwright.config.ts | 71 +++++++++++++++++++++++++++++ src/juju/api.ts | 2 +- yarn.lock | 40 +++++++++++++++- 11 files changed, 172 insertions(+), 6 deletions(-) create mode 100644 e2e/example.spec.ts create mode 100644 playwright.config.ts diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index cbbdedeac..501b07680 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -8,6 +8,7 @@ on: - main jobs: prettier: + if: false name: Check Prettier runs-on: ubuntu-latest strategy: @@ -24,6 +25,7 @@ jobs: run: yarn install --immutable - run: yarn prettier --check 'src/**/*' eslint: + if: false name: Lint JavaScript/TypeScript runs-on: ubuntu-latest strategy: @@ -40,6 +42,7 @@ jobs: run: yarn install --immutable - run: yarn eslint-check stylelint: + if: false name: Lint SCSS runs-on: ubuntu-latest strategy: @@ -56,6 +59,7 @@ jobs: run: yarn install --immutable - run: yarn stylelint-check renovate: + if: false name: Check renovate runs-on: ubuntu-latest strategy: @@ -71,6 +75,7 @@ jobs: - name: Validate Renovate Configuration with renovate-config-validator uses: suzuki-shunsuke/github-action-renovate-config-validator@v1.1.1 types: + if: false name: Check types runs-on: ubuntu-latest strategy: @@ -87,6 +92,7 @@ jobs: run: yarn install --immutable - run: yarn typescript-build build: + if: false name: Build runs-on: ubuntu-latest strategy: @@ -103,6 +109,7 @@ jobs: run: yarn install --immutable - run: CI=false yarn build dotrun: + if: false runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 79b6e9685..7752b73ad 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -6,6 +6,7 @@ on: - completed jobs: report: + if: false runs-on: ubuntu-latest permissions: actions: read diff --git a/.github/workflows/jimm.yml b/.github/workflows/jimm.yml index b9dfd9d89..7c7cb654b 100644 --- a/.github/workflows/jimm.yml +++ b/.github/workflows/jimm.yml @@ -18,6 +18,9 @@ jobs: with: repository: canonical/jimm path: jimm + - name: Update dashboard paths + run: | + sed -i -e 's/JIMM_DASHBOARD_FINAL_REDIRECT_URL: "https:\/\/jaas.ai"/CORS_ALLOWED_ORIGINS: "http:\/\/127.0.0.1:8000"\n JIMM_DASHBOARD_LOCATION: "http:\/\/127.0.0.1:8000"\n JIMM_DASHBOARD_FINAL_REDIRECT_URL: "http:\/\/127.0.0.1:8000"/g' jimm/docker-compose.common.yaml - name: Setup Go uses: actions/setup-go@v4 @@ -33,6 +36,7 @@ jobs: jimm-version: dev juju-channel: "3/stable" ghcr-pat: ${{ secrets.GITHUB_TOKEN }} + dump-logs: true - name: Create a model, deploy an application and run juju status run: | @@ -50,6 +54,22 @@ jobs: - name: Build run: yarn build - name: Configure - run: sed -i -e 's/controllerAPIEndpoint\:\ \"\"/controllerAPIEndpoint:\ "ws:\/\/jimm.localhost\/api"/g' build/config.js - - name: Start - run: npx http-server build --port 8000 & + run: | + sed -i -e 's/controllerAPIEndpoint\:\ \"\"/controllerAPIEndpoint:\ "wss:\/\/jimm.localhost\/api"/g' build/config.js + sed -i -e 's/analyticsEnabled\:\ true/analyticsEnabled:\ false/g' build/config.js + - name: Install Playwright Browsers + run: yarn playwright install --with-deps + - name: Run Playwright tests + run: yarn playwright test + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: test-results + path: test-results/ + retention-days: 1 + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + if: false + timeout-minutes: 15 + with: + limit-access-to-actor: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fed8eda26..164194f28 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,6 +8,7 @@ on: - main jobs: test: + if: false name: Test runs-on: ubuntu-latest permissions: diff --git a/.github/workflows/tics-coverage.yml b/.github/workflows/tics-coverage.yml index 23d0d24ec..58729cfe9 100644 --- a/.github/workflows/tics-coverage.yml +++ b/.github/workflows/tics-coverage.yml @@ -5,6 +5,7 @@ on: jobs: TICS: + if: false runs-on: ubuntu-latest strategy: matrix: diff --git a/.gitignore b/.gitignore index aad4b29c7..0c8a8ed53 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,9 @@ public/config.local.js .env.local .env.*.local + +# Playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/e2e/example.spec.ts b/e2e/example.spec.ts new file mode 100644 index 000000000..37c8a8b46 --- /dev/null +++ b/e2e/example.spec.ts @@ -0,0 +1,22 @@ +import { test, expect } from "@playwright/test"; + +test("Log in", async ({ page }) => { + test.setTimeout(30_000); + page.on("request", (request) => { + console.log("request url: ", request.url()); + }); + page.on("response", (response) => { + console.log("response url: ", response.url()); + }); + await page.goto("/"); + await page.getByRole("link", { name: "Log in to the dashboard" }).click(); + await page + .getByRole("textbox", { name: "Username or email" }) + .fill("jimm-test"); + await page.getByRole("textbox", { name: "Password" }).fill("password"); + await page.getByRole("button", { name: "Sign In" }).click(); + await page.waitForURL("http://127.0.0.1:8000/"); + await expect(page.getByRole("link", { name: "Models" })).toBeVisible({ + timeout: 30_000, + }); +}); diff --git a/package.json b/package.json index dbabc6d01..1c82def5b 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ "@eslint/compat": "1.2.6", "@eslint/eslintrc": "3.2.0", "@eslint/js": "9.20.0", + "@playwright/test": "^1.50.1", "@testing-library/dom": "10.4.0", "@testing-library/jest-dom": "6.6.3", "@testing-library/react": "16.2.0", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 000000000..d1108c66a --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,71 @@ +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: "./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: "list", + /* 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://127.0.0.1:8000", + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: "on-first-retry", + screenshot: "on", + ignoreHTTPSErrors: true, + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: "chromium", + use: { ...devices["Desktop Chrome"] }, + }, + + /* 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: "npx http-server build --port 8000", + url: "http://127.0.0.1:8000", + reuseExistingServer: !process.env.CI, + }, +}); diff --git a/src/juju/api.ts b/src/juju/api.ts index 36cf5e4b6..7804c49e0 100644 --- a/src/juju/api.ts +++ b/src/juju/api.ts @@ -99,7 +99,7 @@ export function generateConnectionOptions( return { bakery, closeCallback: onClose, - debug: false, + debug: true, facades, oidcEnabled: authMethod === AuthMethod.OIDC, wsclass: WebSocket, diff --git a/yarn.lock b/yarn.lock index 93ef5c23e..d0f157fe1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -797,6 +797,17 @@ __metadata: languageName: node linkType: hard +"@playwright/test@npm:^1.50.1": + version: 1.50.1 + resolution: "@playwright/test@npm:1.50.1" + dependencies: + playwright: "npm:1.50.1" + bin: + playwright: cli.js + checksum: 10c0/77c1a7cfaca7b3b88804256bb4c0e15c54b8df02690298086ef4a4fc8c2a42b99b69ba1b83906d00cc7ddb322ce8b2f19f0238f189913607c679779a4d132da1 + languageName: node + linkType: hard + "@reduxjs/toolkit@npm:2.5.1": version: 2.5.1 resolution: "@reduxjs/toolkit@npm:2.5.1" @@ -5635,7 +5646,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:~2.3.2": +"fsevents@npm:2.3.2, fsevents@npm:~2.3.2": version: 2.3.2 resolution: "fsevents@npm:2.3.2" dependencies: @@ -5655,7 +5666,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": +"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": version: 2.3.2 resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" dependencies: @@ -7472,6 +7483,7 @@ __metadata: "@eslint/compat": "npm:1.2.6" "@eslint/eslintrc": "npm:3.2.0" "@eslint/js": "npm:9.20.0" + "@playwright/test": "npm:^1.50.1" "@reduxjs/toolkit": "npm:2.5.1" "@sentry/browser": "npm:9.1.0" "@sentry/core": "npm:9.1.0" @@ -8826,6 +8838,30 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.50.1": + version: 1.50.1 + resolution: "playwright-core@npm:1.50.1" + bin: + playwright-core: cli.js + checksum: 10c0/c158764257d870897c31807a830ddcc3f5aaf4376719e05aeada3489a01f751650b2dc43e027201a40405a1b075084e89f58cd3730a985a229efe9d8cecfe360 + languageName: node + linkType: hard + +"playwright@npm:1.50.1": + version: 1.50.1 + resolution: "playwright@npm:1.50.1" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.50.1" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 10c0/b292ee6e0d122748a3d024b85ace86a0d9c848fc4121685d90ffc5d43d6bcf13ed7dc7488b1055f69040599c420052306ccba6fabfe2f69a15fc109c55171207 + languageName: node + linkType: hard + "plur@npm:^4.0.0": version: 4.0.0 resolution: "plur@npm:4.0.0"