Site: source archives, macOS 15 open steps, contrast test in both themes (R2.1)
This commit is contained in:
4 files changed
+43
-32
No files matched your search
+24
-22
@@ -61,29 +61,31 @@ test("the lamp turns the page dark in a wave", async ({ page }) => {
|
||||
await expect(page.locator("html")).toHaveCSS("background-color", "rgb(37, 37, 37)");
|
||||
});
|
||||
|
||||
test("dark text keeps 4.5:1 against the page", async ({ page }) => {
|
||||
await page.emulateMedia({ colorScheme: "dark" });
|
||||
await open(page);
|
||||
const worst = await page.evaluate(() => {
|
||||
const parse = (c: string) => c.match(/[\d.]+/g)!.slice(0, 3).map(Number);
|
||||
const lum = (c: string) => {
|
||||
const [r, g, b] = parse(c).map((v) => {
|
||||
const s = v / 255;
|
||||
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
|
||||
});
|
||||
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
};
|
||||
const page = lum(getComputedStyle(document.documentElement).backgroundColor);
|
||||
const ratios = [...document.querySelectorAll<HTMLElement>("h1, h2, h3, p, a, li, button")]
|
||||
.filter((el) => el.textContent?.trim() && getComputedStyle(el).color !== "rgba(0, 0, 0, 0)")
|
||||
.map((el) => {
|
||||
const text = lum(getComputedStyle(el).color);
|
||||
return { ratio: (Math.max(text, page) + 0.05) / (Math.min(text, page) + 0.05), text: el.textContent };
|
||||
});
|
||||
return ratios.sort((a, b) => a.ratio - b.ratio)[0];
|
||||
});
|
||||
expect(worst.ratio, String(worst.text)).toBeGreaterThanOrEqual(4.5);
|
||||
for (const scheme of ["light", "dark"] as const) {
|
||||
test(`${scheme} text and links keep 4.5:1 against the page`, async ({ page }) => {
|
||||
await page.emulateMedia({ colorScheme: scheme });
|
||||
await open(page);
|
||||
const worst = await page.evaluate(() => {
|
||||
const parse = (c: string) => c.match(/[\d.]+/g)!.slice(0, 3).map(Number);
|
||||
const lum = (c: string) => {
|
||||
const [r, g, b] = parse(c).map((v) => {
|
||||
const s = v / 255;
|
||||
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
|
||||
});
|
||||
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
};
|
||||
const page = lum(getComputedStyle(document.documentElement).backgroundColor);
|
||||
const ratios = [...document.querySelectorAll<HTMLElement>("h1, h2, h3, p, a, li, button")]
|
||||
.filter((el) => el.textContent?.trim() && getComputedStyle(el).color !== "rgba(0, 0, 0, 0)")
|
||||
.map((el) => {
|
||||
const text = lum(getComputedStyle(el).color);
|
||||
return { ratio: (Math.max(text, page) + 0.05) / (Math.min(text, page) + 0.05), text: el.textContent };
|
||||
});
|
||||
return ratios.sort((a, b) => a.ratio - b.ratio)[0];
|
||||
});
|
||||
expect(worst.ratio, String(worst.text)).toBeGreaterThanOrEqual(4.5);
|
||||
});
|
||||
}
|
||||
|
||||
test("the system scheme sets the first theme; the lamp's choice stays", async ({ page }) => {
|
||||
await page.emulateMedia({ colorScheme: "dark" });
|
||||
|
||||
@@ -4,6 +4,7 @@ import { TEXT, type Key, type Lang } from "../src/text.ts";
|
||||
const REPO = "https://github.com/ZacharyZhang-NY/ElyOffice";
|
||||
const APPS = ["ElyDoc", "ElyTable", "ElyShow", "ElyPDF", "ElyTree", "ElyMark"];
|
||||
const dmg = (app: string) => `${REPO}/releases/download/v0.1.0/${app}-0.1.0-arm64.dmg`;
|
||||
const tarball = (kind: string) => `${REPO}/releases/download/v0.1.0/ElyOffice-0.1.0-${kind}.tar.gz`;
|
||||
|
||||
test.use({ reducedMotion: "reduce" });
|
||||
|
||||
@@ -84,11 +85,12 @@ test.describe("English locale", () => {
|
||||
for (const [i, app] of APPS.entries()) {
|
||||
await expect(page.locator(".tour .get").nth(i)).toHaveAttribute("href", dmg(app));
|
||||
}
|
||||
await expect(page.locator("#download ul a")).toHaveText([...APPS, TEXT.en.source]);
|
||||
await expect(page.locator("#download ul a")).toHaveText([...APPS, TEXT.en.source, TEXT.en.upstream]);
|
||||
for (const [i, app] of APPS.entries()) {
|
||||
await expect(page.locator("#download ul a").nth(i)).toHaveAttribute("href", dmg(app));
|
||||
}
|
||||
await expect(page.locator("[data-t=source]")).toHaveAttribute("href", REPO);
|
||||
await expect(page.locator("[data-t=source]")).toHaveAttribute("href", tarball("source"));
|
||||
await expect(page.locator("[data-t=upstream]")).toHaveAttribute("href", tarball("upstream-source"));
|
||||
await expect(page.locator(".hero > a")).toHaveText("GitHub");
|
||||
await expect(page.locator(".hero > a")).toHaveAttribute("href", REPO);
|
||||
});
|
||||
@@ -97,7 +99,7 @@ test.describe("English locale", () => {
|
||||
await page.goto("/");
|
||||
const hrefs = await page.locator("a[href^='http']").evaluateAll((as) => as.map((a) => (a as HTMLAnchorElement).href));
|
||||
const unique = [...new Set(hrefs)];
|
||||
expect(unique.sort()).toEqual([REPO, ...APPS.map(dmg)].sort());
|
||||
expect(unique.sort()).toEqual([REPO, ...APPS.map(dmg), tarball("source"), tarball("upstream-source")].sort());
|
||||
for (const url of unique) {
|
||||
const res = await request.head(url);
|
||||
expect(res.status(), url).toBeLessThan(400);
|
||||
|
||||
+10
-5
@@ -42,11 +42,16 @@ for (const name of APPS) {
|
||||
li.append(a);
|
||||
list.append(li);
|
||||
}
|
||||
const source = said("a", "source");
|
||||
source.href = REPO;
|
||||
const li = document.createElement("li");
|
||||
li.append(source);
|
||||
list.append(li);
|
||||
for (const [key, file] of [
|
||||
["source", "ElyOffice-0.1.0-source.tar.gz"],
|
||||
["upstream", "ElyOffice-0.1.0-upstream-source.tar.gz"],
|
||||
] as const) {
|
||||
const a = said("a", key);
|
||||
a.href = `${RELEASE}/${file}`;
|
||||
const li = document.createElement("li");
|
||||
li.append(a);
|
||||
list.append(li);
|
||||
}
|
||||
footer.append(version, said("p", "platforms"), said("p", "needs"), said("p", "unsigned"), list);
|
||||
|
||||
const toggle = said("button", "other");
|
||||
|
||||
+4
-2
@@ -15,8 +15,9 @@ const en = {
|
||||
download: "Download",
|
||||
platforms: "Out now for macOS. Windows and Linux are coming soon.",
|
||||
needs: "macOS 14 or later, Apple silicon.",
|
||||
unsigned: "Not notarized. The first time, Control-click the app and choose Open.",
|
||||
unsigned: "Not notarized. If macOS blocks the app, open System Settings › Privacy & Security and click Open Anyway.",
|
||||
source: "Source code",
|
||||
upstream: "Upstream source",
|
||||
shot: "screenshot",
|
||||
other: "中文",
|
||||
roads: "Drag a file down the road.",
|
||||
@@ -52,8 +53,9 @@ const zh: typeof en = {
|
||||
download: "下载",
|
||||
platforms: "macOS 版已发布。Windows 与 Linux 版即将推出。",
|
||||
needs: "macOS 14 或更新,Apple 芯片。",
|
||||
unsigned: "未经公证。第一次打开时,按住 Control 点按应用,选“打开”。",
|
||||
unsigned: "未经公证。macOS 拦下应用时,打开“系统设置 › 隐私与安全性”,点“仍要打开”。",
|
||||
source: "源代码",
|
||||
upstream: "上游源码",
|
||||
shot: "截图",
|
||||
other: "English",
|
||||
roads: "把文件沿着路拖过去。",
|
||||
|
||||
Reference in new issue
Block a user