Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Playwright test to MRZ Scanner #4

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
35 changes: 35 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Playwright Tests
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
jobs:
test:
env:
HOME: /root
name: 'Playwright Tests'
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright:v1.46.1-jammy
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies (clean install)
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npm test
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report
retention-days: 30
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,41 @@ The following table is a list of supported browsers based on the above requireme
<sup>1</sup> devices running iOS needs to be on iOS 14.3+ for camera video streaming to work in Chrome, Firefox or other Apps using webviews.

Apart from the browsers, the operating systems may impose some limitations of their own that could restrict the use of the SDK. Browser compatibility ultimately depends on whether the browser on that particular operating system supports the features listed above.


## End to End (E2E) testing with Playwright

The end-to-end (E2E) tests for this project are located in the `/e2e` folder.

To set up and run the tests, follow the steps below:

1. Install the project dependencies:

```bash
npm install
npx playwright install --with-deps # installs Playwright and all required browsers and dependencies
```

2. Run the tests:

```bash
npm test
```

This command will trigger the Playwright test suite, executing all tests defined in the `/e2e` folder.

### Additional Notes

- **Playwright Configurations:** If you need to customize the Playwright settings (like browser options, timeouts, or environment variables), check the playwright.config.ts file in the root directory.

- **Running Specific Tests:** To run a specific test file or group, use:

```bash
npx playwright test <test-file-name>
```

- **Generating Reports:** Playwright can generate test reports. You can view detailed results after the tests by running:

```bash
npx playwright show-report
```
33 changes: 33 additions & 0 deletions e2e/assets/sample.y4m

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions e2e/fixtures/MRZScanner.fixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Page, Locator } from "@playwright/test";

// TODO: Update the URL when we upload the page to live server.

const URL = "/index.html";

export class MRZScannerPage {
private page: Page;
private dialogCloseButton: Locator;
private startButton: Locator;

private scanIDButton: Locator;
private scanPassportButton: Locator;
private scanBothButton: Locator;

constructor(page: Page) {
this.page = page;
this.dialogCloseButton = this.page.locator("i.dls-license-icon-close");
this.startButton = this.page.locator(".start-btn");

this.scanIDButton = this.page.locator("#scan-id-btn");
this.scanPassportButton = this.page.locator("#scan-passport-btn");
this.scanBothButton = this.page.locator("#scan-both-btn");
}

/**
* Close the license related dialog if it shows.
*/
async closeDialogIfPresent() {
await this.dialogCloseButton.click();
}

async navigateTo() {
await this.page.setExtraHTTPHeaders({
"sec-ch-ua": '"Chromium";v="91", " Not;A Brand";v="99"',
});

await this.page.goto(URL);
await this.closeDialogIfPresent();
}

async getTitle() {
return await this.page.title();
}

async getSelectedButton() {
return await this.page.locator("button.scan-option-btn.selected");
}

async clickStartButton() {
await this.startButton.click();

// Ensuring the page is loaded after clicked on the Start button
await this.page.waitForLoadState("networkidle", { timeout: 30000 });
await this.page.waitForLoadState("domcontentloaded", { timeout: 30000 });
}

async clickscanIDButton() {
await this.scanIDButton.click();
await this.page.waitForTimeout(2000);
}

async clickscanPassportButton() {
await this.scanPassportButton.click();
await this.page.waitForTimeout(2000);
}

async clickScanBothButton() {
await this.scanBothButton.click();
await this.page.waitForTimeout(2000);
}

async evaluate(props) {
await this.page.evaluate(props);
}
}
13 changes: 13 additions & 0 deletions e2e/fixtures/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { test as baseTest } from "@playwright/test";
import { MRZScannerPage } from "./MRZScanner.fixture";

export const test = baseTest.extend<{
mrzScannerPage: MRZScannerPage;
}>({
mrzScannerPage: async ({ page }, use) => {
const mrzScannerPage = new MRZScannerPage(page);
await use(mrzScannerPage);
},
});

export { expect } from "@playwright/test";
40 changes: 40 additions & 0 deletions e2e/tests/MRZScanner.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { test, expect } from "../fixtures";

test.describe.configure({ mode: "serial" });

test.describe("Verify the MRZ Scanner page title and verify user can select different settings", () => {
test.beforeEach(async ({ mrzScannerPage }) => {
// Navigate to the MRZ Scanner page
await mrzScannerPage.navigateTo();
});

test("should display the correct title", async ({ mrzScannerPage }) => {
// Validate the page title
const title = await mrzScannerPage.getTitle();
await expect(title).toContain("Dynamsoft MRZ Scanner");
});

test('should click "Both" button on the page and validate the header label text', async ({ mrzScannerPage }) => {
await mrzScannerPage.clickStartButton();

await mrzScannerPage.clickScanBothButton();
const selectedBtn = await mrzScannerPage.getSelectedButton();
await expect(selectedBtn).toHaveText("Both");
});

test('should click "ID" button on the page and validate the header label text', async ({ mrzScannerPage }) => {
await mrzScannerPage.clickStartButton();

await mrzScannerPage.clickscanIDButton();
const selectedBtn = await mrzScannerPage.getSelectedButton();
await expect(selectedBtn).toHaveText("ID");
});

test('should click "Passport" button on the page and validate the header label text', async ({ mrzScannerPage }) => {
await mrzScannerPage.clickStartButton();

await mrzScannerPage.clickscanPassportButton();
const selectedBtn = await mrzScannerPage.getSelectedButton();
await expect(selectedBtn).toHaveText("Passport");
});
});
Loading
Loading