// frontend/playwright/journey.spec.ts — 여정(오늘의 흐름) E2E
// 문서 §9.1 테스팅 섹션 + 코너케이스(베지어 호버 강조, done 토글, 반응형) 포함.
import { test, expect } from "@playwright/test";

test.beforeEach(async ({ page }) => {
  await page.goto("/journey");
  await expect(page.getByRole("heading", { name: "오늘의 여정" })).toBeVisible();
});

test("헤더: 날짜·날씨 eyebrow + 타이틀", async ({ page }) => {
  await expect(page.locator(".ph-eyebrow")).toContainText("6월 10일 화요일");
  await expect(page.locator(".ph-eyebrow")).toContainText("맑음");
  await expect(page.getByPlaceholder("흐름에서 작업·사람 찾기…")).toBeVisible();
});

test("흐름 패널 라벨: 4단계 · 12개 항목 · 5명 협업", async ({ page }) => {
  const label = page.locator(".jx-label");
  await expect(label).toContainText("오늘의 흐름");
  await expect(label).toContainText("4단계");
  await expect(label).toContainText("12개 항목");
  await expect(label).toContainText("5명 협업");
});

test("4개 컬럼 스테이지 라벨 + 시간", async ({ page }) => {
  const labels = page.locator(".jx-labels .cl");
  await expect(labels).toHaveCount(4);
  await expect(labels.nth(0)).toContainText("아침 준비");
  await expect(labels.nth(1)).toContainText("오전 집중");
  await expect(labels.nth(2)).toContainText("오후 협업");
  await expect(labels.nth(3)).toContainText("마무리 & 내일");
  await expect(labels.nth(0)).toContainText("06:40");
});

test("피플 스택: 핵심 5인", async ({ page }) => {
  // 메일 발신자 제외, 핵심 5명만 (지/현/민/재/수) + '+3' more
  const avs = page.locator(".jx-stack .av");
  await expect(avs).toHaveCount(5);
  await expect(page.locator(".jx-stack .more")).toHaveText("+3");
  await expect(avs.nth(0)).toContainText("지");
  await expect(avs.nth(1)).toContainText("현");
});

test("베지어 커넥터: 8개 .jx-line 경로가 렌더된다", async ({ page }) => {
  // DOM 측정 후 RAF/폰트 로드까지 경로 계산이 끝나길 대기
  await expect.poll(async () => page.locator(".jx-svg .jx-line").count()).toBe(8);
  // svg 는 접근성 트리에서 숨김 + 카드 아래(z-index)
  await expect(page.locator(".jx-svg")).toHaveAttribute("aria-hidden", "true");
});

// phase-16+: 작업 시드 제거 → 카드 내용(작업 제목)·done 상태·라이브 동기화는
// 실제 작업이 있어야 검증 가능(노드 매핑 k1/k3 는 공개 API로 생성 불가) → 해당 테스트 제외.
// 여정의 구조(노드 카드·베지어·테이블 행/별·게이지·반응형)는 아래에서 계속 검증한다.

test("하단 작업 테이블: 5행 + 별 2개 on(구조)", async ({ page }) => {
  const rows = page.locator(".jtable tbody tr");
  await expect(rows).toHaveCount(5); // TABLE_ROWS 고정
  await expect(page.locator(".jtable .star.on")).toHaveCount(2);
});

test("지표 게이지 2개 + 풋 문구", async ({ page }) => {
  await expect(page.locator(".gauges .gauge")).toHaveCount(2);
  await expect(page.locator(".gauges")).toContainText("딥 워크");
  await expect(page.locator(".gauges")).toContainText("활동 링");
  await expect(page.locator(".gauge-foot")).toContainText("스트레칭");
});

test("힌트 문구 노출", async ({ page }) => {
  await expect(page.locator(".jx-hint")).toContainText("마우스를 올리면");
});

test("반응형: 720px 이하에서 베지어 svg 숨김", async ({ page }) => {
  await expect(page.locator(".jx-svg")).toBeVisible();
  await page.setViewportSize({ width: 700, height: 900 });
  await expect(page.locator(".jx-svg")).toBeHidden();
  await expect(page.locator(".jx-labels")).toBeHidden();
});

