diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 00000000..369dc723 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,39 @@ +name: Playwright Tests +on: + 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: setup environment + run: | + echo "TEST_IDP_EMAIL=${{ secrets.TEST_IDP_EMAIL }}" >> .env + echo "TEST_IDP_PASSWORD=${{ secrets.TEST_IDP_PASSWORD }}" >> .env + echo "NEXTAUTH_SECRET=${{ secrets.NEXTAUTH_SECRET }}" >> .env.production + echo "IDP_CLIENT_SECRET=${{ secrets.IDP_CLIENT_SECRET }}" >> .env.production + - name: Install dependencies + run: npm install -g yarn && yarn + - name: Install Playwright Browsers + run: yarn playwright install --with-deps + - name: Run Dev Server + run: | + yarn dev & + echo "Waiting for server to start..." + until curl -s http://localhost:3000 > /dev/null; do + echo "Server is not ready yet. Retrying in 2 seconds..." + sleep 2 + done + - 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 diff --git a/.gitignore b/.gitignore index 082fa3a6..24cfbfb6 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,8 @@ yarn-error.log* next-env.d.ts playwright test-results -playwright-report \ No newline at end of file +playwright-report +node_modules/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/README.md b/README.md index cdb2f8bd..6988e7bf 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,15 @@ yarn install yarn dev ``` +## Test + +Playwright를 이용하여 E2E 테스트를 진행하고 있습니다. + +```bash +yarn playwright test // 모든 테스트 실행 +yarn playwright test --ui // 테스트 콘솔 UI 실행 +``` + ## Misc 해당 프로젝트는 `.gitattributes` 파일에서 eol 설정을 `lf`로 하고 있습니다. diff --git a/package.json b/package.json index ecbb9e40..f0772abf 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "tinymce": "^6.8.3" }, "devDependencies": { + "@playwright/test": "^1.49.1", "@storybook/addon-essentials": "^8.1.2", "@storybook/addon-interactions": "^8.1.2", "@storybook/addon-links": "^8.1.2", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000..bf78b65a --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,83 @@ +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://127.0.0.1:3000', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'setups', + testMatch: /.*\.setup\.ts$/, + }, + { + 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' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + // webServer: { + // command: 'npm run start', + // url: 'http://127.0.0.1:3000', + // reuseExistingServer: !process.env.CI, + // }, +}); diff --git a/src/app/[lng]/(with-page-layout)/(with-sidebar-layout)/notice/[id]/Content.tsx b/src/app/[lng]/(with-page-layout)/(with-sidebar-layout)/notice/[id]/Content.tsx index c32a9ed2..f98e8773 100644 --- a/src/app/[lng]/(with-page-layout)/(with-sidebar-layout)/notice/[id]/Content.tsx +++ b/src/app/[lng]/(with-page-layout)/(with-sidebar-layout)/notice/[id]/Content.tsx @@ -7,6 +7,7 @@ interface ContentProps { const Content = ({ content }: ContentProps) => { return (