From e1ca5af5b4b409f8fc727ac22ab972ae0d977cba Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Fri, 3 Oct 2025 16:51:14 +0200 Subject: [PATCH 01/11] chore: setup (e2e) tests --- .gitignore | 9 +- juno.config.ts | 30 +++++++ package-lock.json | 117 ++++++++++++++++++++++++++ package.json | 9 +- playwright.config.ts | 36 ++++++++ tests/constants/test-ids.constants.ts | 18 ++++ tests/create-website.spec.ts | 19 +++++ tests/page-objects/console.page.ts | 67 +++++++++++++++ tests/page-objects/identity.page.ts | 25 ++++++ tests/types/test-id.ts | 9 ++ tests/utils/init.utils.ts | 35 ++++++++ 11 files changed, 372 insertions(+), 2 deletions(-) create mode 100644 juno.config.ts create mode 100644 playwright.config.ts create mode 100644 tests/constants/test-ids.constants.ts create mode 100644 tests/create-website.spec.ts create mode 100644 tests/page-objects/console.page.ts create mode 100644 tests/page-objects/identity.page.ts create mode 100644 tests/types/test-id.ts create mode 100644 tests/utils/init.utils.ts diff --git a/.gitignore b/.gitignore index a5e8695b..f58e1354 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,11 @@ dist/ target/ templates/eject/rust/Cargo.lock templates/eject/rust/src/declarations -templates/eject/rust/src/satellite/satellite_extension.did \ No newline at end of file +templates/eject/rust/src/satellite/satellite_extension.did + +# Playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ +/playwright/.auth/ diff --git a/juno.config.ts b/juno.config.ts new file mode 100644 index 00000000..c1351b0b --- /dev/null +++ b/juno.config.ts @@ -0,0 +1,30 @@ +import {defineConfig} from '@junobuild/config'; + +export default defineConfig({ + satellite: { + ids: { + development: 'jx5yt-yyaaa-aaaal-abzbq-cai', + production: '' + }, + source: 'build', + predeploy: ['npm run build'], + collections: { + datastore: [ + { + collection: 'notes', + read: 'managed', + write: 'managed', + memory: 'stable' + } + ], + storage: [ + { + collection: 'images', + read: 'managed', + write: 'managed', + memory: 'stable' + } + ] + } + } +}); diff --git a/package-lock.json b/package-lock.json index f9eb0e21..9f34f70b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,9 +41,11 @@ "juno": "dist/index.js" }, "devDependencies": { + "@dfinity/internet-identity-playwright": "^2.0.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "^9.36.0", "@junobuild/functions": "^0.3.3", + "@playwright/test": "^1.55.1", "@types/node": "^24.5.2", "@types/prompts": "^2.4.9", "@types/semver": "^7.7.1", @@ -639,6 +641,19 @@ "@noble/hashes": "^1.8.0" } }, + "node_modules/@dfinity/internet-identity-playwright": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@dfinity/internet-identity-playwright/-/internet-identity-playwright-2.0.0.tgz", + "integrity": "sha512-8dqxxKEqNhM+dozEHFB3Dn54lXsFMjuDKy4qT4ALWypWDM61Ey1KFfvI34gyn70xWLLTLxEiWb6CrDnzJu3NGQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=22" + }, + "peerDependencies": { + "@playwright/test": "^1.52.0" + } + }, "node_modules/@dfinity/principal": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-3.2.6.tgz", @@ -1670,6 +1685,22 @@ "node": ">= 8" } }, + "node_modules/@playwright/test": { + "version": "1.55.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.55.1.tgz", + "integrity": "sha512-IVAh/nOJaw6W9g+RJVlIQJ6gSiER+ae6mKQ5CX1bERzQgbC1VSeBlwdvczT7pxb0GWiyrxH4TGKbMfDb4Sq/ig==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.55.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -3797,6 +3828,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5242,6 +5288,38 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/playwright": { + "version": "1.55.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.55.1.tgz", + "integrity": "sha512-cJW4Xd/G3v5ovXtJJ52MAOclqeac9S/aGGgRzLabuF8TnIb6xHvMzKIa6JmrRzUkeXJgfL1MhukP0NK6l39h3A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.55.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.55.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.55.1.tgz", + "integrity": "sha512-Z6Mh9mkwX+zxSlHqdr5AOcJnfp+xUWLCt9uKV18fhzA8eyxUd8NUWzAjxUh55RZKSYwDGX0cfaySdhZJGMoJ+w==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/portfinder": { "version": "1.0.38", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.38.tgz", @@ -6866,6 +6944,13 @@ "integrity": "sha512-18ecTwtz4Yv8coaNM4ooCzqlib9ooP20JFHJ2RVAtlWPaVcRC/4nzXTEJiUH+TytC7ZbBkuRYlJ/eLeIhyYqaA==", "requires": {} }, + "@dfinity/internet-identity-playwright": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@dfinity/internet-identity-playwright/-/internet-identity-playwright-2.0.0.tgz", + "integrity": "sha512-8dqxxKEqNhM+dozEHFB3Dn54lXsFMjuDKy4qT4ALWypWDM61Ey1KFfvI34gyn70xWLLTLxEiWb6CrDnzJu3NGQ==", + "dev": true, + "requires": {} + }, "@dfinity/principal": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-3.2.6.tgz", @@ -7400,6 +7485,15 @@ "fastq": "^1.6.0" } }, + "@playwright/test": { + "version": "1.55.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.55.1.tgz", + "integrity": "sha512-IVAh/nOJaw6W9g+RJVlIQJ6gSiER+ae6mKQ5CX1bERzQgbC1VSeBlwdvczT7pxb0GWiyrxH4TGKbMfDb4Sq/ig==", + "dev": true, + "requires": { + "playwright": "1.55.1" + } + }, "@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -8790,6 +8884,13 @@ "is-callable": "^1.2.7" } }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -9681,6 +9782,22 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "playwright": { + "version": "1.55.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.55.1.tgz", + "integrity": "sha512-cJW4Xd/G3v5ovXtJJ52MAOclqeac9S/aGGgRzLabuF8TnIb6xHvMzKIa6JmrRzUkeXJgfL1MhukP0NK6l39h3A==", + "dev": true, + "requires": { + "fsevents": "2.3.2", + "playwright-core": "1.55.1" + } + }, + "playwright-core": { + "version": "1.55.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.55.1.tgz", + "integrity": "sha512-Z6Mh9mkwX+zxSlHqdr5AOcJnfp+xUWLCt9uKV18fhzA8eyxUd8NUWzAjxUh55RZKSYwDGX0cfaySdhZJGMoJ+w==", + "dev": true + }, "portfinder": { "version": "1.0.38", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.38.tgz", diff --git a/package.json b/package.json index ad38b942..c471e64e 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,12 @@ "format:check": "prettier --check .", "build": "tsc --noEmit && node ./scripts/rmdir.mjs && node ./scripts/esbuild.mjs", "lint": "eslint --max-warnings 0 \"src/**/*\"", - "prepublishOnly": "./scripts/prepublish.sh" + "prepublishOnly": "./scripts/prepublish.sh", + "test": "NODE_ENV=development playwright test", + "test:ci": "playwright test --reporter=html", + "test:snapshots": "playwright test --update-snapshots --reporter=list", + "test:report": "playwright show-report", + "test:playwright:install": "playwright install chromium --with-deps" }, "dependencies": { "@dfinity/agent": "^3.2.6", @@ -52,9 +57,11 @@ "zod": "^4.1.11" }, "devDependencies": { + "@dfinity/internet-identity-playwright": "^2.0.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "^9.36.0", "@junobuild/functions": "^0.3.3", + "@playwright/test": "^1.55.1", "@types/node": "^24.5.2", "@types/prompts": "^2.4.9", "@types/semver": "^7.7.1", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000..7486d85c --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,36 @@ +import {defineConfig, devices} from '@playwright/test'; + +const DEV = (process.env.NODE_ENV ?? 'production') === 'development'; + +export default defineConfig({ + testDir: './tests', + snapshotDir: `./${DEV ? 'tmp' : 'src'}/e2e/snapshots`, + testMatch: ['**/*.e2e.ts', '**/*.spec.ts'], + fullyParallel: true, + forbidOnly: !!process.env.CI, + workers: process.env.CI ? 1 : undefined, + expect: { + toHaveScreenshot: { + animations: 'disabled', + caret: 'hide' + } + }, + webServer: { + command: 'npm run build', + url: 'http://localhost:5866', + reuseExistingServer: DEV, + timeout: 120 * 1000 + }, + use: { + testIdAttribute: 'data-tid', + baseURL: 'http://localhost:5866', + trace: 'on', + ...(DEV && {headless: false}) + }, + projects: [ + { + name: 'chromium', + use: {...devices['Desktop Chrome']} + } + ] +}); diff --git a/tests/constants/test-ids.constants.ts b/tests/constants/test-ids.constants.ts new file mode 100644 index 00000000..e53ed29e --- /dev/null +++ b/tests/constants/test-ids.constants.ts @@ -0,0 +1,18 @@ +import {TestIds} from '../types/test-id'; + +export const testIds: TestIds = { + auth: { + signIn: 'btn-sign-in' + }, + createSatellite: { + launch: 'btn-launch-satellite', + create: 'btn-create-satellite', + input: 'input-satellite-name', + website: 'input-radio-satellite-website', + application: 'input-radio-satellite-application', + continue: 'btn-continue-overview' + }, + satelliteOverview: { + visit: 'link-visit-satellite' + } +}; diff --git a/tests/create-website.spec.ts b/tests/create-website.spec.ts new file mode 100644 index 00000000..f411a845 --- /dev/null +++ b/tests/create-website.spec.ts @@ -0,0 +1,19 @@ +import {testWithII} from '@dfinity/internet-identity-playwright'; +import {expect} from '@playwright/test'; +import {initTestSuite} from './utils/init.utils'; + +const getConsolePage = initTestSuite(); + +testWithII('should create a satellite for a website', async () => { + const consolePage = getConsolePage(); + + await consolePage.createSatellite({kind: 'website'}); +}); + +testWithII('should visit newly create satellite', async () => { + const consolePage = getConsolePage(); + + const satellitePage = await consolePage.visitSatellite(); + + await expect(satellitePage).toHaveScreenshot({fullPage: true}); +}); diff --git a/tests/page-objects/console.page.ts b/tests/page-objects/console.page.ts new file mode 100644 index 00000000..7747d8b7 --- /dev/null +++ b/tests/page-objects/console.page.ts @@ -0,0 +1,67 @@ +import {InternetIdentityPage} from '@dfinity/internet-identity-playwright'; +import {expect} from '@playwright/test'; +import type {Page} from 'playwright-core'; +import {testIds} from '../constants/test-ids.constants'; +import {IdentityPage, type IdentityPageParams} from './identity.page'; + +export class ConsolePage extends IdentityPage { + readonly #consoleIIPage: InternetIdentityPage; + + constructor(params: IdentityPageParams) { + super(params); + + this.#consoleIIPage = new InternetIdentityPage({ + page: this.page, + context: this.context, + browser: this.browser + }); + } + + async goto(): Promise { + await this.page.goto('/'); + } + + async signIn(): Promise { + this.identity = await this.#consoleIIPage.signInWithNewIdentity({ + selector: `[data-tid=${testIds.auth.signIn}]` + }); + } + + async waitReady(): Promise { + const CONTAINER_URL = 'http://127.0.0.1:5987'; + const INTERNET_IDENTITY_ID = 'rdmx6-jaaaa-aaaaa-aaadq-cai'; + + await this.#consoleIIPage.waitReady({url: CONTAINER_URL, canisterId: INTERNET_IDENTITY_ID}); + } + + async createSatellite({kind}: {kind: 'website' | 'application'}): Promise { + await expect(this.page.getByTestId(testIds.createSatellite.launch)).toBeVisible(); + + await this.page.getByTestId(testIds.createSatellite.launch).click(); + + await expect(this.page.getByTestId(testIds.createSatellite.create)).toBeVisible(); + + await this.page.getByTestId(testIds.createSatellite.input).fill('Test'); + await this.page.getByTestId(testIds.createSatellite[kind]).click(); + + await this.page.getByTestId(testIds.createSatellite.create).click(); + + await expect(this.page.getByTestId(testIds.createSatellite.continue)).toBeVisible(); + + await this.page.getByTestId(testIds.createSatellite.continue).click(); + } + + async visitSatellite(): Promise { + await expect(this.page.getByTestId(testIds.satelliteOverview.visit)).toBeVisible(); + + const satellitePagePromise = this.context.waitForEvent('page'); + + await this.page.getByTestId(testIds.satelliteOverview.visit).click(); + + const satellitePage = await satellitePagePromise; + + await expect(satellitePage).toHaveTitle('Juno / Satellite'); + + return satellitePage; + } +} diff --git a/tests/page-objects/identity.page.ts b/tests/page-objects/identity.page.ts new file mode 100644 index 00000000..5bfa9162 --- /dev/null +++ b/tests/page-objects/identity.page.ts @@ -0,0 +1,25 @@ +import type {Browser, BrowserContext, Page} from '@playwright/test'; + +export interface IdentityPageParams { + page: Page; + context: BrowserContext; + browser: Browser; +} + +export abstract class IdentityPage { + protected identity: number | undefined; + + protected readonly page: Page; + protected readonly context: BrowserContext; + protected readonly browser: Browser; + + protected constructor({page, context, browser}: IdentityPageParams) { + this.page = page; + this.context = context; + this.browser = browser; + } + + async close(): Promise { + await this.page.close(); + } +} diff --git a/tests/types/test-id.ts b/tests/types/test-id.ts new file mode 100644 index 00000000..b0998cde --- /dev/null +++ b/tests/types/test-id.ts @@ -0,0 +1,9 @@ +type TestCTAType = 'btn' | 'link' | 'input'; + +type TestAction = string; + +export type TestId = `${TestCTAType}-${TestAction}`; + +type TestSuite = string; + +export type TestIds = Record>; diff --git a/tests/utils/init.utils.ts b/tests/utils/init.utils.ts new file mode 100644 index 00000000..91a33410 --- /dev/null +++ b/tests/utils/init.utils.ts @@ -0,0 +1,35 @@ +import {testWithII} from '@dfinity/internet-identity-playwright'; +import {ConsolePage} from '../page-objects/console.page'; + +export const initTestSuite = (): (() => ConsolePage) => { + testWithII.describe.configure({mode: 'serial'}); + + let consolePage: ConsolePage; + + testWithII.beforeAll(async ({playwright}) => { + testWithII.setTimeout(120000); + + const browser = await playwright.chromium.launch(); + + const context = await browser.newContext(); + const page = await context.newPage(); + + consolePage = new ConsolePage({ + page, + context, + browser + }); + + await consolePage.waitReady(); + + await consolePage.goto(); + + await consolePage.signIn(); + }); + + testWithII.afterAll(async () => { + await consolePage.close(); + }); + + return (): ConsolePage => consolePage; +}; From 632eae69dc198ed2aeeddfd1ec1b422cb6320fc8 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Fri, 3 Oct 2025 17:16:09 +0200 Subject: [PATCH 02/11] chore: run tests in CI --- .github/actions/setup-tests-env/action.yml | 27 ++++++++++++++ .github/workflows/tests-screenshots.yml | 28 ++++++++++++++ .github/workflows/tests.yml | 43 ++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 .github/actions/setup-tests-env/action.yml create mode 100644 .github/workflows/tests-screenshots.yml create mode 100644 .github/workflows/tests.yml diff --git a/.github/actions/setup-tests-env/action.yml b/.github/actions/setup-tests-env/action.yml new file mode 100644 index 00000000..9e875480 --- /dev/null +++ b/.github/actions/setup-tests-env/action.yml @@ -0,0 +1,27 @@ +name: Setup Tests Environment + +description: Build the CLI and caches Docker layers + +runs: + using: 'composite' + steps: + - name: Build the CLI + run: npm run build + shell: bash + + - name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /home/runner/.docker + key: ${{ runner.os }}-docker-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-docker- + + - name: Run emulator + shell: bash + run: | + set -e + juno emulator start --headless & + juno emulator wait + juno login --emulator --mode development --headless + juno config apply --mode development --headless diff --git a/.github/workflows/tests-screenshots.yml b/.github/workflows/tests-screenshots.yml new file mode 100644 index 00000000..7212e9de --- /dev/null +++ b/.github/workflows/tests-screenshots.yml @@ -0,0 +1,28 @@ +name: Update E2E Screenshots + +on: + workflow_dispatch: + +jobs: + tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Prepare + uses: ./.github/actions/prepare + - name: Setup Tests Environment + uses: ./.github/actions/setup-tests-env + + - name: Run Playwright tests + run: npm run e2e:snapshots + + - name: Commit Playwright updated screenshots + uses: EndBug/add-and-commit@v9 + if: ${{ github.ref != 'refs/heads/main' }} + with: + add: ./src/tests + default_author: github_actions + message: '🤖 update tests screenshots' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..1f6b0899 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,43 @@ +name: Tests + +on: + pull_request: + workflow_dispatch: + +jobs: + tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Prepare + uses: ./.github/actions/prepare + - name: Setup Tests Environment + uses: ./.github/actions/setup-tests-env + + - name: Run tests + run: npm run e2e:ci + + - name: Upload Playwright report on failure + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: playwright-report + path: playwright-report/ + retention-days: 3 + - name: Upload Playwright results on failure + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: test-results + path: test-results/ + retention-days: 3 + + may-merge: + needs: ['tests'] + runs-on: ubuntu-latest + steps: + - name: Cleared for merging + run: echo OK From 5441a4f8c5d2e9190a6b35047248cbd2513762c8 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Fri, 3 Oct 2025 17:22:30 +0200 Subject: [PATCH 03/11] chore: link CLI globally for running juno cmd in CI --- .github/actions/setup-tests-env/action.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/actions/setup-tests-env/action.yml b/.github/actions/setup-tests-env/action.yml index 9e875480..e0b1c716 100644 --- a/.github/actions/setup-tests-env/action.yml +++ b/.github/actions/setup-tests-env/action.yml @@ -9,6 +9,10 @@ runs: run: npm run build shell: bash + - name: Link CLI globally + run: npm link + shell: bash + - name: Cache Docker layers uses: actions/cache@v3 with: From 2187c0a98c33d6b6c18b3f1927c197d9600a2d68 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sat, 4 Oct 2025 08:43:50 +0200 Subject: [PATCH 04/11] fix: emulator config to be tested --- .github/actions/setup-tests-env/action.yml | 2 -- juno.config.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/actions/setup-tests-env/action.yml b/.github/actions/setup-tests-env/action.yml index e0b1c716..1689321a 100644 --- a/.github/actions/setup-tests-env/action.yml +++ b/.github/actions/setup-tests-env/action.yml @@ -27,5 +27,3 @@ runs: set -e juno emulator start --headless & juno emulator wait - juno login --emulator --mode development --headless - juno config apply --mode development --headless diff --git a/juno.config.ts b/juno.config.ts index c1351b0b..90cddcb0 100644 --- a/juno.config.ts +++ b/juno.config.ts @@ -3,7 +3,7 @@ import {defineConfig} from '@junobuild/config'; export default defineConfig({ satellite: { ids: { - development: 'jx5yt-yyaaa-aaaal-abzbq-cai', + development: '', production: '' }, source: 'build', From 612988023bc40c8f4eda3697220820a67a31ea25 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sat, 4 Oct 2025 08:46:15 +0200 Subject: [PATCH 05/11] feat: rename into e2e --- .../{setup-tests-env => setup-e2e-env}/action.yml | 2 +- .github/workflows/tests-screenshots.yml | 2 +- .github/workflows/tests.yml | 8 ++++---- package.json | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) rename .github/actions/{setup-tests-env => setup-e2e-env}/action.yml (95%) diff --git a/.github/actions/setup-tests-env/action.yml b/.github/actions/setup-e2e-env/action.yml similarity index 95% rename from .github/actions/setup-tests-env/action.yml rename to .github/actions/setup-e2e-env/action.yml index 1689321a..a5aa6328 100644 --- a/.github/actions/setup-tests-env/action.yml +++ b/.github/actions/setup-e2e-env/action.yml @@ -1,4 +1,4 @@ -name: Setup Tests Environment +name: Setup E2E Environment description: Build the CLI and caches Docker layers diff --git a/.github/workflows/tests-screenshots.yml b/.github/workflows/tests-screenshots.yml index 7212e9de..f1547f8b 100644 --- a/.github/workflows/tests-screenshots.yml +++ b/.github/workflows/tests-screenshots.yml @@ -14,7 +14,7 @@ jobs: - name: Prepare uses: ./.github/actions/prepare - name: Setup Tests Environment - uses: ./.github/actions/setup-tests-env + uses: ./.github/actions/setup-e2e-env - name: Run Playwright tests run: npm run e2e:snapshots diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1f6b0899..307697f8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,11 +1,11 @@ -name: Tests +name: E2E Tests on: pull_request: workflow_dispatch: jobs: - tests: + e2e: runs-on: ubuntu-latest steps: @@ -15,7 +15,7 @@ jobs: - name: Prepare uses: ./.github/actions/prepare - name: Setup Tests Environment - uses: ./.github/actions/setup-tests-env + uses: ./.github/actions/setup-e2e-env - name: Run tests run: npm run e2e:ci @@ -36,7 +36,7 @@ jobs: retention-days: 3 may-merge: - needs: ['tests'] + needs: ['e2e'] runs-on: ubuntu-latest steps: - name: Cleared for merging diff --git a/package.json b/package.json index c471e64e..8e68863b 100644 --- a/package.json +++ b/package.json @@ -21,11 +21,11 @@ "build": "tsc --noEmit && node ./scripts/rmdir.mjs && node ./scripts/esbuild.mjs", "lint": "eslint --max-warnings 0 \"src/**/*\"", "prepublishOnly": "./scripts/prepublish.sh", - "test": "NODE_ENV=development playwright test", - "test:ci": "playwright test --reporter=html", - "test:snapshots": "playwright test --update-snapshots --reporter=list", - "test:report": "playwright show-report", - "test:playwright:install": "playwright install chromium --with-deps" + "e2e": "NODE_ENV=development playwright test", + "e2e:ci": "playwright test --reporter=html", + "e2e:snapshots": "playwright test --update-snapshots --reporter=list", + "e2e:report": "playwright show-report", + "e2e:playwright:install": "playwright install chromium --with-deps" }, "dependencies": { "@dfinity/agent": "^3.2.6", From e9ea30308ec45c0d0bd15dcdf23f9a85dbe1e45f Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sat, 4 Oct 2025 08:50:42 +0200 Subject: [PATCH 06/11] feat: do not star a web server --- playwright.config.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index 7486d85c..6b10b650 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -15,12 +15,6 @@ export default defineConfig({ caret: 'hide' } }, - webServer: { - command: 'npm run build', - url: 'http://localhost:5866', - reuseExistingServer: DEV, - timeout: 120 * 1000 - }, use: { testIdAttribute: 'data-tid', baseURL: 'http://localhost:5866', From 7d7bc54c5dd0f4ef829b98b25ba9979254c254e1 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sat, 4 Oct 2025 08:54:01 +0200 Subject: [PATCH 07/11] chore: test --- playwright.config.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/playwright.config.ts b/playwright.config.ts index 6b10b650..6abe175a 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -15,6 +15,12 @@ export default defineConfig({ caret: 'hide' } }, + webServer: { + command: 'npm run build', + url: 'http://localhost:5866', + reuseExistingServer: true, + timeout: 120 * 1000 + }, use: { testIdAttribute: 'data-tid', baseURL: 'http://localhost:5866', From 0bbe226e1e92c667c295e4ce2d550201ff29ada4 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sat, 4 Oct 2025 08:59:05 +0200 Subject: [PATCH 08/11] chore: redo --- playwright.config.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index 6abe175a..6b10b650 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -15,12 +15,6 @@ export default defineConfig({ caret: 'hide' } }, - webServer: { - command: 'npm run build', - url: 'http://localhost:5866', - reuseExistingServer: true, - timeout: 120 * 1000 - }, use: { testIdAttribute: 'data-tid', baseURL: 'http://localhost:5866', From f6311f6a4b46b1d207e20fc5e999f7f0ab0b63f8 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sat, 4 Oct 2025 08:59:14 +0200 Subject: [PATCH 09/11] fix: install chrome --- .github/workflows/tests-screenshots.yml | 4 ++++ .github/workflows/tests.yml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/.github/workflows/tests-screenshots.yml b/.github/workflows/tests-screenshots.yml index f1547f8b..5d6c6801 100644 --- a/.github/workflows/tests-screenshots.yml +++ b/.github/workflows/tests-screenshots.yml @@ -13,6 +13,10 @@ jobs: - name: Prepare uses: ./.github/actions/prepare + + - name: Prepare Playwright + run: npm run e2e:playwright:install + - name: Setup Tests Environment uses: ./.github/actions/setup-e2e-env diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 307697f8..a67d23ab 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,6 +14,10 @@ jobs: - name: Prepare uses: ./.github/actions/prepare + + - name: Prepare Playwright + run: npm run e2e:playwright:install + - name: Setup Tests Environment uses: ./.github/actions/setup-e2e-env From 0bba4ac8ca75df06f622825827793561be85947a Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sat, 4 Oct 2025 09:06:39 +0200 Subject: [PATCH 10/11] feat: wait for visibility --- tests/page-objects/console.page.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/page-objects/console.page.ts b/tests/page-objects/console.page.ts index 7747d8b7..842acdd0 100644 --- a/tests/page-objects/console.page.ts +++ b/tests/page-objects/console.page.ts @@ -46,7 +46,9 @@ export class ConsolePage extends IdentityPage { await this.page.getByTestId(testIds.createSatellite.create).click(); - await expect(this.page.getByTestId(testIds.createSatellite.continue)).toBeVisible(); + await expect(this.page.getByTestId(testIds.createSatellite.continue)).toBeVisible({ + timeout: 20000 + }); await this.page.getByTestId(testIds.createSatellite.continue).click(); } From eb2fe3f0fa9943083724eba10062dcb5b72d565c Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sat, 4 Oct 2025 09:07:59 +0200 Subject: [PATCH 11/11] feat: rename to e2e --- .github/workflows/tests-screenshots.yml | 2 +- {tests => e2e}/constants/test-ids.constants.ts | 0 {tests => e2e}/create-website.spec.ts | 0 {tests => e2e}/page-objects/console.page.ts | 0 {tests => e2e}/page-objects/identity.page.ts | 0 {tests => e2e}/types/test-id.ts | 0 {tests => e2e}/utils/init.utils.ts | 0 playwright.config.ts | 4 ++-- 8 files changed, 3 insertions(+), 3 deletions(-) rename {tests => e2e}/constants/test-ids.constants.ts (100%) rename {tests => e2e}/create-website.spec.ts (100%) rename {tests => e2e}/page-objects/console.page.ts (100%) rename {tests => e2e}/page-objects/identity.page.ts (100%) rename {tests => e2e}/types/test-id.ts (100%) rename {tests => e2e}/utils/init.utils.ts (100%) diff --git a/.github/workflows/tests-screenshots.yml b/.github/workflows/tests-screenshots.yml index 5d6c6801..768feabc 100644 --- a/.github/workflows/tests-screenshots.yml +++ b/.github/workflows/tests-screenshots.yml @@ -27,6 +27,6 @@ jobs: uses: EndBug/add-and-commit@v9 if: ${{ github.ref != 'refs/heads/main' }} with: - add: ./src/tests + add: ./e2e default_author: github_actions message: '🤖 update tests screenshots' diff --git a/tests/constants/test-ids.constants.ts b/e2e/constants/test-ids.constants.ts similarity index 100% rename from tests/constants/test-ids.constants.ts rename to e2e/constants/test-ids.constants.ts diff --git a/tests/create-website.spec.ts b/e2e/create-website.spec.ts similarity index 100% rename from tests/create-website.spec.ts rename to e2e/create-website.spec.ts diff --git a/tests/page-objects/console.page.ts b/e2e/page-objects/console.page.ts similarity index 100% rename from tests/page-objects/console.page.ts rename to e2e/page-objects/console.page.ts diff --git a/tests/page-objects/identity.page.ts b/e2e/page-objects/identity.page.ts similarity index 100% rename from tests/page-objects/identity.page.ts rename to e2e/page-objects/identity.page.ts diff --git a/tests/types/test-id.ts b/e2e/types/test-id.ts similarity index 100% rename from tests/types/test-id.ts rename to e2e/types/test-id.ts diff --git a/tests/utils/init.utils.ts b/e2e/utils/init.utils.ts similarity index 100% rename from tests/utils/init.utils.ts rename to e2e/utils/init.utils.ts diff --git a/playwright.config.ts b/playwright.config.ts index 6b10b650..a6ded49c 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -3,8 +3,8 @@ import {defineConfig, devices} from '@playwright/test'; const DEV = (process.env.NODE_ENV ?? 'production') === 'development'; export default defineConfig({ - testDir: './tests', - snapshotDir: `./${DEV ? 'tmp' : 'src'}/e2e/snapshots`, + testDir: './e2e', + snapshotDir: `./${DEV ? 'tmp' : 'e2e'}/snapshots`, testMatch: ['**/*.e2e.ts', '**/*.spec.ts'], fullyParallel: true, forbidOnly: !!process.env.CI,