You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
3.1 KiB
TypeScript
67 lines
3.1 KiB
TypeScript
// frontend/playwright/connectors.spec.ts — phase-13 외부 연동(연결 관리) E2E
|
|
// 연결 상태 표시 → 동기화 → 해제 → 임포트(미지원 graceful) + a11y.
|
|
import AxeBuilder from "@axe-core/playwright";
|
|
import { expect, test } from "@playwright/test";
|
|
|
|
import { resetSeed } from "./fixtures/seed-reset";
|
|
|
|
test.describe.configure({ mode: "serial" });
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
await resetSeed();
|
|
await page.goto("/life");
|
|
// 라이프 모듈 레일에서 '연결' 모듈로 전환
|
|
await page.locator(".subnav .mod-row", { hasText: "외부 데이터 소스" }).click();
|
|
await expect(page.getByRole("heading", { name: "연결된 데이터 소스" })).toBeVisible();
|
|
});
|
|
|
|
test("14개 커넥터 카드 + 12/14 연결됨 + 미연결 카드 표시", async ({ page }) => {
|
|
await expect(page.locator(".cn-grid .cn-card")).toHaveCount(14);
|
|
await expect(page.locator(".cn-count")).toHaveText("12/14 연결됨");
|
|
|
|
// Google Fit / KB증권 은 미연결(off + '연결 안 됨')
|
|
const fit = page.locator(".cn-card", { hasText: "Google Fit" });
|
|
await expect(fit).toHaveClass(/off/);
|
|
await expect(fit.locator(".cs-badge")).toContainText("연결 안 됨");
|
|
|
|
// 우리카드는 연결됨(동기화/해제 액션)
|
|
const woori = page.locator(".cn-card", { hasText: "우리카드" });
|
|
await expect(woori.getByRole("button", { name: /동기화/ })).toBeVisible();
|
|
await expect(woori.getByRole("button", { name: /해제/ })).toBeVisible();
|
|
});
|
|
|
|
test("동기화 → 토스트 노출", async ({ page }) => {
|
|
const work = page.locator(".cn-card", { hasText: "회사" }).first();
|
|
await work.getByRole("button", { name: /동기화/ }).click();
|
|
await expect(page.locator(".au-toast")).toContainText("새 항목");
|
|
});
|
|
|
|
test("연결 해제 → 미연결 상태로 전환", async ({ page }) => {
|
|
const toss = page.locator(".cn-card", { hasText: "토스" });
|
|
await expect(toss).not.toHaveClass(/off/);
|
|
await toss.getByRole("button", { name: /해제/ }).click();
|
|
await expect(page.locator(".au-toast")).toContainText("연결을 해제");
|
|
await expect(toss).toHaveClass(/off/);
|
|
await expect(toss.locator(".cs-badge")).toContainText("연결 안 됨");
|
|
await expect(toss.getByRole("button", { name: /연결$/ })).toBeVisible(); // [연결] 으로 전환
|
|
});
|
|
|
|
test("파일 가져오기 — 미지원 소스(mock)는 안내 토스트", async ({ page }) => {
|
|
// 기본 env(mock)에서 mock 커넥터는 import 미지원 → 400 → graceful 토스트
|
|
const kakao = page.locator(".cn-card", { hasText: "카카오뱅크" });
|
|
await kakao.locator('input[type="file"]').setInputFiles({
|
|
name: "statement.csv",
|
|
mimeType: "text/csv",
|
|
buffer: Buffer.from("거래일,가맹점,금액\n2026-06-08,쿠팡,23900\n"),
|
|
});
|
|
await expect(page.locator(".au-toast")).toContainText("가져오기를 지원하지 않아요");
|
|
});
|
|
|
|
test("연결 모듈 a11y — 위반 0건", async ({ page }) => {
|
|
const r = await new AxeBuilder({ page })
|
|
.withTags(["wcag2a", "wcag2aa", "wcag21aa"])
|
|
.disableRules(["color-contrast"])
|
|
.analyze();
|
|
expect(r.violations, JSON.stringify(r.violations, null, 2)).toEqual([]);
|
|
});
|