mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-10-18 19:30:27 +08:00
Refactor visual tests
We use built in devices for testing instead of our own custom ones. Split up desktop and mobile visual tests for better separation.
This commit is contained in:
@@ -46,7 +46,7 @@ jobs:
|
||||
|
||||
- name: Install Playwright browsers
|
||||
if: steps.playwright-dep-cache.outputs.cache-hit != 'true'
|
||||
run: npx playwright install chromium
|
||||
run: npx playwright install chromium webkit --with-deps
|
||||
|
||||
- name: Install Radicle binaries
|
||||
run: |
|
||||
@@ -57,9 +57,9 @@ jobs:
|
||||
- name: Run Playwright tests
|
||||
run: |
|
||||
if [ ${{ github.ref }} = "refs/heads/master" ]; then
|
||||
npm run test:e2e -- --project visual --update-snapshots || true;
|
||||
npm run test:e2e -- --project visual-desktop visual-mobile --update-snapshots || true;
|
||||
else
|
||||
npm run test:e2e -- --project visual;
|
||||
npm run test:e2e -- --project visual-desktop visual-mobile;
|
||||
fi
|
||||
|
||||
# We don't care about logs in visual snapshot tests, only the images.
|
||||
|
||||
+24
-5
@@ -41,7 +41,7 @@ const config: PlaywrightTestConfig = {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "visual",
|
||||
name: "visual-desktop",
|
||||
timeout: 60_000,
|
||||
expect: {
|
||||
timeout: 30_000,
|
||||
@@ -51,13 +51,32 @@ const config: PlaywrightTestConfig = {
|
||||
animations: "disabled",
|
||||
},
|
||||
},
|
||||
testDir: "./tests/visual",
|
||||
snapshotDir: "./tests/visual/snapshots",
|
||||
testDir: "./tests/visual/desktop",
|
||||
snapshotDir: "./tests/visual/snapshots/desktop",
|
||||
retries: 0,
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
...devices["Desktop Chrome HiDPI"],
|
||||
actionTimeout: 0,
|
||||
trace: "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "visual-mobile",
|
||||
timeout: 60_000,
|
||||
expect: {
|
||||
timeout: 30_000,
|
||||
toHaveScreenshot: {
|
||||
threshold: 0.01,
|
||||
scale: "device",
|
||||
animations: "disabled",
|
||||
},
|
||||
},
|
||||
testDir: "./tests/visual/mobile",
|
||||
snapshotDir: "./tests/visual/snapshots/mobile",
|
||||
retries: 0,
|
||||
use: {
|
||||
...devices["iPhone 13 Mini"],
|
||||
actionTimeout: 0,
|
||||
deviceScaleFactor: 2,
|
||||
trace: "off",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@ import type * as Stream from "node:stream";
|
||||
import * as Fs from "node:fs/promises";
|
||||
import * as Path from "node:path";
|
||||
import assert from "node:assert";
|
||||
import { test as base, expect, type ViewportSize } from "@playwright/test";
|
||||
import { test as base, expect } from "@playwright/test";
|
||||
|
||||
import * as Process from "./process.js";
|
||||
import * as issue from "@tests/support/cobs/issue.js";
|
||||
@@ -18,13 +18,6 @@ export { expect };
|
||||
|
||||
const fixturesDir = Path.resolve(supportDir, "..", "./fixtures");
|
||||
|
||||
type ViewportTypes = "iPhoneXR" | "Desktop";
|
||||
|
||||
export const viewportSizes: Record<ViewportTypes, ViewportSize> = {
|
||||
iPhoneXR: { width: 414, height: 896 },
|
||||
Desktop: { width: 1280, height: 720 },
|
||||
};
|
||||
|
||||
export const test = base.extend<{
|
||||
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
||||
forAllTests: void;
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
import type { Page } from "@playwright/test";
|
||||
import { test, expect, markdownUrl } from "@tests/support/fixtures.js";
|
||||
|
||||
async function goToSection(section: string, page: Page) {
|
||||
await page.goto(`${markdownUrl}/tree/main/cheatsheet.md`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await page.getByText("Collapse").click();
|
||||
await page.locator(`[href="${section}"]`).click();
|
||||
}
|
||||
|
||||
test.describe("markdown rendering basics", async () => {
|
||||
test.use({ viewport: { width: 1600, height: 1200 } });
|
||||
|
||||
test("table of contents", async ({ page }) => {
|
||||
await page.goto(
|
||||
`${markdownUrl}/tree/main/cheatsheet.md#table-of-contents`,
|
||||
{
|
||||
waitUntil: "networkidle",
|
||||
},
|
||||
);
|
||||
await page.getByText("Collapse").click();
|
||||
await expect(page.getByText("Table of Contents")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("headers", async ({ page }) => {
|
||||
await goToSection("#headers", page);
|
||||
await expect(page.getByText("###### H6")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("emphasis", async ({ page }) => {
|
||||
await goToSection("#emphasis", page);
|
||||
await expect(page.getByText("Emphasis, aka").first()).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("lists", async ({ page }) => {
|
||||
await goToSection("#lists", page);
|
||||
await expect(page.getByText("First ordered list").first()).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("links", async ({ page }) => {
|
||||
await goToSection("#links", page);
|
||||
await expect(page.getByText("There are two ways")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("images", async ({ page }) => {
|
||||
await goToSection("#images", page);
|
||||
await expect(page.getByText("Here's our logo").first()).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("code and syntax highlighting", async ({ page }) => {
|
||||
await goToSection("#code", page);
|
||||
await expect(page.getByText("Code blocks are part")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("tables", async ({ page }) => {
|
||||
await goToSection("#tables", page);
|
||||
await expect(page.getByText("Tables aren't part of the")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("blockquotes", async ({ page }) => {
|
||||
await goToSection("#blockquotes", page);
|
||||
await expect(page.getByText("Blockquotes are").first()).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("inline HTML", async ({ page }) => {
|
||||
await goToSection("#html", page);
|
||||
await expect(page.getByText("You can also use raw HTML")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("horizontal rule", async ({ page }) => {
|
||||
await goToSection("#hr", page);
|
||||
await expect(page.getByText("Three or more...").first()).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("line breaks", async ({ page }) => {
|
||||
await goToSection("#lines", page);
|
||||
await expect(page.getByText("My basic recommendation")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("videos", async ({ page }) => {
|
||||
await goToSection("#videos", page);
|
||||
await expect(page.getByText("They can't be added")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test("footnotes", async ({ page }) => {
|
||||
await page.goto(`${markdownUrl}/tree/main/footnotes.md#footnotes`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await expect(
|
||||
page.locator(
|
||||
"text=This is an example footnote[0]. And some radicle[1] examples.",
|
||||
),
|
||||
).toBeVisible();
|
||||
await page.getByText("Collapse").click();
|
||||
await expect(page.getByText("0. https://example.com ↩")).toBeVisible();
|
||||
await expect(page.getByText("1. https://radicle.xyz ↩")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
|
||||
await page.getByText("Plain").click();
|
||||
await expect(
|
||||
page.locator(
|
||||
"text=This is an example footnote[^0]. And some radicle[^1] examples.",
|
||||
),
|
||||
).toBeVisible();
|
||||
await expect(page.getByText("[^0]: https://example.com")).toBeVisible();
|
||||
await expect(page.getByText("[^1]: https://radicle.xyz")).toBeVisible();
|
||||
});
|
||||
|
||||
test("math", async ({ page }) => {
|
||||
await page.goto(`${markdownUrl}/tree/main/math.md`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await expect(page.getByText("The Cauchy-Schwarz Inequality")).toBeVisible();
|
||||
await page.getByText("Collapse").click();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
});
|
||||
|
||||
test("relative image not able to being loaded", async ({ page }) => {
|
||||
await page.goto(`${markdownUrl}/tree/main/loading-image.md`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await page.getByText("Collapse").click();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
});
|
||||
|
||||
test("markdown in issues is not overflowing", async ({ page }) => {
|
||||
await page.goto(`${markdownUrl}/issues`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await page.getByText("Collapse").click();
|
||||
await page.getByRole("link", { name: "This title has markdown" }).click();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
});
|
||||
@@ -1,194 +0,0 @@
|
||||
import type { Page } from "@playwright/test";
|
||||
import {
|
||||
test,
|
||||
expect,
|
||||
markdownUrl,
|
||||
viewportSizes,
|
||||
} from "@tests/support/fixtures.js";
|
||||
|
||||
async function goToSection(section: string, page: Page) {
|
||||
await page.goto(`${markdownUrl}/tree/main/cheatsheet.md`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await page.locator(`[href="${section}"]`).click();
|
||||
}
|
||||
|
||||
const viewportWidth = viewportSizes["Desktop"].width;
|
||||
|
||||
test.describe("markdown rendering", async () => {
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 450 } });
|
||||
test("table of contents", async ({ page }) => {
|
||||
await page.goto(
|
||||
`${markdownUrl}/tree/main/cheatsheet.md#table-of-contents`,
|
||||
{
|
||||
waitUntil: "networkidle",
|
||||
},
|
||||
);
|
||||
await expect(page.getByText("Table of Contents")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({
|
||||
viewport: { width: viewportWidth, height: 1030 },
|
||||
});
|
||||
test("headers", async ({ page }) => {
|
||||
await goToSection("#headers", page);
|
||||
await expect(page.getByText("###### H6")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 470 } });
|
||||
test("emphasis", async ({ page }) => {
|
||||
await goToSection("#emphasis", page);
|
||||
await expect(page.getByText("Emphasis, aka").first()).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 1100 } });
|
||||
test("lists", async ({ page }) => {
|
||||
await goToSection("#lists", page);
|
||||
await expect(page.getByText("First ordered list").first()).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 1024 } });
|
||||
test("links", async ({ page }) => {
|
||||
await goToSection("#links", page);
|
||||
await expect(page.getByText("There are two ways")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 520 } });
|
||||
test("images", async ({ page }) => {
|
||||
await goToSection("#images", page);
|
||||
await expect(page.getByText("Here's our logo").first()).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 1130 } });
|
||||
test("code and syntax highlighting", async ({ page }) => {
|
||||
await goToSection("#code", page);
|
||||
await expect(page.getByText("Code blocks are part")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test("footnotes", async ({ page }) => {
|
||||
await page.goto(`${markdownUrl}/tree/main/footnotes.md#footnotes`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await expect(
|
||||
page.locator(
|
||||
"text=This is an example footnote[0]. And some radicle[1] examples.",
|
||||
),
|
||||
).toBeVisible();
|
||||
await expect(page.getByText("0. https://example.com ↩")).toBeVisible();
|
||||
await expect(page.getByText("1. https://radicle.xyz ↩")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
|
||||
await page.getByText("Plain").click();
|
||||
await expect(
|
||||
page.locator(
|
||||
"text=This is an example footnote[^0]. And some radicle[^1] examples.",
|
||||
),
|
||||
).toBeVisible();
|
||||
await expect(page.getByText("[^0]: https://example.com")).toBeVisible();
|
||||
await expect(page.getByText("[^1]: https://radicle.xyz")).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test("math", async ({ page }) => {
|
||||
await page.goto(`${markdownUrl}/tree/main/math.md`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await expect(
|
||||
page.getByText("The Cauchy-Schwarz Inequality"),
|
||||
).toBeVisible();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 1100 } });
|
||||
test("tables", async ({ page }) => {
|
||||
await goToSection("#tables", page);
|
||||
await expect(page.getByText("Tables aren't part of the")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 450 } });
|
||||
test("blockquotes", async ({ page }) => {
|
||||
await goToSection("#blockquotes", page);
|
||||
await expect(page.getByText("Blockquotes are").first()).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 510 } });
|
||||
test("inline HTML", async ({ page }) => {
|
||||
await goToSection("#html", page);
|
||||
await expect(page.getByText("You can also use raw HTML")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 710 } });
|
||||
test("horizontal rule", async ({ page }) => {
|
||||
await goToSection("#hr", page);
|
||||
await expect(page.getByText("Three or more...").first()).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 625 } });
|
||||
test("line breaks", async ({ page }) => {
|
||||
await goToSection("#lines", page);
|
||||
await expect(page.getByText("My basic recommendation")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: viewportWidth, height: 500 } });
|
||||
test("videos", async ({ page }) => {
|
||||
await goToSection("#videos", page);
|
||||
await expect(page.getByText("They can't be added")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("relative image not able to being loaded", async ({ page }) => {
|
||||
await page.goto(`${markdownUrl}/tree/main/loading-image.md`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
});
|
||||
|
||||
test("markdown in issues is not overflowing", async ({ page }) => {
|
||||
await page.goto(`${markdownUrl}/issues`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await page.getByRole("link", { name: "This title has markdown" }).click();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
});
|
||||
@@ -1,11 +1,4 @@
|
||||
import {
|
||||
test,
|
||||
expect,
|
||||
cobUrl,
|
||||
viewportSizes,
|
||||
} from "@tests/support/fixtures.js";
|
||||
|
||||
test.use({ viewport: viewportSizes["iPhoneXR"] });
|
||||
import { test, expect, cobUrl } from "@tests/support/fixtures.js";
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.addInitScript(() => {
|
||||
@@ -68,11 +61,12 @@ test("patch page", async ({ page }) => {
|
||||
["This patch is going to be archived", "archived"],
|
||||
["Let's add a README", "merged"],
|
||||
["Add subtitle to README", "open"],
|
||||
["Taking another stab at the README", "open"],
|
||||
];
|
||||
|
||||
for (const [name, state] of patches) {
|
||||
await page.goto(`${cobUrl}/patches?state=${state}`);
|
||||
await page.goto(`${cobUrl}/patches?state=${state}`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await page.getByRole("link", { name }).click();
|
||||
await page.getByRole("heading", { name }).waitFor();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
|
||||
@@ -3,11 +3,8 @@ import {
|
||||
expect,
|
||||
sourceBrowsingUrl,
|
||||
test,
|
||||
viewportSizes,
|
||||
} from "@tests/support/fixtures.js";
|
||||
|
||||
test.use({ viewport: viewportSizes["iPhoneXR"] });
|
||||
|
||||
test("source tree page", async ({ page }) => {
|
||||
await page.goto(sourceBrowsingUrl, { waitUntil: "networkidle" });
|
||||
await expect(page).toHaveScreenshot();
|
||||
|
||||
Reference in New Issue
Block a user