diff --git a/web/e2e/issues.spec.ts b/web/e2e/issues.spec.ts index fb56137..0273ea2 100644 --- a/web/e2e/issues.spec.ts +++ b/web/e2e/issues.spec.ts @@ -39,12 +39,12 @@ test("переход по связи и «назад»; ✕ и щелчок по await page.getByRole("link", { name: "Задачи", exact: true }).click(); await page.getByRole("link", { name: "AURORA-9001", exact: true }).click(); const d = page.getByRole("dialog"); - await d.getByRole("link", { name: "AURORA-9002", exact: true }).click(); + await d.locator(".links-sec").getByRole("link", { name: "AURORA-9002", exact: true }).click(); await expect(page).toHaveURL(/\/app\/issues\/AURORA-9002$/); await expect(d.getByRole("heading", { name: "API свода" })).toBeVisible(); await page.goBack(); await expect(d.getByRole("heading", { name: "Схема свода" })).toBeVisible(); - await d.getByRole("link", { name: "AURORA-9002", exact: true }).click(); + await d.locator(".links-sec").getByRole("link", { name: "AURORA-9002", exact: true }).click(); await d.getByRole("button", { name: "Закрыть" }).click(); await expect(page).toHaveURL(/\/app\/issues$/); await expect(page.getByRole("dialog")).toHaveCount(0); @@ -75,12 +75,12 @@ test("карточка: описание свёрнуто, комментари await expect(d.getByRole("heading", { name: "Комментарии (3)" })).toBeVisible(); await expect(d.getByTestId("comments").getByRole("listitem").first()).toContainText("[мост] служебный комментарий"); await expect(d.getByRole("button", { name: "развернуть" })).toBeVisible(); - await expect(d.locator("pre.description")).toHaveClass(/clamped/); // свёрнуто построчным обрезанием (текст в DOM остаётся) - const hClamped = (await d.locator("pre.description").boundingBox())!.height; - expect(await d.locator("pre.description").evaluate((e) => e.scrollHeight > e.clientHeight)).toBe(true); + await expect(d.locator("div.description")).toHaveClass(/clamped/); // свёрнуто по высоте (текст в DOM остаётся) + const hClamped = (await d.locator("div.description").boundingBox())!.height; + expect(await d.locator("div.description").evaluate((e) => e.scrollHeight > e.clientHeight)).toBe(true); await d.getByRole("button", { name: "развернуть" }).click(); - await expect(d.locator("pre.description")).not.toHaveClass(/clamped/); - expect((await d.locator("pre.description").boundingBox())!.height).toBeGreaterThan(hClamped); + await expect(d.locator("div.description")).not.toHaveClass(/clamped/); + expect((await d.locator("div.description").boundingBox())!.height).toBeGreaterThan(hClamped); await expect(d.getByText("Конец описания.")).toBeVisible(); await expect(d.getByRole("cell", { name: "ensure_fields" })).toBeHidden(); await d.getByText("Команды моста (2)").click(); @@ -92,6 +92,34 @@ test("карточка: описание свёрнуто, комментари await expect(page.getByRole("dialog").getByText("Первый комментарий e2e")).toHaveCount(0); }); +test("разметка Jira: описание и комментарии отрендерены, «исходник» у каждого блока, ключ задачи — ссылка", async ({ page }) => { + await login(page, "/app/issues/AURORA-9001"); + const d = page.getByRole("dialog"); + const desc = d.locator("section", { has: page.getByRole("heading", { name: "Описание" }) }); + await expect(desc.getByRole("heading", { level: 3, name: "Контекст" })).toBeVisible(); + await expect(desc.getByRole("listitem").first()).toHaveText("Таблицы."); + await expect(desc.getByText("КФО", { exact: true })).toHaveJSProperty("tagName", "STRONG"); + await expect(desc).not.toContainText("h3."); + await desc.getByRole("button", { name: "исходник" }).click(); + await expect(desc.locator("pre.description")).toContainText("h3. Контекст"); + await expect(desc.locator("pre.description")).toContainText("# Таблицы."); + await desc.getByRole("button", { name: "текст" }).click(); + await expect(desc.getByRole("heading", { level: 3, name: "Контекст" })).toBeVisible(); + + const items = d.getByTestId("comments").getByRole("listitem"); + const first = items.filter({ hasText: "Первый комментарий e2e" }); + await expect(first.getByText("Первый комментарий e2e")).toHaveJSProperty("tagName", "STRONG"); + await first.getByRole("button", { name: "исходник" }).click(); + await expect(first.locator("pre.body")).toContainText("*Первый комментарий e2e*"); + await expect(d.locator("pre.body")).toHaveCount(1); + + await items.filter({ hasText: "Схему согласовали" }).getByRole("link", { name: "AURORA-9002" }).click(); + await expect(d.getByRole("heading", { name: "API свода" })).toBeVisible(); + await page.goBack(); + await expect(d.getByRole("heading", { name: "Схема свода" })).toBeVisible(); + await expect(d.locator("pre.body, pre.description")).toHaveCount(0); // после перехода всё снова отрендерено +}); + test("несохранённая заметка: Esc спрашивает, «Остаться» оставляет окно, «Уйти» закрывает", async ({ page }) => { await login(page, "/app/issues"); await page.getByRole("link", { name: "AURORA-9003", exact: true }).click(); @@ -118,4 +146,7 @@ test("узкий экран: окно на всю ширину, заметки const linksY = (await d.getByRole("heading", { name: "Связи", exact: true }).boundingBox())!.y; expect(notesY).toBeLessThan(linksY); expect(await d.evaluate((el) => el.scrollWidth <= el.clientWidth + 1)).toBe(true); + await d.getByRole("button", { name: "развернуть" }).click(); // широкая таблица описания прокручивается внутри + await expect(d.getByRole("columnheader", { name: "Источник" })).toBeAttached(); + expect(await d.evaluate((el) => el.scrollWidth <= el.clientWidth + 1)).toBe(true); }); diff --git a/web/scripts/seed-extras.json b/web/scripts/seed-extras.json index 38d6f01..75de19d 100644 --- a/web/scripts/seed-extras.json +++ b/web/scripts/seed-extras.json @@ -1,10 +1,10 @@ { "issues": { "AURORA-9001": { - "description": "Цель: схема свода для КФО.\nКонтекст: ТЗ 6.4.\nШаг 1 — таблицы.\nШаг 2 — связи.\nШаг 3 — индексы.\nШаг 4 — миграции.\nШаг 5 — проверки.\nШаг 6 — документация.\nШаг 7 — ревью.\nШаг 8 — выкатка.\nШаг 9 — приёмка.\nКонец описания.", + "description": "h3. Контекст\nЦель: схема свода для *КФО*, поле {{data_type}}.\n\nh3. Шаги\n# Таблицы.\n# Связи.\n# Индексы.\n# Миграции.\n# Проверки.\n\n||Поле||Тип||Описание поля, достаточно длинное, чтобы таблица была шире узкого экрана||Источник||\n|data_type|varchar|вид данных строки: количество, валюта, налоговый учёт или бухгалтерский учёт|ОСВ|\n\nКонец описания.", "comments": [ - {"id": "501", "author": "Петров Пётр Петрович", "created": "2026-10-13T10:00:00.000+0300", "updated": "2026-10-13T10:00:00.000+0300", "body": "Первый комментарий e2e\nвторая строка"}, - {"id": "502", "author": "Иванов Иван Иванович", "created": "2026-10-14T11:30:00.000+0300", "updated": "2026-10-14T12:00:00.000+0300", "body": "Схему согласовали с аналитиком."}, + {"id": "501", "author": "Петров Пётр Петрович", "created": "2026-10-13T10:00:00.000+0300", "updated": "2026-10-13T10:00:00.000+0300", "body": "*Первый комментарий e2e*\nвторая строка"}, + {"id": "502", "author": "Иванов Иван Иванович", "created": "2026-10-14T11:30:00.000+0300", "updated": "2026-10-14T12:00:00.000+0300", "body": "Схему согласовали, см. AURORA-9002."}, {"id": "503", "author": null, "created": "2026-10-15T09:15:00.000+0300", "updated": "2026-10-15T09:15:00.000+0300", "body": "[мост] служебный комментарий"} ] }