mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(test): resolve CI failures from the overhaul
- fixture-integrity: probe media via media-engine probeMedia (resolves the bundled static ffmpeg) instead of bare system ffprobe, which is ENOENT in CI; gate on ffmpegAvailable() like the other media tests - a11y: regenerate a11y-baseline.json to include the mobile device keys (the baseline only had desktop keys, so the mobile a11y scan saw them as new) - device-visual: tag @visual and exclude it from the PR mobile-smoke gate (darwin-only screenshots cannot pass on linux; nightly + update-visual-baselines still run it to seed linux goldens)
This commit is contained in:
@@ -140,6 +140,131 @@
|
||||
"impact": "moderate",
|
||||
"description": "Ensure all skip links have a focusable target",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-home-en:color-contrast": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
|
||||
"count": 7
|
||||
},
|
||||
"mobile-home-en:heading-order": {
|
||||
"impact": "moderate",
|
||||
"description": "Ensure the order of headings is semantically correct",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-image-resize-en:color-contrast": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
|
||||
"count": 2
|
||||
},
|
||||
"mobile-image-resize-en:link-name": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure links have discernible text",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-video-convert-en:color-contrast": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
|
||||
"count": 2
|
||||
},
|
||||
"mobile-video-convert-en:link-name": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure links have discernible text",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-audio-convert-en:color-contrast": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
|
||||
"count": 2
|
||||
},
|
||||
"mobile-audio-convert-en:link-name": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure links have discernible text",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-document-pdf-to-image-en:color-contrast": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
|
||||
"count": 2
|
||||
},
|
||||
"mobile-document-pdf-to-image-en:link-name": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure links have discernible text",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-data-csv-excel-en:color-contrast": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
|
||||
"count": 2
|
||||
},
|
||||
"mobile-data-csv-excel-en:link-name": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure links have discernible text",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-editor-en:page-has-heading-one": {
|
||||
"impact": "moderate",
|
||||
"description": "Ensure that the page, or at least one of its frames contains a level-one heading",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-editor-en:region": {
|
||||
"impact": "moderate",
|
||||
"description": "Ensure all page content is contained by landmarks",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-editor-en:skip-link": {
|
||||
"impact": "moderate",
|
||||
"description": "Ensure all skip links have a focusable target",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-login-en:color-contrast": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-login-en:region": {
|
||||
"impact": "moderate",
|
||||
"description": "Ensure all page content is contained by landmarks",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-login-en:skip-link": {
|
||||
"impact": "moderate",
|
||||
"description": "Ensure all skip links have a focusable target",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-home-ar:color-contrast": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
|
||||
"count": 8
|
||||
},
|
||||
"mobile-home-ar:heading-order": {
|
||||
"impact": "moderate",
|
||||
"description": "Ensure the order of headings is semantically correct",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-image-resize-ar:color-contrast": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-image-resize-ar:link-name": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure links have discernible text",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-login-ar:color-contrast": {
|
||||
"impact": "serious",
|
||||
"description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-login-ar:region": {
|
||||
"impact": "moderate",
|
||||
"description": "Ensure all page content is contained by landmarks",
|
||||
"count": 1
|
||||
},
|
||||
"mobile-login-ar:skip-link": {
|
||||
"impact": "moderate",
|
||||
"description": "Ensure all skip links have a focusable target",
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { expect, openSettings, test } from "./helpers";
|
||||
// ---------------------------------------------------------------------------
|
||||
// Mobile (Pixel 7 -- mobile-chromium)
|
||||
// ---------------------------------------------------------------------------
|
||||
test.describe("@mobile Device visual regression", () => {
|
||||
test.describe("@mobile @visual Device visual regression", () => {
|
||||
test("home page", async ({ loggedInPage: page }) => {
|
||||
await page.goto("/");
|
||||
await page.waitForLoadState("networkidle");
|
||||
@@ -49,7 +49,7 @@ test.describe("@mobile Device visual regression", () => {
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tablet (Galaxy Tab S9 -- tablet-chromium)
|
||||
// ---------------------------------------------------------------------------
|
||||
test.describe("@tablet Device visual regression", () => {
|
||||
test.describe("@tablet @visual Device visual regression", () => {
|
||||
test("home page", async ({ loggedInPage: page }) => {
|
||||
await page.goto("/");
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
|
||||
import sharp from "sharp";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { fixtures } from "../../fixtures/index.js";
|
||||
|
||||
const ffprobe = process.env.FFPROBE_PATH || "ffprobe";
|
||||
const qpdf = process.env.QPDF_PATH || "qpdf";
|
||||
|
||||
describe("real fixtures decode through their real tools", () => {
|
||||
@@ -21,33 +21,35 @@ describe("real fixtures decode through their real tools", () => {
|
||||
expect((meta.width ?? 0) * (meta.height ?? 0)).toBeGreaterThan(64 * 64);
|
||||
});
|
||||
|
||||
it.each([
|
||||
fixtures.video.hero.mp4,
|
||||
fixtures.video.hero.mov,
|
||||
fixtures.video.hero.webm,
|
||||
fixtures.video.hero.mkv,
|
||||
fixtures.video.hero.avi,
|
||||
fixtures.audio.speech.wav,
|
||||
fixtures.audio.speech.flac,
|
||||
fixtures.audio.speech.ogg,
|
||||
fixtures.audio.speech.m4a,
|
||||
fixtures.audio.speech.aac,
|
||||
fixtures.audio.speech.opus,
|
||||
fixtures.audio.tagged,
|
||||
])("ffprobe reads a positive duration from %s", (path) => {
|
||||
const out = execFileSync(
|
||||
ffprobe,
|
||||
["-v", "error", "-show_entries", "format=duration", "-of", "csv=p=0", path],
|
||||
{ encoding: "utf8" },
|
||||
);
|
||||
expect(Number.parseFloat(out.trim())).toBeGreaterThan(0);
|
||||
// Probe via media-engine, which resolves the bundled static ffmpeg/ffprobe.
|
||||
// System ffprobe is NOT on PATH in CI (only the static binary is), so a bare
|
||||
// `ffprobe` spawn would ENOENT. Gate on ffmpeg presence so a machine with no
|
||||
// ffmpeg at all skips cleanly.
|
||||
describe.skipIf(!ffmpegAvailable())("media probes", () => {
|
||||
it.each([
|
||||
fixtures.video.hero.mp4,
|
||||
fixtures.video.hero.mov,
|
||||
fixtures.video.hero.webm,
|
||||
fixtures.video.hero.mkv,
|
||||
fixtures.video.hero.avi,
|
||||
fixtures.audio.speech.wav,
|
||||
fixtures.audio.speech.flac,
|
||||
fixtures.audio.speech.ogg,
|
||||
fixtures.audio.speech.m4a,
|
||||
fixtures.audio.speech.aac,
|
||||
fixtures.audio.speech.opus,
|
||||
fixtures.audio.tagged,
|
||||
])("media probe reads a positive duration from %s", async (path) => {
|
||||
const info = await probeMedia(path);
|
||||
expect(info.durationS).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
it.each([
|
||||
fixtures.document.pdfMulti,
|
||||
fixtures.document.pdfScanned,
|
||||
])("qpdf reports pages for %s", (path) => {
|
||||
const out = execFileSync(qpdf, ["--show-npages", path], { encoding: "utf8" });
|
||||
expect(Number.parseInt(out.trim(), 10)).toBeGreaterThan(0);
|
||||
});
|
||||
it.each([fixtures.document.pdfMulti, fixtures.document.pdfScanned])(
|
||||
"qpdf reports pages for %s",
|
||||
(path) => {
|
||||
const out = execFileSync(qpdf, ["--show-npages", path], { encoding: "utf8" });
|
||||
expect(Number.parseInt(out.trim(), 10)).toBeGreaterThan(0);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user