Browse Source

build: add visual regression testing

add image and dom snapshot comparison for storybook components

image snapshot comparison can been flaky and produce many
false-positives. a higher threshold has been used to mitigate this
although it may not identify all regressions. DOM snapshots
supplement images to increase the likelihood of capturing
regressions.
master
DanConwayDev 2 years ago
parent
commit
d663869b0f
No known key found for this signature in database
GPG Key ID: 68E15486D73F75E1
  1. 27
      .github/workflows/playwright.yml
  2. 29
      .storybook/test-runner.ts
  3. BIN
      __snapshots__/navbar--default.png
  4. BIN
      __snapshots__/navbar--nip-07-exists.png
  5. BIN
      __snapshots__/navbar--no-nip-07.png
  6. 10
      package.json
  7. 76
      src/lib/components/__snapshots__/Navbar.stories.ts.snap
  8. 1982
      yarn.lock

27
.github/workflows/playwright.yml

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: yarn
- name: Install Playwright Browsers
run: yarn playwright install --with-deps
- name: Run Storybook tests
run: yarn test-storybook:ci
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30

29
.storybook/test-runner.ts

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
import type { TestRunnerConfig } from "@storybook/test-runner";
import { toMatchImageSnapshot } from 'jest-image-snapshot';
const customSnapshotsDir = `${process.cwd()}/__snapshots__`;
const config: TestRunnerConfig = {
setup() {
expect.extend({ toMatchImageSnapshot });
},
async postRender(page, context) {
// DOM Snapshot
const elementHandler = await page.$('#storybook-root');
if (elementHandler) {
const innerHTML = await elementHandler.innerHTML();
expect(innerHTML).toMatchSnapshot();
}
// Image Snapshop
const image = await page.screenshot();
expect(image).toMatchImageSnapshot({
customSnapshotsDir,
customSnapshotIdentifier: context.id,
failureThresholdType: 'percent',
failureThreshold: 0.002,
});
},
};
export default config;

BIN
__snapshots__/navbar--default.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
__snapshots__/navbar--nip-07-exists.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
__snapshots__/navbar--no-nip-07.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

10
package.json

@ -9,7 +9,9 @@ @@ -9,7 +9,9 @@
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
"build-storybook": "storybook build",
"test-storybook": "test-storybook",
"test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"yarn build-storybook --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && yarn test-storybook --maxWorkers=2\""
},
"devDependencies": {
"@storybook/addon-a11y": "^7.4.5",
@ -19,12 +21,16 @@ @@ -19,12 +21,16 @@
"@storybook/blocks": "^7.4.5",
"@storybook/svelte": "^7.4.5",
"@storybook/sveltekit": "^7.4.5",
"@storybook/test-runner": "^0.13.0",
"@storybook/testing-library": "^0.2.1",
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/adapter-node": "^1.2.3",
"@sveltejs/kit": "^1.5.0",
"@tailwindcss/typography": "^0.5.10",
"@types/jest-image-snapshot": "^6.2.1",
"@types/node": "^20.8.2",
"autoprefixer": "^10.4.16",
"jest-image-snapshot": "^6.2.0",
"postcss": "^8.4.30",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@ -46,4 +52,4 @@ @@ -46,4 +52,4 @@
"resolutions": {
"jackspeak": "2.1.1"
}
}
}

76
src/lib/components/__snapshots__/Navbar.stories.ts.snap

@ -0,0 +1,76 @@ @@ -0,0 +1,76 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Navbar Default smoke-test 1`] = `
<div class="navbar bg-neutral">
<div class="flex-1">
<h4>
<span class="primary">
git
</span>
<span class>
together
</span>
<span class>
.xyz
</span>
</h4>
</div>
<div class="flex-none gap-4">
<div class="btn btn-primary normal-case">
Sign up
</div>
<button class="btn btn-outline normal-case">
Login
</button>
</div>
</div>
`;
exports[`Navbar NIP07Exists smoke-test 1`] = `
<div class="navbar bg-neutral">
<div class="flex-1">
<h4>
<span class="primary">
git
</span>
<span class>
together
</span>
<span class>
.xyz
</span>
</h4>
</div>
<div class="flex-none gap-4">
<button class="btn btn-outline normal-case">
Login
</button>
</div>
</div>
`;
exports[`Navbar NoNIP07 smoke-test 1`] = `
<div class="navbar bg-neutral">
<div class="flex-1">
<h4>
<span class="primary">
git
</span>
<span class>
together
</span>
<span class>
.xyz
</span>
</h4>
</div>
<div class="flex-none gap-4">
<div class="btn btn-primary normal-case">
Sign up
</div>
<button class="btn btn-outline normal-case">
Login
</button>
</div>
</div>
`;

1982
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save