test(ai-character): 리소스 운영 E2E 보강
This commit is contained in:
83
tests/e2e/responsive-capabilities.spec.ts
Normal file
83
tests/e2e/responsive-capabilities.spec.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import type { Locator, Page } from "@playwright/test";
|
||||
|
||||
type ViewportCase = {
|
||||
readonly height: number;
|
||||
readonly name: string;
|
||||
readonly width: number;
|
||||
};
|
||||
|
||||
const viewports = [
|
||||
{ height: 640, name: "mobile 320", width: 320 },
|
||||
{ height: 640, name: "mobile 640", width: 640 },
|
||||
{ height: 900, name: "tablet 768", width: 768 },
|
||||
{ height: 900, name: "desktop 1024", width: 1024 },
|
||||
{ height: 900, name: "desktop 1280", width: 1280 },
|
||||
{ height: 390, name: "mobile landscape", width: 844 },
|
||||
] as const satisfies readonly ViewportCase[];
|
||||
|
||||
async function loginThroughMockMode(page: Page): Promise<void> {
|
||||
await page.goto("/login");
|
||||
await page.getByLabel("이메일").fill("admin@test.com");
|
||||
await page.getByLabel("비밀번호").fill("password");
|
||||
await page.getByRole("button", { name: "로그인" }).click();
|
||||
await expect(page).toHaveURL(/\/ai-characters$/);
|
||||
}
|
||||
|
||||
async function expectNoHorizontalOverflow(page: Page): Promise<void> {
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth > document.documentElement.clientWidth)).toBe(false);
|
||||
}
|
||||
|
||||
async function expectTouchTarget(locator: Locator): Promise<void> {
|
||||
const box = await locator.boundingBox();
|
||||
|
||||
expect(box).not.toBeNull();
|
||||
expect(box?.height ?? 0).toBeGreaterThanOrEqual(44);
|
||||
}
|
||||
|
||||
test("mock shell stays usable across the P9 viewport matrix", async ({ page }) => {
|
||||
// Given
|
||||
await loginThroughMockMode(page);
|
||||
|
||||
for (const viewport of viewports) {
|
||||
// When
|
||||
await page.setViewportSize(viewport);
|
||||
await page.goto("/ai-characters");
|
||||
|
||||
// Then
|
||||
await expect(page.getByRole("main", { name: "AI 캐릭터 관리" })).toBeVisible();
|
||||
await expect(page.getByRole("status", { name: /Mock Preview/ })).toBeVisible();
|
||||
await expectNoHorizontalOverflow(page);
|
||||
if (viewport.width < 768) {
|
||||
await expectTouchTarget(page.getByRole("button", { name: "모바일 메뉴 열기" }));
|
||||
await expectTouchTarget(page.getByRole("button", { name: "로그아웃" }));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("route capability matches mobile read-only and tablet desktop management rules", async ({ page }) => {
|
||||
// Given
|
||||
await loginThroughMockMode(page);
|
||||
|
||||
// When / Then
|
||||
await page.setViewportSize({ width: 320, height: 640 });
|
||||
await page.goto("/ai-characters/101/audio-contents/new");
|
||||
await expect(page.getByText(/데스크톱.*(생성|업로드|이용)/)).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "생성" })).toBeHidden();
|
||||
|
||||
await page.goto("/ai-characters/101/community-posts/new");
|
||||
await expect(page.getByRole("heading", { name: "모바일에서는 커뮤니티 게시글 생성을 제한합니다" })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "생성" })).toBeHidden();
|
||||
|
||||
await page.goto("/ai-characters/101/fan-talks");
|
||||
await expect(page.getByRole("button", { name: "첫 번째 응원입니다. 답변하기" })).toBeVisible();
|
||||
|
||||
await page.setViewportSize({ width: 768, height: 900 });
|
||||
await page.goto("/ai-characters/101/community-posts");
|
||||
await expect(page.getByRole("link", { name: "커뮤니티 게시글 생성" })).toBeVisible();
|
||||
|
||||
await page.setViewportSize({ width: 1280, height: 900 });
|
||||
await page.goto("/ai-characters/101/series/5001");
|
||||
await expect(page.getByRole("searchbox", { name: "검색어" })).toBeVisible();
|
||||
await expectNoHorizontalOverflow(page);
|
||||
});
|
||||
Reference in New Issue
Block a user