a30bf6be4c
CI Pipeline / e2e (chromium) (pull_request) Successful in 6m13s
CI Pipeline / e2e (firefox) (pull_request) Successful in 7m3s
CI Pipeline / e2e (webkit) (pull_request) Successful in 5m52s
CI Pipeline / visual-regression (pull_request) Successful in 7m48s
CI Pipeline / performance (pull_request) Successful in 7m59s
CI Pipeline / lint (pull_request) Successful in 6m16s
CI Pipeline / build (pull_request) Successful in 5m30s
CI Pipeline / test (pull_request) Successful in 6m26s
197 lines
6.2 KiB
TypeScript
197 lines
6.2 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
|
|
test.describe("Visual Regression Tests", () => {
|
|
async function settle(page: any) {
|
|
await page.evaluate(() => {
|
|
window.scrollTo(0, window.scrollY); // ensure a frame boundary
|
|
void document.body.getBoundingClientRect();
|
|
});
|
|
await page.waitForTimeout(50);
|
|
}
|
|
|
|
test("homepage full page screenshot", async ({ page }) => {
|
|
// Add deterministic CSS to normalize rendering
|
|
await page.addStyleTag({
|
|
content: `
|
|
/* stop caret and selection flicker */
|
|
* { caret-color: transparent !important; }
|
|
::selection { background: transparent !important; }
|
|
/* hide scrollbars */
|
|
::-webkit-scrollbar { display: none !important; }
|
|
html { scrollbar-width: none !important; }
|
|
/* stabilize font rasterization */
|
|
* {
|
|
text-rendering: geometricPrecision !important;
|
|
-webkit-font-smoothing: antialiased !important;
|
|
-moz-osx-font-smoothing: grayscale !important;
|
|
}
|
|
`,
|
|
});
|
|
|
|
await page.goto("/");
|
|
await page.waitForLoadState("networkidle");
|
|
|
|
// Make sure we've really got the webfonts before shots
|
|
await page.evaluate(async () => {
|
|
// @ts-ignore
|
|
if (document.fonts && document.fonts.status !== "loaded") {
|
|
// @ts-ignore
|
|
await document.fonts.ready;
|
|
}
|
|
});
|
|
|
|
// Stabilize layout before screenshot
|
|
await settle(page);
|
|
|
|
// Take full page screenshot
|
|
await expect(page).toHaveScreenshot("homepage-full.png", {
|
|
fullPage: true,
|
|
animations: "disabled",
|
|
scale: "css",
|
|
});
|
|
});
|
|
|
|
test("homepage viewport screenshot", async ({ page }) => {
|
|
// Add deterministic CSS to normalize rendering
|
|
await page.addStyleTag({
|
|
content: `
|
|
/* stop caret and selection flicker */
|
|
* { caret-color: transparent !important; }
|
|
::selection { background: transparent !important; }
|
|
/* hide scrollbars */
|
|
::-webkit-scrollbar { display: none !important; }
|
|
html { scrollbar-width: none !important; }
|
|
/* stabilize font rasterization */
|
|
* {
|
|
text-rendering: geometricPrecision !important;
|
|
-webkit-font-smoothing: antialiased !important;
|
|
-moz-osx-font-smoothing: grayscale !important;
|
|
}
|
|
`,
|
|
});
|
|
|
|
await page.goto("/");
|
|
await page.waitForLoadState("networkidle");
|
|
|
|
// Make sure we've really got the webfonts before shots
|
|
await page.evaluate(async () => {
|
|
// @ts-ignore
|
|
if (document.fonts && document.fonts.status !== "loaded") {
|
|
// @ts-ignore
|
|
await document.fonts.ready;
|
|
}
|
|
});
|
|
|
|
// Stabilize layout before screenshot
|
|
await page.evaluate(() => {
|
|
window.scrollTo(0, 0);
|
|
void document.body.getBoundingClientRect();
|
|
});
|
|
await page.waitForTimeout(50);
|
|
|
|
// Take viewport screenshot
|
|
await expect(page).toHaveScreenshot("homepage-viewport.png", {
|
|
animations: "disabled",
|
|
});
|
|
});
|
|
|
|
test("blog listing page", async ({ page }) => {
|
|
// Add deterministic CSS to normalize rendering
|
|
await page.addStyleTag({
|
|
content: `
|
|
/* stop caret and selection flicker */
|
|
* { caret-color: transparent !important; }
|
|
::selection { background: transparent !important; }
|
|
/* hide scrollbars */
|
|
::-webkit-scrollbar { display: none !important; }
|
|
html { scrollbar-width: none !important; }
|
|
/* stabilize font rasterization */
|
|
* {
|
|
text-rendering: geometricPrecision !important;
|
|
-webkit-font-smoothing: antialiased !important;
|
|
-moz-osx-font-smoothing: grayscale !important;
|
|
}
|
|
`,
|
|
});
|
|
|
|
// Navigate to blog listing page
|
|
await page.goto("/blog");
|
|
await page.waitForLoadState("networkidle");
|
|
|
|
// Wait for blog content to be fully rendered
|
|
await page.waitForTimeout(1000);
|
|
await settle(page);
|
|
|
|
// Take full page screenshot of blog listing
|
|
await expect(page).toHaveScreenshot("blog-listing.png", {
|
|
fullPage: true,
|
|
animations: "disabled",
|
|
});
|
|
});
|
|
|
|
test("blog post page", async ({ page }) => {
|
|
// Add deterministic CSS to normalize rendering
|
|
await page.addStyleTag({
|
|
content: `
|
|
/* stop caret and selection flicker */
|
|
* { caret-color: transparent !important; }
|
|
::selection { background: transparent !important; }
|
|
/* hide scrollbars */
|
|
::-webkit-scrollbar { display: none !important; }
|
|
html { scrollbar-width: none !important; }
|
|
/* stabilize font rasterization */
|
|
* {
|
|
text-rendering: geometricPrecision !important;
|
|
-webkit-font-smoothing: antialiased !important;
|
|
-moz-osx-font-smoothing: grayscale !important;
|
|
}
|
|
`,
|
|
});
|
|
|
|
// Navigate to a specific blog post
|
|
await page.goto("/blog/resolving-active-conflicts");
|
|
await page.waitForLoadState("networkidle");
|
|
|
|
// Wait for blog post content to be fully rendered
|
|
await page.waitForSelector("main", { timeout: 10000 });
|
|
await page.waitForTimeout(1000);
|
|
await settle(page);
|
|
|
|
// Take full page screenshot of blog post
|
|
await expect(page).toHaveScreenshot("blog-post.png", {
|
|
fullPage: true,
|
|
animations: "disabled",
|
|
});
|
|
});
|
|
|
|
test("404 error page", async ({ page }) => {
|
|
// Add deterministic CSS to normalize rendering
|
|
await page.addStyleTag({
|
|
content: `
|
|
/* stop caret and selection flicker */
|
|
* { caret-color: transparent !important; }
|
|
::selection { background: transparent !important; }
|
|
/* hide scrollbars */
|
|
::-webkit-scrollbar { display: none !important; }
|
|
html { scrollbar-width: none !important; }
|
|
/* stabilize font rasterization */
|
|
* {
|
|
text-rendering: geometricPrecision !important;
|
|
-webkit-font-smoothing: antialiased !important;
|
|
-moz-osx-font-smoothing: grayscale !important;
|
|
}
|
|
`,
|
|
});
|
|
|
|
// Navigate to a non-existent route to trigger 404
|
|
await page.goto("/non-existent-page");
|
|
await page.waitForLoadState("networkidle");
|
|
await settle(page);
|
|
|
|
// Take screenshot of 404 page
|
|
await expect(page).toHaveScreenshot("404-error.png", {
|
|
animations: "disabled",
|
|
});
|
|
});
|
|
});
|