From 28fc1e9800a7bdff14c5079691040be1fdcc90b1 Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Sat, 25 Jul 2026 19:49:20 +0900 Subject: [PATCH] test(wbs-ux): implement Playwright E2E tests for Vue template navigation validation --- src/frontend/e2e/template-navigation.spec.ts | 18 ++++++ src/frontend/package-lock.json | 64 ++++++++++++++++++++ src/frontend/package.json | 3 +- src/frontend/playwright.config.ts | 28 +++++++++ 4 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 src/frontend/e2e/template-navigation.spec.ts create mode 100644 src/frontend/playwright.config.ts diff --git a/src/frontend/e2e/template-navigation.spec.ts b/src/frontend/e2e/template-navigation.spec.ts new file mode 100644 index 00000000..dd0dca4f --- /dev/null +++ b/src/frontend/e2e/template-navigation.spec.ts @@ -0,0 +1,18 @@ +import { test, expect } from '@playwright/test'; + +test.describe('Vite SPA 어드민 템플릿 네비게이션 E2E 테스트', () => { + test('프로토타입 갤러리 진입 및 카드 목록 확인', async ({ page }) => { + // 1. 로컬 개발 서버 진입 + await page.goto('http://localhost:5173/templates'); + + // 2. 갤러리 타이틀 렌더링 확인 + const header = page.locator('h2'); + await expect(header).toContainText('상용화 프로토타입 템플릿 갤러리'); + + // 3. 카드 수 검증 (9대 템플릿) + const cardLinks = page.locator('a:has-text("템플릿 화면 보기")'); + await expect(cardLinks).toHaveCount(9); + + console.log('✓ E2E 검증 통과: 9대 CRUD/엑셀/OLAP 프로토타입 카드가 100% 정상 활성화되었습니다.'); + }); +}); diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index bd2b898b..8c8ac11f 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -19,6 +19,7 @@ "xlsx": "^0.18.5" }, "devDependencies": { + "@playwright/test": "^1.62.0", "@types/node": "^24.13.2", "@vitejs/plugin-vue": "^6.0.7", "@vue/test-utils": "^2.4.6", @@ -752,6 +753,22 @@ "node": ">=14" } }, + "node_modules/@playwright/test": { + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.62.0.tgz", + "integrity": "sha512-9zOJ6ZQRAena31MpOH9VSzIz8Ou3YJ/wtY/eQm5T2uhfhG7/U3COrMS8xOtUrZrp9OgdmzEnIYODye3nY1VqzA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.62.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/@primeuix/styled": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.5.1.tgz", @@ -3450,6 +3467,53 @@ } } }, + "node_modules/playwright": { + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.62.0.tgz", + "integrity": "sha512-Z14dG305dgaLu6foB1TXQagFiW8JfSUIUaUuPaKQ6NtBPKF1P/qXcqfh6c6K/icPqdy37JmjbiBXf6JNg6Sylw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.62.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.62.0.tgz", + "integrity": "sha512-nsNRyq0r2zsG8AcRHWknc9QRA5XCueC7gWMrs+Gx2tlZn9hcl8zudfh00lhJPY1DE7NmZ6bDsT9g2yey8mXljA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/postcss": { "version": "8.5.21", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.21.tgz", diff --git a/src/frontend/package.json b/src/frontend/package.json index 59104ae2..45431f5a 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -20,8 +20,8 @@ "vue-router": "^4.6.4", "xlsx": "^0.18.5" }, - "devDependencies": { + "@playwright/test": "^1.62.0", "@types/node": "^24.13.2", "@vitejs/plugin-vue": "^6.0.7", "@vue/test-utils": "^2.4.6", @@ -33,4 +33,3 @@ "vue-tsc": "^3.3.5" } } - diff --git a/src/frontend/playwright.config.ts b/src/frontend/playwright.config.ts new file mode 100644 index 00000000..1b028569 --- /dev/null +++ b/src/frontend/playwright.config.ts @@ -0,0 +1,28 @@ +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: './e2e', + timeout: 30 * 1000, + expect: { + timeout: 5000 + }, + fullyParallel: true, + reporter: 'list', + use: { + actionTimeout: 0, + trace: 'on-first-retry', + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + ], + webServer: { + command: 'npm run dev', + url: 'http://localhost:5173', + reuseExistingServer: true, + timeout: 10 * 1000 + } +}); +