feat: import F95 screenshot galleries with AVIF support
CI / frontend (push) Failing after 19s
CI / backend (push) Failing after 41s

This commit is contained in:
mrleo1nid committed 2026-10-26 17:51:19 +03:00
1 parent 5b911d1e3b
commit 69f71cb836
21 files changed
+513 -33

No files matched your search

+29 -2
View File
@@ -144,16 +144,28 @@ test("new game shows an unsaved F95 cover and aligns metadata fields", {
bundle: true, write: false, format: "iife", platform: "browser", logLevel: "silent"});
const css = readFileSync(new URL("../src/styles.css", import.meta.url), "utf8");
let blobRequests = 0;
const server = createServer((req, res) => {
let createdGame;
const server = createServer(async (req, res) => {
if (req.url === "/styles.css") { res.setHeader("Content-Type", "text/css"); res.end(css); return; }
if (req.url === "/bundle.js") { res.setHeader("Content-Type", "application/javascript"); res.end(compiled.outputFiles[0].text); return; }
if (req.url.startsWith("/blobs/")) { blobRequests++; res.writeHead(404); res.end(); return; }
if (req.url === "/api/games" && req.method === "POST") {
let body = "";
for await (const chunk of req) body += chunk;
createdGame = JSON.parse(body);
res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify({id: 1})); return;
}
if (req.url.startsWith("/api/games/1/upload")) {
res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify({id: 1, status: "ready"})); return;
}
if (req.url === "/api/metadata/f95") {
res.setHeader("Content-Type", "application/json");
res.end(JSON.stringify({url: "https://f95zone.to/threads/example.123/", title: "Mist", description: "A story",
tags: ["adventure", "survival"], cover_hash: "a".repeat(64) + ".webp",
cover_preview: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jCTkAAAAASUVORK5CYII=",
cover_warning: null, auth_required: false, metadata_available: true})); return;
cover_warning: null, auth_required: false, metadata_available: true,
gallery: ["b", "c"].map(char => ({hash: char.repeat(64) + ".webp",
preview: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jCTkAAAAASUVORK5CYII="}))})); return;
}
res.setHeader("Content-Type", "text/html");
res.end('<!doctype html><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/styles.css"><main></main><script src="/bundle.js"></script>');
@@ -170,6 +182,15 @@ test("new game shows an unsaved F95 cover and aligns metadata fields", {
await page.getByRole("button", {name: "Подтянуть", exact: true}).click();
await page.getByText("Данные из F95zone загружены", {exact: true}).waitFor();
await page.getByRole("img", {name: "Обложка игры из F95zone"}).evaluate(image => image.decode());
const gallery = page.getByRole("region", {name: "Галерея игры"});
await gallery.getByRole("button", {name: "Открыть изображение 1", exact: true}).click();
const viewer = page.getByRole("dialog", {name: "Просмотр галереи"});
await viewer.waitFor();
await viewer.getByRole("img", {name: "Кадр 1", exact: true}).evaluate(image => image.decode());
await viewer.press("ArrowRight");
await viewer.getByRole("img", {name: "Кадр 2", exact: true}).waitFor();
await viewer.press("Escape");
await viewer.waitFor({state: "detached"});
assert.equal(blobRequests, 0, "unsaved covers must not use a route that requires a saved game");
assert.equal(await page.getByRole("textbox", {name: "Название", exact: true}).inputValue(), "Mist");
assert.equal(await page.getByRole("textbox", {name: /^Теги/}).inputValue(), "adventure, survival");
@@ -186,6 +207,12 @@ test("new game shows an unsaved F95 cover and aligns metadata fields", {
await page.getByRole("button", {name: "Убрать обложку", exact: true}).click();
assert.equal(await page.getByRole("img", {name: "Обложка игры из F95zone"}).count(), 0);
assert.equal(await page.getByRole("textbox", {name: "Название", exact: true}).inputValue(), "Mist");
await gallery.getByRole("button", {name: "Убрать изображение 1", exact: true}).click();
assert.equal(await gallery.getByRole("img").count(), 1);
await page.getByRole("button", {name: "Загрузить", exact: true}).click();
await page.getByText("Готово", {exact: true}).waitFor();
assert.deepEqual(createdGame.gallery_hashes, ["c".repeat(64) + ".webp"]);
assert.equal(createdGame.title, "Mist");
} finally {
await browser?.close();
await new Promise(resolve => server.close(resolve));