Skip to content

Commit

Permalink
test(pixelperfect): pixel perfect on visual regression (momentum-desi…
Browse files Browse the repository at this point in the history
…gn#884)

* feat: show playwright test report

* temp change in test file

* temporary fix to compression

* temporary change in test file

* added download artifact, job summary to test

* no message

* no message

* no message

* no message

* no message

* no message

* Possible fix

* Minor fix

* Added temp tests

* test(pixelperfect): test screenshots on firefox

* test(pixelperfect): use docker to handle e2e test

* test(pixelperfect): support all browser and add docker to workflow

* test(pixelperfect): update readme doc

* test(pixelperfect): update snapshot

* test(pixelperfect): update webkit snapshot

* test(pixelperfect): update themeprovider snapshot

* Update package.json

* test(pixelperfect): address comments

* Update text.e2e-test.ts

* Update themeprovider.e2e-test.ts

* revert: remove github action change

* ci: run test:e2e:docker:all as postbuild

* test(pixelperfect): update snapshot

* test(pixelperfect): update testing

* test(pixelperfect): update docker testing

* test(pixelperfect): update snapshot changes for text component

* test(pixelperfect): testing for ghrc credential

* test(pixelperfect): update pull-request yml

* fix(pixelperfect): update port changes

* fix(pixelperfect): fix ci issue

* test(pixelperfect): update

* test(pixelperfect): update

* test(pixelperfect): fix port issue

* docs: added to testing markdown

* docs: small fix i overlooked

* test(pixelperfect): update script

---------

Co-authored-by: Deeya <dishuupadhyay01@gmail.com>
Co-authored-by: Jason Chai Jing <jachai@cisco.com>
Co-authored-by: Christoph Scheffauer <scheffauerc@gmail.com>
  • Loading branch information
4 people authored Oct 25, 2024
1 parent f26e522 commit e0fee19
Show file tree
Hide file tree
Showing 207 changed files with 342 additions and 65 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module.exports = {
globals: {
BufferEncoding: 'readonly',
},
ignorePatterns: ['**/dist/**', '*.hbs', 'scripts/**', '**/husky/**'],
ignorePatterns: ['**/dist/**', '*.hbs', 'scripts/**', '**/husky/**', '**/Dockerfile.*'],
overrides: [
{
files: ['**/*.test.ts'],
Expand Down
16 changes: 9 additions & 7 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -344,19 +344,21 @@ jobs:
- name: Synchronize Packages
run: yarn

- name: Install Playwright
run: |
if [ ${{ matrix.package }} == '@momentum-design/components' ]; then
yarn workspace @momentum-design/components test:e2e:install
fi
- name: Log in to GitHub Container Registry
if: ${{ matrix.package == '@momentum-design/components' }}
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Test - Postbuild
run: yarn workspace ${{ matrix.package }} test:postbuild
run: yarn workspace ${{ matrix.package }} test:postbuild

- name: Upload Playwright Report
uses: actions/upload-artifact@v4
if: ${{ !cancelled() && matrix.package == '@momentum-design/components' }}
with:
name: playwright-report
path: packages/components/playwright-report/
retention-days: 30
retention-days: 30
157 changes: 146 additions & 11 deletions packages/components/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

## E2E Testing

Testing of the mounted, built component in real browsers.
E2E Testing is done with the help of [Playwright](https://playwright.dev/).
`@momentum-design/components` utilizes [Playwright](https://playwright.dev/) as the core end-to-end testing framework to ensure continuous functionality during development. Our e2e tests focus on functionality rather than code coverage to strike a balance between quick feedback and usability.

### Scope

Expand All @@ -21,22 +20,158 @@ E2E Testing is done with the help of [Playwright](https://playwright.dev/).
* Edge
* Safari/webkit

#### Setup

`@momentum-design/components` project performs visual comparisons and functionality testing for all components. There are different setups for local environments versus GitHub Workflow:

* On Local:
* You can run functional tests locally (for easier debugging) or in Docker.
* Update snapshot images (golden images) only using Docker with the official Playwright image, via the provided yarn scripts.
* Uses `playwright.config.ts`, relying on local and a web server.
* On Github Workflow:
* GitHub Workflow build the Playwright Docker image to run all tests, including snapshot tests.
* Playwright projects:
* Default = Functional tests and Snapshot tests (Docker required)
* Skip Snapshot = Snapshot tests (Recommend for local)

### Local development

For the best local development experience, the following E2E setup testing is recommended:

1. Open 2 terminals
2. In the first terminal, run `yarn components test:e2e:setup`
* This will spin up the local dev environment with dev server
* Wait till a `Serving!` message appears
3. In the second terminal, run `yarn components test:e2e`
* This allows to run all E2E tests
* To run a specific E2E test, run `yarn components test:e2e XXX`
* To run the tests in `headed mode`, run `yarn components test:e2e --headed`
1. In the terminal, run:

```bash
yarn components test:e2e:install # install all browsers for playwright to run on local
# you don't have to install if you already have them
```

2. Once the install completes, setup the webserver:

```bash
yarn components test:e2e:serve # setup server on localhost:4000
```

3. Open another terminal, now you can start run the test:

```bash
yarn components test:e2e:skip-snapshot # without snapshot
# if you want to test the snapshot, please see Docker Testing
```

* To run the tests in `headed mode`, run:

```bash
yarn components test:e2e:skip-snapshot -- --headed # without snapshot
```

4. To Run **single** E2E Test file, run:

```bash
yarn components test:e2e:skip-snapshot XXX.e2e-test.ts # without snapshot
```

5. To Run **individual** test in a testing file, run:

```bash
yarn components test:e2e:skip-snapshot -- './src/components/iconprovider/iconprovider.e2e-test.ts' -g 'mdc-IconmProvider nested'
```

* where the test file is `"./src/components/iconprovider/iconprovider.e2e-test.ts"`, while within the file, the test naming structure is `mdc-IconmProvider nested`.

6. To Run test in **specific** browser, run:

```bash
yarn components test:e2e:chrome # run on chrome whithout snapshots
yarn components test:e2e:firefox # run on firefox whithout snapshots
```

### Update Visual Regression snapshots

To update Visual Regression snapshots, follow the steps below to run E2E testing on Docker:

1. You need to have docker installed on local.

2. **Docker engine / daemon needs to run before executing.**

3. Login to the docker ghrc.io:

You can keep the first terminal open, while running/developing E2E tests in the second terminal.
```bash
echo $PAT | docker login ghcr.io -u username --password-stdin # login to docker with you github credentials (replace $PAT with personal access token (access token needs write packages access))
```

4. Open a terminal to setup webserver:

```bash
yarn components test:e2e:serve # setup server on localhost:4000
```

5. Open another terminal to run docker image:

```bash
yarn components test:e2e:docker:serve # run docker image on localhost:3000
```

6. Open another terminal to start run the test:

```bash
yarn components test:e2e:docker # run all the e2e test
yarn components test:e2e:docker:update-snapshot # update snapshots
```

7. To Run **single** E2E Test file, run:

```bash
yarn components test:e2e:docker XXX.e2e-test.ts
yarn components test:e2e:docker:update-snapshot XXX.e2e-test.ts # update snapshots
```

#### Testing method

```bash
# E2E test methods
yarn components test:e2e:skip-snapshot # you should run this on local, test are filter test base on snapshot condition check
yarn components test:e2e # the general playwright script for local to run
yarn components test:e2e:install # install all the browsers dependencies to local
yarn components test:e2e:chrome # runs all test on specific browser, without snapshot
yarn components test:e2e:report # shows the previous test report (also work for docker test)

yarn components test:e2e:docker:build # build docker image that required for testing (can pull from GHCR)
yarn components test:e2e:docker:serve # run Playwright server in docker image to run the test
yarn components test:e2e:docker # the general playwright script for docker to run (Follow Docker Testing Instruction)
yarn components test:e2e:docker:update-snapshot # build and update snapshots (Only works if docker is installed)
```

#### Other ways of running tests

* Using UI Mode - by running `yarn components test:e2e:ui` a separate browser window will be available, which allows you to control the running of tests from there
* Using [Playwright VS Code extension](https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright)

#### Note on Docker Perfomance on Mac (M Series)

Since Docker runs on the `amd64` architecture, using Docker on Mac with M chips may result in slower performance due to the emulation layer provided by Rosetta 2. For faster performance, it's recommended to run Docker in a native `amd64` environment or be aware of the potential delays when running locally on Mac.

### Upload Latest Version of Docker Playwright Image

1. You need to have docker installed on local.

2. Set the version to latest playwright version and build the new image to local :

```bash
"yarn components test:e2e:docker:build": "docker build --platform linux/amd64 -f ./config/playwright/docker/utils/Dockerfile.test.postbuild -t ghcr.io/momentum-design/momentum-design/docker-playwright:v1.47.2 ."
# replace all the v1.47.2 to the latest version of playwright and run this script to build new image
```

3. After the build is done, login to the docker ghrc.io:

```bash
echo $PAT | docker login ghcr.io -u username --password-stdin # login to docker with you github credentials (replace $PAT with personal access token (access token needs write packages access))
```

4. Now you can push the latest image to GHRC:

```bash
docker push ghcr.io/momentum-design/momentum-design/docker-playwright:v1.47.2
# replace the v1.47.2 to the version you want to push
```

5. You can check the image that you push here [Docker-Playwright](https://github.com/orgs/momentum-design/packages/container/package/momentum-design%2Fdocker-playwright)
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import type { PlaywrightTestConfig } from '@playwright/test';
import type { GitHubActionOptions } from '@estruyf/github-actions-reporter';
import { devices } from '@playwright/test';
import os from 'os';

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();

let url;
if (os.platform() === 'linux') {
url = 'http://172.17.0.1:4000';
} else {
url = 'http://host.docker.internal:4000';
}

const githubActionsReporterOptions: GitHubActionOptions = {
title: 'Playwright E2E Test results',
useDetails: true,
showAnnotations: true,
showTags: true,
showError: true,
includeResults: ['fail', 'flaky'],
};

/**
* See https://playwright.dev/docs/test-configuration.
*/
const config: PlaywrightTestConfig = {
testDir: '../../../src',
testMatch: /.*\.e2e-test\.ts/,
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000,
},
/* 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 ? '50%' : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: process.env.CI ? [['html'], ['@estruyf/github-actions-reporter', githubActionsReporterOptions]] : 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: url,
/* On CI: Collect trace when retrying the failed test /
Locally: always collect trace. See https://playwright.dev/docs/trace-viewer */
trace: process.env.CI ? 'retain-on-failure' : 'on',
},

snapshotPathTemplate: '{testDir}/{testFileDir}/__screenshots__/{projectName}/{arg}{ext}',

/* Configure projects for major browsers */
projects: [
{
name: 'chrome',
use: {
...devices['Desktop Chrome'],
channel: 'chrome',
},
},
{
name: 'firefox',
use: {
...devices['Desktop Firefox'],
},
},

{
name: 'webkit',
use: {
...devices['Desktop Safari'],
},
},

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: {
// ...devices['Pixel 5'],
// },
// },
// {
// name: 'Mobile Safari',
// use: {
// ...devices['iPhone 12'],
// },
// },

/* Test against branded browsers. */
{
name: 'msedge',
use: {
channel: 'msedge',
},
},
],

/* Run your local dev server before starting the tests */
webServer: [
{
command: 'yarn test:e2e:setup',
url: 'http://localhost:4000',
stdout: 'pipe',
stderr: 'pipe',
timeout: 240 * 1000,
reuseExistingServer: !process.env.CI,
},
{
command: 'yarn test:e2e:docker:run',
url: 'http://localhost:3000',
stdout: 'pipe',
stderr: 'pipe',
timeout: 240 * 1000,
reuseExistingServer: !process.env.CI,
},
],
};

export default config;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM mcr.microsoft.com/playwright:v1.47.2-focal

RUN npm install -g playwright@1.47.2

RUN npx playwright install

RUN npx playwright install chrome

RUN npx playwright install msedge

CMD ["npx", "playwright", "run-server", "--port", "3000", "--host", "0.0.0.0"]
4 changes: 2 additions & 2 deletions packages/components/config/playwright/setup/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const DEFAULT_ACCESSIBILITY_SCAN_OPTIONS = {
// we keep the threshold, max_diff_pixels_ratio at a higher value until
// we have pixel perfect visual regression testing enabled.
const VISUAL_REGRESSION = {
THRESHOLD: 0.1,
MAX_DIFF_PIXELS_RATIO: 0.25,
THRESHOLD: 0,
MAX_DIFF_PIXELS_RATIO: 0,
FILE_EXTENSION: 'png',
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ class VisualRegression {
*/
async takeScreenshot(name: string, options?: ScreenShotOptions): Promise<void> {
const elementToTakeScreenShotFrom = options?.element || this.page;
const isSnapshotRun = process.env.E2E_SKIP_SNAPSHOT !== 'true';

expect(await elementToTakeScreenShotFrom.screenshot(options)).toMatchSnapshot({
name: `${name}.${CONSTANTS.VISUAL_REGRESSION.FILE_EXTENSION}`,
threshold: CONSTANTS.VISUAL_REGRESSION.THRESHOLD,
maxDiffPixelRatio: CONSTANTS.VISUAL_REGRESSION.MAX_DIFF_PIXELS_RATIO,
});
if (isSnapshotRun) {
expect(await elementToTakeScreenShotFrom.screenshot(options)).toMatchSnapshot({
name: `${name}.${CONSTANTS.VISUAL_REGRESSION.FILE_EXTENSION}`,
threshold: CONSTANTS.VISUAL_REGRESSION.THRESHOLD,
maxDiffPixelRatio: CONSTANTS.VISUAL_REGRESSION.MAX_DIFF_PIXELS_RATIO,
});
}
}
}

Expand Down
Loading

0 comments on commit e0fee19

Please sign in to comment.