feat: add source aware resolver, update reset, update generator

This commit is contained in:
2026-09-25 19:01:43 +05:00
parent 5313567e70
commit 5f77c097e2
19 changed files with 361 additions and 179 deletions
+14 -8
View File
@@ -1,23 +1,29 @@
import { expect, test } from "playwright/test";
import {
expectNoErrorAlert,
expectNoErrors,
openTool,
resultImage,
trackErrors,
} from "./helpers/page";
test.describe("generators — known UI gap (#checklist, п.1)", () => {
// FIXME: Генераторы открываются, но в UI нет ни полей схемы, ни кнопки
// «Generate» — только RU/EN/Reset. Задача Q5: `docs/backlog.md`,
// `docs/checklist-manual-testing.md`. После фикса убрать fixme.
test.fixme("single-color-png renders Generate controls and produces a result", async ({
test.describe("generators", () => {
test("single-color-png auto-runs and reacts to parameters", async ({
page,
}) => {
const sink = trackErrors(page);
await openTool(page, "single-color-png");
const generate = page.getByRole("button", { name: "Generate" });
await expect(generate).toBeVisible();
await generate.click();
await expect(resultImage(page)).toBeVisible();
await expect(page.getByRole("button", { name: "Generate" })).toHaveCount(0);
const firstSource = await resultImage(page).getAttribute("src");
await page.getByRole("spinbutton", { name: "Width" }).fill("32");
await expect(resultImage(page)).not.toHaveAttribute(
"src",
firstSource ?? "",
);
await expectNoErrorAlert(page);
expectNoErrors(sink);
});
test("create-empty-png page opens without errors", async ({ page }) => {
+15 -5
View File
@@ -1,6 +1,6 @@
import { expect, test } from "playwright/test";
import { opaquePng } from "./helpers/fixtures";
import { openTool, toolLink, uploadImage, useEnglish } from "./helpers/page";
import { pixelRow } from "./helpers/fixtures";
import { openTool, toolLink, useEnglish } from "./helpers/page";
test("поиск каталога находит по названию из другой локали", async ({
page,
@@ -31,11 +31,21 @@ test("RU/EN: переключение переводит заголовок ин
await expect(heading).toHaveText("Resize PNG");
});
test("ошибка run'а локализуется, не сырой i18n-ключ", async ({ page }) => {
await openTool(page, "resize-png");
await uploadImage(page, opaquePng);
test("ошибка run'а локализуется и переводится при смене языка", async ({
page,
}) => {
await openTool(page, "bytes-to-png");
await page
.getByRole("textbox", { name: "Text data" })
.fill(pixelRow(33, [255, 0, 0, 255]));
await page.getByRole("button", { name: "Render text" }).click();
const alert = page.getByRole("alert");
await expect(alert).toBeVisible();
await expect(alert).toHaveText(/\S/);
await expect(alert).not.toHaveText(/^errors\./);
const english = await alert.textContent();
await page.getByRole("button", { name: "RU", exact: true }).click();
await expect(alert).not.toHaveText(english ?? "");
await expect(alert).not.toHaveText(/^errors\./);
});
-29
View File
@@ -1,29 +0,0 @@
import { expect, test } from "playwright/test";
import { opaquePng } from "./helpers/fixtures";
import { openTool, resultImage, uploadImage } from "./helpers/page";
// FIXME: В файле зарегистрированы баги production UI (см.
// `docs/backlog.md` и `docs/checklist-manual-testing.md`, раздел G). Тела
// assert'ят ОЖИДАЕМОЕ поведение. Статус fixme означает «мы знаем, что сейчас
// падает»; когда баг починят — убрать fixme и тест станет зелёным «сам по
// себе».
test.describe("known bugs — documented as fixme", () => {
test.fixme("resize-png: upload produces a resized result (no alert)", async ({
page,
}) => {
await openTool(page, "resize-png");
await uploadImage(page, opaquePng);
await expect(page.getByRole("alert")).toHaveCount(0);
await expect(resultImage(page)).toBeVisible();
});
test.fixme("crop-png: upload produces a cropped result (no alert)", async ({
page,
}) => {
await openTool(page, "crop-png");
await uploadImage(page, opaquePng);
await expect(page.getByRole("alert")).toHaveCount(0);
await expect(resultImage(page)).toBeVisible();
});
});
+43 -5
View File
@@ -8,7 +8,6 @@ import {
} from "./helpers/fixtures";
import {
downloadResult,
emptyState,
errorAlert,
expectNoErrorAlert,
expectNoErrors,
@@ -21,6 +20,36 @@ import {
useEnglish,
} from "./helpers/page";
test("resize-png uses the source dimensions by default", async ({ page }) => {
const sink = trackErrors(page);
await openTool(page, "resize-png");
await uploadImage(page, opaquePng);
await expect(page.getByRole("spinbutton", { name: "Width" })).toHaveValue(
"64",
);
await expect(page.getByRole("spinbutton", { name: "Height" })).toHaveValue(
"48",
);
await expect(resultImage(page)).toBeVisible();
await expectNoErrorAlert(page);
expectNoErrors(sink);
});
test("crop-png starts with the full source area", async ({ page }) => {
const sink = trackErrors(page);
await openTool(page, "crop-png");
await uploadImage(page, opaquePng);
await expect(page.getByRole("spinbutton", { name: "Width" })).toHaveValue(
"64",
);
await expect(page.getByRole("spinbutton", { name: "Height" })).toHaveValue(
"48",
);
await expect(resultImage(page)).toBeVisible();
await expectNoErrorAlert(page);
expectNoErrors(sink);
});
test("flip-png: full flow - upload, result, download", async ({ page }) => {
const sink = trackErrors(page);
await openTool(page, "flip-png");
@@ -41,14 +70,23 @@ test("convert-png-to-jpg: produces a downloadable jpg", async ({ page }) => {
expectNoErrors(sink);
});
test.fixme("reset clears result but keeps source", async ({ page }) => {
await openTool(page, "flip-png");
test("reset restores defaults and re-runs with the source", async ({
page,
}) => {
const sink = trackErrors(page);
await openTool(page, "blur-png");
await uploadImage(page, opaquePng);
await expect(resultImage(page)).toBeVisible();
const radius = rangeInput(page, /radius/i);
await radius.fill("20");
await expect(radius).toHaveValue("20");
await page.getByRole("button", { name: "Reset" }).click();
await expect(resultImage(page)).toHaveCount(0);
await expect(emptyState(page)).toBeVisible();
await expect(radius).toHaveValue("4");
await expect(sourceImage(page)).toBeVisible();
await expect(resultImage(page)).toBeVisible();
await expectNoErrorAlert(page);
expectNoErrors(sink);
});
test("blur: changing slider updates result image", async ({ page }) => {