Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
key: ${{ runner.os }}-docker-default-${{ github.sha }}
restore-keys: |
${{ runner.os }}-docker-default-
- name: Run tests without captcha
- name: Run default tests
run: |
cd demo
docker compose up -d
Expand Down Expand Up @@ -55,8 +55,33 @@ jobs:
cd ..
npm run e2e:captcha:ci

tests_passkey:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
- name: Prepare
uses: ./.github/actions/prepare
- name: Install demo dependencies
run: npm ci
working-directory: demo
- name: Cache Docker layers for passkey image
uses: actions/cache@v3
with:
path: /home/runner/.docker
key: ${{ runner.os }}-docker-passkey-${{ github.sha }}
restore-keys: |
${{ runner.os }}-docker-passkey-
- name: Run tests with passkey
run: |
cd demo
docker compose -f docker-compose.passkey.yml up -d
cd ..
npm run e2e:passkey:ci

may-merge:
needs: ['tests', 'tests_captcha']
needs: ['tests', 'tests_captcha', 'tests_passkey']
runs-on: ubuntu-latest
steps:
- name: Cleared for merging
Expand Down
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ testWithII('should sign-in with a new user when II requires a captcha', async ({
});
```

Similarly, you can test a flow where Internet Identity requires the user to create and save a passkey:

```javascript
testWithII('should sign in with a new user when II requires a passkey', async ({page, iiPage}) => {
await page.goto('/');

await iiPage.signInWithNewIdentity({createPasskey: true});
});
```

### 3. Wait for Internet Identity (optional)

You might encounter scenarios where you perform tests against a local replica started in parallel with your tests, commonly when automating the tests in a CI environment. The library also exposes a fixture that lets you wait for Internet Identity to be ready.
Expand Down Expand Up @@ -167,6 +177,20 @@ Then, navigate to the root directory and run the dedicated test:
npm run e2e:captcha
```

### Running Required Passkey Tests Locally

The default test suite validates the use of the latest Internet Identity, which does not require the user to complete a specific step to create a passkey. To test a flow where passkey creation is required, run the following command from the `demo` directory:

```bash
docker compose -f docker-compose.passkey.yml up
```

Then, navigate to the root directory and run the dedicated test:

```bash
npm run e2e:passkey
```

## 🚧 Limitations

Currently, the library's fixtures cannot be implemented with Playwright's ability to [load existing authenticated state](https://playwright.dev/docs/auth). Playwright currently does not support IndexedDB for such features. This limitation is tracked in their [GitHub issue #11164](https://github.com/microsoft/playwright/issues/11164).
Expand Down
12 changes: 12 additions & 0 deletions demo/docker-compose.passkey.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
services:
juno-satellite:
image: junobuild/satellite:0.0.57
ports:
- 5987:5987
volumes:
- juno_satellite_passkey:/juno/.juno
- ./juno.dev.config.js:/juno/juno.dev.config.js
- ./target/deploy:/juno/target/deploy/

volumes:
juno_satellite_passkey:
2 changes: 1 addition & 1 deletion e2e/captcha.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ testWithII.beforeEach(async ({iiPage}) => {
testWithII('should sign-in with a new user when II requires a captcha', async ({page, iiPage}) => {
await page.goto('/');

await iiPage.signInWithNewIdentity({captcha: true});
await iiPage.signInWithNewIdentity({captcha: true, createPasskey: true});
});
12 changes: 12 additions & 0 deletions e2e/passkey.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {testWithII} from '../src';
import {DOCKER_CONTAINER} from './spec.constants';

testWithII.beforeEach(async ({iiPage}) => {
await iiPage.waitReady(DOCKER_CONTAINER);
});

testWithII('should sign-in with a new user when II requires a passkey', async ({page, iiPage}) => {
await page.goto('/');

await iiPage.signInWithNewIdentity({createPasskey: true});
});
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@
"build": "tsc --noEmit && node rmdir.mjs && node esbuild.mjs && npm run ts-declaration",
"lint": "eslint --max-warnings 0",
"dev": "npm --prefix demo run dev",
"e2e": "NODE_ENV=development playwright test --grep-invert 'captcha'",
"e2e:ci": "playwright test --reporter=html --grep-invert 'captcha'",
"e2e": "NODE_ENV=development playwright test e2e/login.spec",
"e2e:ci": "playwright test --reporter=html e2e/login.spec",
"e2e:captcha": "NODE_ENV=development playwright test e2e/captcha.spec",
"e2e:captcha:ci": "playwright test --reporter=html e2e/captcha.spec"
"e2e:captcha:ci": "playwright test --reporter=html e2e/captcha.spec",
"e2e:passkey": "NODE_ENV=development playwright test e2e/passkey.spec",
"e2e:passkey:ci": "playwright test --reporter=html e2e/passkey.spec"
},
"devDependencies": {
"@dfinity/eslint-config-oisy-wallet": "^0.1.10",
Expand Down
7 changes: 6 additions & 1 deletion src/page-objects/InternetIdentityPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,13 @@ export class InternetIdentityPage {
* @param {Object} [params] - The optional arguments for the sign-in method.
* @param {string} [params.selector] - The selector for the login button. Defaults to [data-tid=login-button].
* @param {boolean} [params.captcha] - Set to true if the II login flow requires a captcha.
* @param {boolean} [params.createPasskey] - Set to true if the II login flow requires the user to create a passkey.
* @returns {Promise<number>} A promise that resolves to the new identity number.
*/
signInWithNewIdentity = async (params?: {
selector?: string;
captcha?: boolean;
createPasskey?: boolean;
}): Promise<number> => {
const iiPagePromise = this.context.waitForEvent('page');

Expand All @@ -114,7 +116,10 @@ export class InternetIdentityPage {
await expect(iiPage).toHaveTitle('Internet Identity');

await iiPage.locator('#registerButton').click();
await iiPage.locator('[data-action=construct-identity]').click();

if (params?.createPasskey === true) {
await iiPage.locator('[data-action=construct-identity]').click();
}

if (params?.captcha === true) {
await iiPage.locator('input#captchaInput').fill('a', {timeout: 10000});
Expand Down