Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm install -g yarn && yarn
- name: Install Playwright Browsers
run: yarn playwright install --with-deps
- name: Run Playwright tests
run: yarn playwright test
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 30
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,12 @@ yarn-error.log*
*storybook.log
storybook-static

.docs
.docs
.claude

# Playwright
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
/playwright/.auth/
13 changes: 12 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@
"lint": "eslint",
"api": "dotenv -e .env -- sh -c 'openapi-typescript \"$API_DOCS_URL\" -o src/shared/api/openapi/generated.ts'",
"svgr": "npx @svgr/cli -d src/shared/ui/icons --typescript --no-dimensions public/icons",
"test": "vitest --project unit",
"test:watch": "vitest --watch --project unit",
"test:storybook": "vitest --project storybook",
"test:storybook:watch": "vitest --watch --project storybook",
"test:all": "vitest",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
"build-storybook": "storybook build",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui"
},
"dependencies": {
"@hookform/resolvers": "^5.2.2",
Expand All @@ -31,6 +38,7 @@
"devDependencies": {
"@chromatic-com/storybook": "^5.0.0",
"@hookform/devtools": "^4.4.0",
"@playwright/test": "^1.59.1",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

@playwright/test 버전이 프로젝트에 이미 설치된 playwright 패키지 버전(1.58.1)과 다릅니다. 두 패키지의 버전이 일치하지 않으면 예기치 않은 동작이 발생할 수 있으므로 버전을 맞추는 것이 좋습니다.

Suggested change
"@playwright/test": "^1.59.1",
"@playwright/test": "^1.58.1",

"@storybook/addon-a11y": "^10.2.4",
"@storybook/addon-docs": "^10.2.4",
"@storybook/addon-vitest": "^10.2.4",
Expand All @@ -39,6 +47,7 @@
"@tailwindcss/postcss": "^4",
"@tanstack/eslint-plugin-query": "^5.91.2",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.0",
"@types/node": "^20",
"@types/react": "^19.2.7",
Expand All @@ -49,6 +58,8 @@
"eslint": "^9",
"eslint-config-next": "16.0.7",
"eslint-plugin-storybook": "^10.2.4",
"jsdom": "^29.0.2",
"msw": "^2.13.2",
"playwright": "^1.58.1",
"storybook": "^10.2.4",
"tailwindcss": "^4",
Expand Down
80 changes: 80 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { defineConfig, devices } from "@playwright/test";

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// import dotenv from 'dotenv';
// import path from 'path';
// dotenv.config({ path: path.resolve(__dirname, '.env') });

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: "./tests",
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('')`. */
// baseURL: 'http://localhost:3000',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

baseURL을 설정하면 테스트 코드에서 await page.goto('/')와 같이 상대 경로를 사용할 수 있어 유지보수가 쉬워집니다. 아래 webServer 설정의 URL과 일치하도록 설정하는 것을 권장합니다.

Suggested change
// baseURL: 'http://localhost:3000',
baseURL: 'http://localhost:3000',


/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
actionTimeout: 10000, //10초
},

/* Configure projects for major browsers */
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},

{
name: "firefox",
use: { ...devices["Desktop Firefox"] },
},

{
name: "webkit",
use: { ...devices["Desktop Safari"] },
},

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],

/* 테스트 전 서버 실행 */
webServer: {
command: "yarn dev",
url: "http://localhost:3000",
reuseExistingServer: !process.env.CI,
},
});
1 change: 1 addition & 0 deletions src/app/mocks/handlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const handlers = [];
4 changes: 4 additions & 0 deletions src/app/mocks/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { setupServer } from "msw/node";
import { handlers } from "./handlers";

export const server = setupServer(...handlers);
20 changes: 20 additions & 0 deletions tests/example.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { test, expect } from "@playwright/test";

test("has title", async ({ page }) => {
await page.goto("https://playwright.dev/");

// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
});

test("get started link", async ({ page }) => {
await page.goto("https://playwright.dev/");

// Click the get started link.
await page.getByRole("link", { name: "Get started" }).click();

// Expects page to have a heading with the name of Installation.
await expect(
page.getByRole("heading", { name: "Installation" }),
).toBeVisible();
});
11 changes: 11 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url';

import { defineConfig } from 'vitest/config';
import tsconfigPaths from 'vite-tsconfig-paths';

import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';

Expand All @@ -14,6 +15,16 @@ const dirname =
export default defineConfig({
test: {
projects: [
{
extends: true,
plugins: [tsconfigPaths()],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

tsconfigPaths() 플러그인이 unit 프로젝트에만 적용되어 있습니다. 만약 Storybook 테스트에서도 TypeScript 경로 별칭(path alias)을 사용한다면, 해당 프로젝트 설정에도 추가하거나 공통 플러그인으로 설정하는 것이 좋습니다.

test: {
name: 'unit',
environment: 'jsdom',
include: ['src/**/*.test.{ts,tsx}'],
setupFiles: ['./vitest.setup.ts'],
},
},
{
extends: true,
plugins: [
Expand Down
17 changes: 17 additions & 0 deletions vitest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { server } from "@app/mocks/server";
import "@testing-library/jest-dom/vitest";

import { vi } from "vitest";
import { afterAll, afterEach, beforeAll } from "vitest";

const useRouter = vi.fn(() => {
push: vi.fn();
});
Comment on lines +7 to +9

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

useRouter 모의(mock) 함수가 객체를 반환하지 않고 undefined를 반환하고 있습니다. 화살표 함수에서 객체 리터럴을 반환하려면 소괄호 ()로 감싸야 합니다. 현재 상태로는 테스트에서 router.push() 등을 호출할 때 오류가 발생합니다.

Suggested change
const useRouter = vi.fn(() => {
push: vi.fn();
});
const useRouter = vi.fn(() => ({
push: vi.fn(),
}));


vi.mock("next/navigation", () => ({
useRouter,
}));

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
Loading
Loading