diff --git a/e2e/__screenshots__/angular-example/production/example.spec.ts/entries-current-mode.png b/e2e/__screenshots__/angular-example/production/example.spec.ts/entries-current-mode.png new file mode 100644 index 00000000..37b502cb Binary files /dev/null and b/e2e/__screenshots__/angular-example/production/example.spec.ts/entries-current-mode.png differ diff --git a/e2e/__screenshots__/angular-example/production/example.spec.ts/logged-in-current-mode.png b/e2e/__screenshots__/angular-example/production/example.spec.ts/logged-in-current-mode.png index 1ee25699..c6ad68e1 100644 Binary files a/e2e/__screenshots__/angular-example/production/example.spec.ts/logged-in-current-mode.png and b/e2e/__screenshots__/angular-example/production/example.spec.ts/logged-in-current-mode.png differ diff --git a/e2e/__screenshots__/angular-example/production/example.spec.ts/login-current-mode.png b/e2e/__screenshots__/angular-example/production/example.spec.ts/login-current-mode.png index 451709d9..56d5beb7 100644 Binary files a/e2e/__screenshots__/angular-example/production/example.spec.ts/login-current-mode.png and b/e2e/__screenshots__/angular-example/production/example.spec.ts/login-current-mode.png differ diff --git a/e2e/__screenshots__/angular-example/production/example.spec.ts/logout-current-mode.png b/e2e/__screenshots__/angular-example/production/example.spec.ts/logout-current-mode.png index 451709d9..56d5beb7 100644 Binary files a/e2e/__screenshots__/angular-example/production/example.spec.ts/logout-current-mode.png and b/e2e/__screenshots__/angular-example/production/example.spec.ts/logout-current-mode.png differ diff --git a/e2e/__screenshots__/angular-example/production/example.spec.ts/modal-current-mode.png b/e2e/__screenshots__/angular-example/production/example.spec.ts/modal-current-mode.png index 85d7cc90..12df5246 100644 Binary files a/e2e/__screenshots__/angular-example/production/example.spec.ts/modal-current-mode.png and b/e2e/__screenshots__/angular-example/production/example.spec.ts/modal-current-mode.png differ diff --git a/e2e/__screenshots__/nextjs-example/production/example.spec.ts/entries-current-mode.png b/e2e/__screenshots__/nextjs-example/production/example.spec.ts/entries-current-mode.png new file mode 100644 index 00000000..a042039b Binary files /dev/null and b/e2e/__screenshots__/nextjs-example/production/example.spec.ts/entries-current-mode.png differ diff --git a/e2e/__screenshots__/nextjs-example/production/example.spec.ts/logged-in-current-mode.png b/e2e/__screenshots__/nextjs-example/production/example.spec.ts/logged-in-current-mode.png index 5eb06cd6..810bc785 100644 Binary files a/e2e/__screenshots__/nextjs-example/production/example.spec.ts/logged-in-current-mode.png and b/e2e/__screenshots__/nextjs-example/production/example.spec.ts/logged-in-current-mode.png differ diff --git a/e2e/__screenshots__/nextjs-example/production/example.spec.ts/login-current-mode.png b/e2e/__screenshots__/nextjs-example/production/example.spec.ts/login-current-mode.png index d8d96c48..aaca1a76 100644 Binary files a/e2e/__screenshots__/nextjs-example/production/example.spec.ts/login-current-mode.png and b/e2e/__screenshots__/nextjs-example/production/example.spec.ts/login-current-mode.png differ diff --git a/e2e/__screenshots__/nextjs-example/production/example.spec.ts/logout-current-mode.png b/e2e/__screenshots__/nextjs-example/production/example.spec.ts/logout-current-mode.png index d8d96c48..aaca1a76 100644 Binary files a/e2e/__screenshots__/nextjs-example/production/example.spec.ts/logout-current-mode.png and b/e2e/__screenshots__/nextjs-example/production/example.spec.ts/logout-current-mode.png differ diff --git a/e2e/__screenshots__/nextjs-example/production/example.spec.ts/modal-current-mode.png b/e2e/__screenshots__/nextjs-example/production/example.spec.ts/modal-current-mode.png index f0490fb7..40a580f9 100644 Binary files a/e2e/__screenshots__/nextjs-example/production/example.spec.ts/modal-current-mode.png and b/e2e/__screenshots__/nextjs-example/production/example.spec.ts/modal-current-mode.png differ diff --git a/e2e/__screenshots__/react-example/production/example.spec.ts/entries-current-mode.png b/e2e/__screenshots__/react-example/production/example.spec.ts/entries-current-mode.png new file mode 100644 index 00000000..b4688a9e Binary files /dev/null and b/e2e/__screenshots__/react-example/production/example.spec.ts/entries-current-mode.png differ diff --git a/e2e/__screenshots__/react-example/production/example.spec.ts/logged-in-current-mode.png b/e2e/__screenshots__/react-example/production/example.spec.ts/logged-in-current-mode.png index 83083260..78074be8 100644 Binary files a/e2e/__screenshots__/react-example/production/example.spec.ts/logged-in-current-mode.png and b/e2e/__screenshots__/react-example/production/example.spec.ts/logged-in-current-mode.png differ diff --git a/e2e/__screenshots__/react-example/production/example.spec.ts/login-current-mode.png b/e2e/__screenshots__/react-example/production/example.spec.ts/login-current-mode.png index 6e53d087..ec520fa9 100644 Binary files a/e2e/__screenshots__/react-example/production/example.spec.ts/login-current-mode.png and b/e2e/__screenshots__/react-example/production/example.spec.ts/login-current-mode.png differ diff --git a/e2e/__screenshots__/react-example/production/example.spec.ts/logout-current-mode.png b/e2e/__screenshots__/react-example/production/example.spec.ts/logout-current-mode.png index 6e53d087..ec520fa9 100644 Binary files a/e2e/__screenshots__/react-example/production/example.spec.ts/logout-current-mode.png and b/e2e/__screenshots__/react-example/production/example.spec.ts/logout-current-mode.png differ diff --git a/e2e/__screenshots__/react-example/production/example.spec.ts/modal-current-mode.png b/e2e/__screenshots__/react-example/production/example.spec.ts/modal-current-mode.png index 34c666f9..115565b7 100644 Binary files a/e2e/__screenshots__/react-example/production/example.spec.ts/modal-current-mode.png and b/e2e/__screenshots__/react-example/production/example.spec.ts/modal-current-mode.png differ diff --git a/e2e/__screenshots__/react-ts-example/production/example.spec.ts/entries-current-mode.png b/e2e/__screenshots__/react-ts-example/production/example.spec.ts/entries-current-mode.png new file mode 100644 index 00000000..1731e18c Binary files /dev/null and b/e2e/__screenshots__/react-ts-example/production/example.spec.ts/entries-current-mode.png differ diff --git a/e2e/__screenshots__/react-ts-example/production/example.spec.ts/logged-in-current-mode.png b/e2e/__screenshots__/react-ts-example/production/example.spec.ts/logged-in-current-mode.png index c8cdcfce..78074be8 100644 Binary files a/e2e/__screenshots__/react-ts-example/production/example.spec.ts/logged-in-current-mode.png and b/e2e/__screenshots__/react-ts-example/production/example.spec.ts/logged-in-current-mode.png differ diff --git a/e2e/__screenshots__/react-ts-example/production/example.spec.ts/login-current-mode.png b/e2e/__screenshots__/react-ts-example/production/example.spec.ts/login-current-mode.png index 6e53d087..ec520fa9 100644 Binary files a/e2e/__screenshots__/react-ts-example/production/example.spec.ts/login-current-mode.png and b/e2e/__screenshots__/react-ts-example/production/example.spec.ts/login-current-mode.png differ diff --git a/e2e/__screenshots__/react-ts-example/production/example.spec.ts/logout-current-mode.png b/e2e/__screenshots__/react-ts-example/production/example.spec.ts/logout-current-mode.png index 6e53d087..ec520fa9 100644 Binary files a/e2e/__screenshots__/react-ts-example/production/example.spec.ts/logout-current-mode.png and b/e2e/__screenshots__/react-ts-example/production/example.spec.ts/logout-current-mode.png differ diff --git a/e2e/__screenshots__/react-ts-example/production/example.spec.ts/modal-current-mode.png b/e2e/__screenshots__/react-ts-example/production/example.spec.ts/modal-current-mode.png index 34c666f9..115565b7 100644 Binary files a/e2e/__screenshots__/react-ts-example/production/example.spec.ts/modal-current-mode.png and b/e2e/__screenshots__/react-ts-example/production/example.spec.ts/modal-current-mode.png differ diff --git a/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/entries-current-mode.png b/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/entries-current-mode.png new file mode 100644 index 00000000..45bedece Binary files /dev/null and b/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/entries-current-mode.png differ diff --git a/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/logged-in-current-mode.png b/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/logged-in-current-mode.png index 72cad3d9..c6ad68e1 100644 Binary files a/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/logged-in-current-mode.png and b/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/logged-in-current-mode.png differ diff --git a/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/login-current-mode.png b/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/login-current-mode.png index c90b5508..56d5beb7 100644 Binary files a/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/login-current-mode.png and b/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/login-current-mode.png differ diff --git a/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/logout-current-mode.png b/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/logout-current-mode.png index c90b5508..56d5beb7 100644 Binary files a/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/logout-current-mode.png and b/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/logout-current-mode.png differ diff --git a/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/modal-current-mode.png b/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/modal-current-mode.png index 87ce34f1..bd66c547 100644 Binary files a/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/modal-current-mode.png and b/e2e/__screenshots__/sveltekit-example/production/example.spec.ts/modal-current-mode.png differ diff --git a/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/entries-current-mode.png b/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/entries-current-mode.png new file mode 100644 index 00000000..468c2f2f Binary files /dev/null and b/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/entries-current-mode.png differ diff --git a/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/logged-in-current-mode.png b/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/logged-in-current-mode.png index 0e5d330e..5cfb26a2 100644 Binary files a/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/logged-in-current-mode.png and b/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/logged-in-current-mode.png differ diff --git a/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/login-current-mode.png b/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/login-current-mode.png index fb6851f5..56d5beb7 100644 Binary files a/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/login-current-mode.png and b/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/login-current-mode.png differ diff --git a/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/logout-current-mode.png b/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/logout-current-mode.png index fb6851f5..56d5beb7 100644 Binary files a/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/logout-current-mode.png and b/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/logout-current-mode.png differ diff --git a/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/modal-current-mode.png b/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/modal-current-mode.png index 96a0a632..708f9ed0 100644 Binary files a/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/modal-current-mode.png and b/e2e/__screenshots__/vanilla-js-example/production/example.spec.ts/modal-current-mode.png differ diff --git a/e2e/__screenshots__/vue-example/production/example.spec.ts/entries-current-mode.png b/e2e/__screenshots__/vue-example/production/example.spec.ts/entries-current-mode.png new file mode 100644 index 00000000..1845a148 Binary files /dev/null and b/e2e/__screenshots__/vue-example/production/example.spec.ts/entries-current-mode.png differ diff --git a/e2e/__screenshots__/vue-example/production/example.spec.ts/logged-in-current-mode.png b/e2e/__screenshots__/vue-example/production/example.spec.ts/logged-in-current-mode.png index cb8d2f98..c6ad68e1 100644 Binary files a/e2e/__screenshots__/vue-example/production/example.spec.ts/logged-in-current-mode.png and b/e2e/__screenshots__/vue-example/production/example.spec.ts/logged-in-current-mode.png differ diff --git a/e2e/__screenshots__/vue-example/production/example.spec.ts/login-current-mode.png b/e2e/__screenshots__/vue-example/production/example.spec.ts/login-current-mode.png index 20ec7f9b..56d5beb7 100644 Binary files a/e2e/__screenshots__/vue-example/production/example.spec.ts/login-current-mode.png and b/e2e/__screenshots__/vue-example/production/example.spec.ts/login-current-mode.png differ diff --git a/e2e/__screenshots__/vue-example/production/example.spec.ts/logout-current-mode.png b/e2e/__screenshots__/vue-example/production/example.spec.ts/logout-current-mode.png index 20ec7f9b..56d5beb7 100644 Binary files a/e2e/__screenshots__/vue-example/production/example.spec.ts/logout-current-mode.png and b/e2e/__screenshots__/vue-example/production/example.spec.ts/logout-current-mode.png differ diff --git a/e2e/__screenshots__/vue-example/production/example.spec.ts/modal-current-mode.png b/e2e/__screenshots__/vue-example/production/example.spec.ts/modal-current-mode.png index 4f1caa88..31b90de6 100644 Binary files a/e2e/__screenshots__/vue-example/production/example.spec.ts/modal-current-mode.png and b/e2e/__screenshots__/vue-example/production/example.spec.ts/modal-current-mode.png differ diff --git a/e2e/example.spec.ts b/e2e/example.spec.ts index b52c7da1..d2adbd6b 100644 --- a/e2e/example.spec.ts +++ b/e2e/example.spec.ts @@ -1,100 +1,105 @@ -import {testWithII} from '@dfinity/internet-identity-playwright'; -import {initTestSuiteWithInternetIdentity, initTestSuiteWithPasskey} from './utils/init.utils'; +import {test} from '@playwright/test'; +import {initTestSuiteWithInternetIdentity} from './utils/init.utils'; -testWithII.describe.configure({mode: 'serial'}); +test.describe.configure({mode: 'serial'}); -[ - {title: 'With Passkey', initExamplePage: initTestSuiteWithPasskey}, - {title: 'With II', initExamplePage: initTestSuiteWithInternetIdentity} -].forEach(({title, initExamplePage}) => { - testWithII.describe(title, () => { - const getExamplePage = initExamplePage(); +[{title: 'With Dev', initExamplePage: initTestSuiteWithInternetIdentity}].forEach( + ({title, initExamplePage}) => { + test.describe(title, () => { + const getExamplePage = initExamplePage(); - testWithII('should sign-in', async () => { - const examplePage = getExamplePage(); + test('should sign-in', async () => { + const examplePage = getExamplePage(); - await examplePage.assertSignedIn(); - }); + await examplePage.assertSignedIn(); + }); - testWithII('should add an entry', async () => { - const examplePage = getExamplePage(); + test('should add an entry', async () => { + const examplePage = getExamplePage(); - await examplePage.addEntry('My notes.'); - }); + await examplePage.addEntry('My notes.'); + }); + + test('should add an entry with file', async () => { + const examplePage = getExamplePage(); - testWithII('should add an entry with file', async () => { - const examplePage = getExamplePage(); + await examplePage.addEntryWithFile({ + text: 'My file.', + filePath: 'e2e/data/dog.jpg' + }); - await examplePage.addEntryWithFile({ - text: 'My file.', - filePath: 'e2e/data/dog.jpg' + await examplePage.assertUploadedImage(); }); - await examplePage.assertUploadedImage(); - }); + const lastEntryText = 'My last note.'; - const lastEntryText = 'My last note.'; + test('should add another entry', async () => { + const examplePage = getExamplePage(); - testWithII('should add another entry', async () => { - const examplePage = getExamplePage(); + await examplePage.addEntry(lastEntryText); + }); - await examplePage.addEntry(lastEntryText); - }); + test('should display entries', async () => { + const examplePage = getExamplePage(); - testWithII('should delete entry', async () => { - const examplePage = getExamplePage(); + await examplePage.assertScreenshot({mode: 'current', name: 'entries'}); + }); - await examplePage.deleteLastEntry(); + test('should delete entries', async () => { + const examplePage = getExamplePage(); - await examplePage.assertEntries(2); - }); + await examplePage.deleteEntries(); - testWithII('should sign-out', async () => { - const examplePage = getExamplePage(); + await examplePage.assertEntries(0); + }); - await examplePage.signOut(); + test('should sign-out', async () => { + const examplePage = getExamplePage(); - await examplePage.assertSignedOut(); - }); + await examplePage.signOut(); - // TODO: testWithII does not seem to support setting dark or light mode so for now we just use screenshot of default mode + await examplePage.assertSignedOut(); + }); - testWithII('match login screenshot', async () => { - const examplePage = getExamplePage(); + // TODO: test does not seem to support setting dark or light mode so for now we just use screenshot of default mode - await examplePage.assertSignedOut(); + test('match login screenshot', async () => { + const examplePage = getExamplePage(); - await examplePage.assertScreenshot({mode: 'current', name: 'login'}); - }); + await examplePage.assertSignedOut(); - testWithII('match logged in screenshot', async () => { - const examplePage = getExamplePage(); + await examplePage.assertScreenshot({mode: 'current', name: 'login'}); + }); - await examplePage.signIn(); + test('match logged in screenshot', async () => { + const examplePage = getExamplePage(); - await examplePage.assertSignedIn(); + await examplePage.signIn(); - await examplePage.assertScreenshot({mode: 'current', name: 'logged-in'}); - }); + await examplePage.assertSignedIn(); - testWithII('match modal screenshot', async () => { - const examplePage = getExamplePage(); + await examplePage.assertScreenshot({mode: 'current', name: 'logged-in'}); + }); - await examplePage.openAddEntry(); + test('match modal screenshot', async () => { + const examplePage = getExamplePage(); - await examplePage.assertScreenshot({mode: 'current', name: 'modal'}); + await examplePage.openAddEntry(); - await examplePage.closeAddEntryModal(); - }); + await examplePage.assertScreenshot({mode: 'current', name: 'modal'}); - testWithII('match logout screenshot', async () => { - const examplePage = getExamplePage(); + await examplePage.closeAddEntryModal(); + }); - await examplePage.signOut(); + test('match logout screenshot', async () => { + const examplePage = getExamplePage(); - await examplePage.assertSignedOut(); + await examplePage.signOut(); - await examplePage.assertScreenshot({mode: 'current', name: 'logout'}); + await examplePage.assertSignedOut(); + + await examplePage.assertScreenshot({mode: 'current', name: 'logout'}); + }); }); - }); -}); + } +); diff --git a/e2e/page-objects/app.page.ts b/e2e/page-objects/app.page.ts index 9b6c2cc6..848a308c 100644 --- a/e2e/page-objects/app.page.ts +++ b/e2e/page-objects/app.page.ts @@ -12,26 +12,15 @@ export abstract class AppPage { protected readonly browser: Browser; protected readonly callToActions = { + login: 'Sign in for dev', logout: 'Logout', add_an_entry: 'Add an entry', - submit: 'Submit', - internet_identity: { - continue: 'Continue with Internet Identity' - }, - passkey: { - continue: 'Continue with Passkey', - create: 'Create a new passkey', - create_now: 'Create now', - use: 'Use your Passkey' - } + submit: 'Submit' }; protected readonly locators = { open_data: 'a[aria-label="Open data"]', - delete_entry: 'button[aria-label="Delete entry"]', - internet_identity: { - sign_in: `button:has-text("${this.callToActions.internet_identity.continue}")` - } + delete_entry: 'button[aria-label="Delete entry"]' }; protected constructor({page, context, browser}: AppPageParams) { @@ -44,8 +33,6 @@ export abstract class AppPage { cleanUp?(): Promise; - abstract signUp(): Promise; - abstract signIn(): Promise; async signOut(): Promise { diff --git a/e2e/page-objects/example.dev-sign-in.page.ts b/e2e/page-objects/example.dev-sign-in.page.ts new file mode 100644 index 00000000..a6849ca9 --- /dev/null +++ b/e2e/page-objects/example.dev-sign-in.page.ts @@ -0,0 +1,22 @@ +import {expect} from '@playwright/test'; +import type {AppPageParams} from './app.page'; +import {ExamplePage} from './example.page'; + +export class ExampleInternetIdentityPage extends ExamplePage { + private constructor(params: AppPageParams) { + super(params); + } + + static async create(params: AppPageParams): Promise { + return new ExampleInternetIdentityPage(params); + } + + override async signIn(): Promise { + const signInButton = this.page.locator('button', { + hasText: this.callToActions.login + }); + await expect(signInButton).toBeVisible(); + + await signInButton.click(); + } +} diff --git a/e2e/page-objects/example.ii.page.ts b/e2e/page-objects/example.ii.page.ts deleted file mode 100644 index bc5eed5d..00000000 --- a/e2e/page-objects/example.ii.page.ts +++ /dev/null @@ -1,46 +0,0 @@ -import {InternetIdentityPage} from '@dfinity/internet-identity-playwright'; -import {assertNonNullish} from '@dfinity/utils'; -import type {AppPageParams} from './app.page'; -import {ExamplePage} from './example.page'; - -export class ExampleInternetIdentityPage extends ExamplePage { - #identity: number | undefined; - - #iiPage: InternetIdentityPage; - - private constructor(params: AppPageParams) { - super(params); - - this.#iiPage = new InternetIdentityPage({ - page: this.page, - context: this.context, - browser: this.browser - }); - } - - static async create(params: AppPageParams): Promise { - return new ExampleInternetIdentityPage(params); - } - - override async waitReady(): Promise { - const REPLICA_URL = 'http://127.0.0.1:5987'; - const INTERNET_IDENTITY_ID = 'rdmx6-jaaaa-aaaaa-aaadq-cai'; - - await this.#iiPage.waitReady({url: REPLICA_URL, canisterId: INTERNET_IDENTITY_ID}); - } - - override async signUp(): Promise { - this.#identity = await this.#iiPage.signInWithNewIdentity({ - selector: this.locators.internet_identity.sign_in - }); - } - - override async signIn(): Promise { - assertNonNullish(this.#identity); - - await this.#iiPage.signInWithIdentity({ - identity: this.#identity, - selector: this.locators.internet_identity.sign_in - }); - } -} diff --git a/e2e/page-objects/example.page.ts b/e2e/page-objects/example.page.ts index 0bf68491..22141d0a 100644 --- a/e2e/page-objects/example.page.ts +++ b/e2e/page-objects/example.page.ts @@ -9,7 +9,7 @@ export abstract class ExamplePage extends AppPage { async assertSignedOut(): Promise { const button = this.page.locator('button', { - hasText: this.callToActions.internet_identity.continue + hasText: this.callToActions.login }); await expect(button).toBeVisible(); } @@ -73,11 +73,14 @@ export abstract class ExamplePage extends AppPage { await imgPage.close(); } - async deleteLastEntry(): Promise { - const buttons = this.page.locator(this.locators.delete_entry); - await buttons.last().click(); + async deleteEntries(): Promise { + while ((await this.page.locator(this.locators.delete_entry).count()) > 0) { + const currentCount = await this.page.locator(this.locators.delete_entry).count(); - await expect(this.page.locator('[role="row"]', {hasText: 'text'})).toHaveCount(0); + await this.page.locator(this.locators.delete_entry).first().click(); + + await expect(this.page.locator(this.locators.delete_entry)).toHaveCount(currentCount - 1); + } } async assertScreenshot({ diff --git a/e2e/page-objects/example.passkey.page.ts b/e2e/page-objects/example.passkey.page.ts deleted file mode 100644 index 4a891576..00000000 --- a/e2e/page-objects/example.passkey.page.ts +++ /dev/null @@ -1,135 +0,0 @@ -import {CDPSession, expect} from '@playwright/test'; -import type {AppPageParams} from './app.page'; -import {ExamplePage} from './example.page'; - -export class ExamplePasskeyPage extends ExamplePage { - #authenticatorId: string; - #client: CDPSession; - - private constructor({ - authenticatorId, - client, - ...params - }: AppPageParams & {authenticatorId: string; client: CDPSession}) { - super(params); - - this.#authenticatorId = authenticatorId; - this.#client = client; - } - - static async create({page, ...rest}: AppPageParams): Promise { - const client = await page.context().newCDPSession(page); - - await client.send('WebAuthn.enable'); - - const {authenticatorId} = await client.send('WebAuthn.addVirtualAuthenticator', { - options: { - protocol: 'ctap2', - transport: 'internal', - hasResidentKey: true, - hasUserVerification: true, - // The answer of the authenticator. - isUserVerified: false, - // If set to true, the authenticator always answers "yes" whenever it is prompted. - // We set it to false so that it only triggers explicitly within the suite. - automaticPresenceSimulation: false - } - }); - - return new ExamplePasskeyPage({page, authenticatorId, client, ...rest}); - } - - override async cleanUp(): Promise { - await this.removeAuthenticator(); - } - - override async signUp(): Promise { - await this.continueWithPasskey(); - - // Create a new passkey - const createPasskeyButton = this.page.locator('button', { - hasText: this.callToActions.passkey.create - }); - await expect(createPasskeyButton).toBeVisible(); - - await createPasskeyButton.click(); - - // Skip providing a specific display name and just create it now - const createNowPasskeyButton = this.page.locator('button', { - hasText: this.callToActions.passkey.create_now - }); - await expect(createNowPasskeyButton).toBeVisible(); - - const signUp = async () => await createNowPasskeyButton.click(); - - await this.runWithPasskey({action: signUp, withCreation: true}); - } - - override async signIn(): Promise { - await this.continueWithPasskey(); - - // User the existing passkey - const usePasskeyButton = this.page.locator('button', { - hasText: this.callToActions.passkey.use - }); - await expect(usePasskeyButton).toBeVisible(); - - const signIn = async () => await usePasskeyButton.click(); - await this.runWithPasskey({action: signIn, withCreation: false}); - } - - private async continueWithPasskey() { - const continueWithPasskeyButton = this.page.locator('button', { - hasText: this.callToActions.passkey.continue - }); - await expect(continueWithPasskeyButton).toBeVisible(); - - await continueWithPasskeyButton.click(); - } - - // Source: https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator#612-approach-2-manual-simulation-with-automaticpresencesimulation-set-to-false - private async runWithPasskey({ - action, - withCreation - }: { - action: () => Promise; - withCreation: boolean; - }) { - const createCompleted = new Promise((resolve) => { - this.#client.on('WebAuthn.credentialAdded', () => resolve()); - }); - - const assertCompleted = new Promise((resolve) => { - this.#client.on('WebAuthn.credentialAsserted', () => resolve()); - }); - - // Any passkey request will be approved by the user - await this.#client.send('WebAuthn.setUserVerified', { - authenticatorId: this.#authenticatorId, - isUserVerified: true - }); - - // Any passkey request will be automatically approved by the simulator - await this.#client.send('WebAuthn.setAutomaticPresenceSimulation', { - authenticatorId: this.#authenticatorId, - enabled: true - }); - - await action(); - - withCreation && (await createCompleted); - await assertCompleted; - - // Back to no automatic approval of passkey by the simulator - await this.#client.send('WebAuthn.setAutomaticPresenceSimulation', { - authenticatorId: this.#authenticatorId, - enabled: false - }); - } - - private async removeAuthenticator(): Promise { - await this.#client.send('WebAuthn.removeVirtualAuthenticator', { - authenticatorId: this.#authenticatorId - }); - } -} diff --git a/e2e/utils/init.utils.ts b/e2e/utils/init.utils.ts index 18fce2bf..a95cc458 100644 --- a/e2e/utils/init.utils.ts +++ b/e2e/utils/init.utils.ts @@ -1,24 +1,19 @@ -import {testWithII} from '@dfinity/internet-identity-playwright'; +import {test} from '@playwright/test'; import {AppPageParams} from '../page-objects/app.page'; -import {ExampleInternetIdentityPage} from '../page-objects/example.ii.page'; +import {ExampleInternetIdentityPage} from '../page-objects/example.dev-sign-in.page'; import {ExamplePage} from '../page-objects/example.page'; -import {ExamplePasskeyPage} from '../page-objects/example.passkey.page'; export const initTestSuiteWithInternetIdentity = (): (() => ExampleInternetIdentityPage) => { return initTestSuite(ExampleInternetIdentityPage.create); }; -export const initTestSuiteWithPasskey = (): (() => ExamplePasskeyPage) => { - return initTestSuite(ExamplePasskeyPage.create); -}; - const initTestSuite = ( create: (params: AppPageParams) => Promise ): (() => T) => { let examplePage: T; - testWithII.beforeAll(async ({playwright}) => { - testWithII.setTimeout(120000); + test.beforeAll(async ({playwright}) => { + test.setTimeout(120000); const browser = await playwright.chromium.launch(); @@ -35,10 +30,10 @@ const initTestSuite = ( await examplePage.goto(); - await examplePage.signUp(); + await examplePage.signIn(); }); - testWithII.afterAll(async () => { + test.afterAll(async () => { await examplePage.cleanUp?.(); await examplePage.close(); diff --git a/package-lock.json b/package-lock.json index e486f379..8a9138c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,6 @@ }, "devDependencies": { "@dfinity/eslint-config-oisy-wallet": "^0.2.3", - "@dfinity/internet-identity-playwright": "^2.0.0", "@junobuild/config": "^2.10.1", "@playwright/test": "^1.58.2", "@types/node": "^25.2.2", @@ -85,19 +84,6 @@ "typescript": "^5" } }, - "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/utils": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@dfinity/utils/-/utils-4.1.0.tgz", diff --git a/package.json b/package.json index 8ef889d6..0a22b8cb 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ }, "devDependencies": { "@dfinity/eslint-config-oisy-wallet": "^0.2.3", - "@dfinity/internet-identity-playwright": "^2.0.0", "@junobuild/config": "^2.10.1", "@playwright/test": "^1.58.2", "@types/node": "^25.2.2",