From d2575c9b19c338cbbbcb665237ce52cb25683df4 Mon Sep 17 00:00:00 2001 From: Jaybe Date: Mon, 17 Nov 2025 18:01:08 +0900 Subject: [PATCH] =?UTF-8?q?E2E=20=EC=8A=A4=EB=AA=A8=ED=81=AC:=20WYSIWYG=20?= =?UTF-8?q?=EA=B0=80=EC=9D=B4=EB=93=9C=20=ED=86=A0=EA=B8=80=20=EB=B0=8F=20?= =?UTF-8?q?=EB=A9=80=ED=8B=B0=EC=84=A0=ED=83=9D=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=A6=AC=EC=A0=84=20=EA=B2=80=EC=A6=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../export.css.regression.snapshot.test.ts | 34 +++++++++++++++++ tests/e2e/wysiwyg-guides-multiselect.e2e.ts | 38 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 lib/wysiwyg/export.css.regression.snapshot.test.ts create mode 100644 tests/e2e/wysiwyg-guides-multiselect.e2e.ts diff --git a/lib/wysiwyg/export.css.regression.snapshot.test.ts b/lib/wysiwyg/export.css.regression.snapshot.test.ts new file mode 100644 index 0000000..40b0697 --- /dev/null +++ b/lib/wysiwyg/export.css.regression.snapshot.test.ts @@ -0,0 +1,34 @@ +import { describe, it, expect } from 'vitest' +import { exportFrame } from '@/lib/wysiwyg/export' +import type { Frame } from '@/lib/wysiwyg/schema' + +function baseFrame(bg = '#111111'): Frame { + return { + id: 'f', width: 320, height: 200, background: bg, + layers: [{ id: 'l1', name: 'Base', visible: true, locked: false, objects: [] }], + } +} + +describe('wysiwyg export - CSS regression (tokens + rules presence)', () => { + it('contains core tokens and rules across themes and states', () => { + const out = exportFrame(baseFrame('#222222')) + const css = out.css + // root and theme tokens + expect(css).toMatch(/:root\s*{[^}]*--bg:/) + expect(css).toMatch(/\[data-theme="light"\]\s*{[^}]*--bg:/) + expect(css).toMatch(/\[data-theme="dark"\]\s*{[^}]*--bg:/) + // base usage + expect(css).toMatch(/\.frame\s*{[^}]*background:var\(--bg\)/) + expect(css).toMatch(/a\s*{[^}]*color:var\(--primary\)/) + // controls base + expect(css).toMatch(/input,select,textarea\s*{[^}]*color:var\(--text\)/) + expect(css).toMatch(/input,select,textarea\s*{[^}]*border:1px solid var\(--border\)/) + // states + expect(css).toMatch(/input:focus,select:focus,textarea:focus\s*{[^}]*outline:2px solid var\(--primary\)/) + expect(css).toMatch(/:focus-visible\s*{[^}]*outline:2px solid var\(--ring\)/) + expect(css).toMatch(/:focus-visible\s*{[^}]*outline-offset:var\(--ring-offset\)/) + expect(css).toMatch(/input:invalid,select:invalid,textarea:invalid\s*{[^}]*border-color:var\(--danger\)/) + expect(css).toMatch(/input:disabled,select:disabled,textarea:disabled\s*{[^}]*background:var\(--disabled-bg\)/) + expect(css).toMatch(/input\[readonly\],select\[readonly\],textarea\[readonly\]\s*{[^}]*color:var\(--disabled-fg\)/) + }) +}) diff --git a/tests/e2e/wysiwyg-guides-multiselect.e2e.ts b/tests/e2e/wysiwyg-guides-multiselect.e2e.ts new file mode 100644 index 0000000..f3983b5 --- /dev/null +++ b/tests/e2e/wysiwyg-guides-multiselect.e2e.ts @@ -0,0 +1,38 @@ +import { test, expect } from '@playwright/test' + +const wysiwygUrl = '/en/wysiwyg' + +test.describe('WYSIWYG - Guides toggle and multiselect live region', () => { + test('toggles guides and announces multiselect in aria-live', async ({ page }) => { + await page.goto(wysiwygUrl) + + // Canvas and live region present + const canvas = page.getByTestId('wysiwyg-canvas') + await expect(canvas).toBeVisible() + const live = page.getByTestId('aria-live') + await expect(live).toContainText(/선택\s*0개/) + + // Add two text objects + const addText = page.getByRole('button', { name: /^Add Text$/i }) + await addText.click() + await addText.click() + + // Marquee select both + const box = await canvas.boundingBox() + if (!box) throw new Error('canvas not found') + await page.mouse.move(box.x + 40, box.y + 40) + await page.mouse.down() + await page.mouse.move(box.x + 300, box.y + 200) + await page.mouse.up() + + await expect(live).toContainText(/선택\s*2개/) + + // Guides toggle + const guidesBtn = page.getByRole('button', { name: /Guides/i }) + await expect(guidesBtn).toHaveAttribute('aria-pressed', 'true') + await guidesBtn.click() + await expect(guidesBtn).toHaveAttribute('aria-pressed', 'false') + await guidesBtn.click() + await expect(guidesBtn).toHaveAttribute('aria-pressed', 'true') + }) +}) -- 2.52.0