Last active
December 29, 2022 04:09
-
-
Save dohooo/efa053c6273b2a148c3a5f7319c1a9a5 to your computer and use it in GitHub Desktop.
Visual testing with vitest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { join } from "path"; | |
import type { Meta, StoryFn } from "@storybook/react"; | |
import { composeStories } from "@storybook/react"; | |
import { render } from "@testing-library/react"; | |
import glob from "glob"; | |
import { toMatchImageSnapshot } from "jest-image-snapshot"; | |
import { chromium, type Browser, type Page } from "playwright"; | |
import { afterAll, beforeAll, expect, describe, it, vi } from "vitest"; | |
interface StoryFile { | |
default: Meta | |
[name: string]: StoryFn | Meta | |
} | |
it.skipIf(process.env.IS_CI)("local only test", async () => { | |
expect.extend({ toMatchImageSnapshot }); | |
const TEST_ID = "VISUAL_TESTING_TEST_ID"; | |
const storyFiles = glob.sync(join(__dirname, "./components/**/*.stories.tsx")); | |
describe("should", async () => { | |
let page: Page; | |
let browser: Browser; | |
beforeAll(async () => { | |
browser = await chromium.launch(); | |
page = await browser.newPage(); | |
}); | |
afterAll(async () => { | |
await browser.close(); | |
}); | |
const stories = (await Promise.all( | |
storyFiles.map(async (storyPath) => { | |
return Object.values(composeStories(await vi.importActual(storyPath) as StoryFile)); | |
}), | |
)).reduce((acc, cur) => [...acc, ...cur], [] as StoryFn[]); | |
it.each( | |
stories.map(i => [String(i.parameters?.__id), i]), | |
)("%s", async (id, Story) => { | |
const { container } = render(<div id={TEST_ID}><Story /></div>); | |
expect(container).toMatchSnapshot(); | |
const styles = document.querySelector("style")?.outerHTML || ""; | |
const content = `<div style="display:inline-block;" id="${id}">${container.innerHTML}</div>`; | |
const html = `${styles}${content}`; | |
await page.setContent(html); | |
await page.waitForSelector(`#${id}`, { state: "visible" }); | |
const target = (await page.$$(`#${id}`))[0]; | |
const demission = await target.boundingBox(); | |
const { x, y, width, height } = demission!; | |
const screenshot = await page.screenshot({ clip: { x, y, width, height } }); | |
expect(screenshot).toMatchImageSnapshot({ customSnapshotIdentifier: id }); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment