모바일 메뉴와 주요 화면 UX 개선 및 시각 검수

This commit is contained in:
Yun Chan 2026-09-12 17:57:59 +09:00
parent 89b5093ec7
commit e8b770e4d9
50 changed files with 3189 additions and 457 deletions

View file

@ -18,6 +18,8 @@
* ( , by ··, ,
* usage , · ) .
*/
import { mkdir } from "node:fs/promises";
import path from "node:path";
import { expect, test, type Page, type Route } from "@playwright/test";
const NOW = 1_755_400_000; // 2026-08-17 근처 고정 기준
@ -1442,4 +1444,78 @@ test.describe("관리자 콘솔 유스케이스 여정", () => {
}
expect((await protocolTab.boundingBox())?.height ?? 0).toBeGreaterThanOrEqual(44);
});
test("모바일 티켓 새로고침과 해결 처리가 동작한다 @single-run", async ({
page,
}) => {
const outputDir = path.resolve(
process.cwd(),
"../../outputs/ux-audit-2026-09-12/admin-ticket-targets",
);
await mkdir(outputDir, { recursive: true });
await page.setViewportSize({ width: 320, height: 844 });
await installAdminMock(page, {
tickets: [
makeTicket({
ticket_id: "ticket-mobile-active",
subject: "모바일 티켓 처리",
status: "open",
}),
makeTicket({
ticket_id: "ticket-mobile-history",
subject: "해결된 모바일 티켓",
status: "resolved",
resolved_at: NOW - 600,
}),
],
});
await page.goto("/admin/tickets");
const refresh = page
.locator('[data-admin-section="tickets"] .vgops-head')
.getByRole("button", { name: "새로고침" });
const activeCard = page.locator(".vgops-ticket").filter({
hasText: "모바일 티켓 처리",
});
await expect(refresh).toBeVisible();
await expect(activeCard).toBeVisible();
await page.screenshot({ path: path.join(outputDir, "tickets-top-320.png") });
const refreshBox = await refresh.boundingBox();
expect(refreshBox?.width ?? 0).toBeGreaterThanOrEqual(44);
expect(refreshBox?.height ?? 0).toBeGreaterThanOrEqual(44);
await page.setViewportSize({ width: 710, height: 844 });
const refreshAt720 = await refresh.boundingBox();
expect(refreshAt720?.width ?? 0).toBeGreaterThanOrEqual(44);
expect(refreshAt720?.height ?? 0).toBeGreaterThanOrEqual(44);
await page.setViewportSize({ width: 320, height: 844 });
const reload = page.waitForResponse(
(response) =>
response.request().method() === "GET" &&
new URL(response.url()).pathname.endsWith("/admin/tickets"),
);
await refresh.click();
await reload;
await expect(activeCard).toBeVisible();
const patch = page.waitForRequest(
(request) =>
request.method() === "PATCH" &&
request.url().includes("/admin/tickets/ticket-mobile-active"),
);
await activeCard.getByRole("button", { name: "해결" }).click();
await patch;
const history = page.locator(".vgops-ticket--history").filter({
hasText: "모바일 티켓 처리",
});
await expect(history).toBeVisible();
await history.scrollIntoViewIfNeeded();
await page.screenshot({ path: path.join(outputDir, "tickets-history-320.png") });
await expect
.poll(() =>
page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth),
)
.toBe(true);
});
});