diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 00000000..e72c072f --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,25 @@ +name: Playwright Tests +on: + pull_request: + branches: [ develop] +jobs: + playwright-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 ci #equivalent to npm ci + - name: Install Playwright Browsers #install browsers + run: pnpm playwright install --with-deps + - name: Run Playwright tests + run: pnpm playwright test + - uses: actions/upload-artifact@v4 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index a112a9b0..788ff8b0 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,8 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts -*storybook.log \ No newline at end of file +*storybook.log + +#playwright +/blob-report/ +/playwright/.cache/ diff --git a/README.md b/README.md index 4ad8f520..0a8386c1 100644 --- a/README.md +++ b/README.md @@ -103,3 +103,25 @@ Run Storybook in the project root ``` npm run storybook ``` + +## React Testing Library (RTL) && Jest + +Run RTL && Jest in the project root + +``` +pnpm test +``` + +## Playwright Testing + + +Run all Playwright tests + +``` +pnpm playwright test +``` + +Run single Playwright tests + +``` +pnpm playwright test (name of file) \ No newline at end of file diff --git a/package.json b/package.json index da9c88f2..ff4eba84 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,58 @@ { - "private": true, - "version": "0.1.0", - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "test": "jest --passWithNoTests", - "test:watch": "jest --watchAll --passWithNoTests", - "storybook-docs": "storybook dev --docs", - "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" - }, - "dependencies": { - "@radix-ui/react-slot": "^1.0.2", - "@supabase/ssr": "latest", - "@supabase/supabase-js": "latest", - "autoprefixer": "10.4.15", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.0", - "geist": "^1.2.2", - "lucide-react": "^0.312.0", - "next": "latest", - "postcss": "8.4.29", - "react": "18.2.0", - "react-dom": "18.2.0", - "tailwind-merge": "^2.2.2", - "tailwindcss": "3.3.3", - "tailwindcss-animate": "^1.0.7", - "typescript": "5.1.3" - }, - "devDependencies": { - "@chromatic-com/storybook": "^1.2.25", - "@storybook/addon-essentials": "^8.0.4", - "@storybook/addon-interactions": "^8.0.4", - "@storybook/addon-links": "^8.0.4", - "@storybook/addon-onboarding": "^8.0.4", - "@storybook/blocks": "^8.0.4", - "@storybook/nextjs": "^8.0.4", - "@storybook/react": "^8.0.4", - "@storybook/test": "^8.0.4", - "@testing-library/jest-dom": "^6.4.2", - "@testing-library/react": "^14.2.2", - "@testing-library/user-event": "^14.5.2", - "@types/jest": "^29.5.12", - "@types/node": "20.3.1", - "@types/react": "18.2.8", - "@types/react-dom": "18.2.5", - "encoding": "^0.1.13", - "jest": "^29.7.0", - "jest-environment-jsdom": "^29.7.0", - "storybook": "^8.0.4", - "ts-jest": "^29.1.2", - "ts-node": "^10.9.2", - "typescript": "5.1.3" - } + "private": true, + "version": "0.1.0", + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "test": "jest --passWithNoTests", + "test:watch": "jest --watchAll --passWithNoTests", + "storybook-docs": "storybook dev --docs", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" + }, + "dependencies": { + "@radix-ui/react-slot": "^1.0.2", + "@supabase/ssr": "latest", + "@supabase/supabase-js": "latest", + "autoprefixer": "10.4.15", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.0", + "geist": "^1.2.2", + "lucide-react": "^0.312.0", + "next": "latest", + "postcss": "8.4.29", + "react": "18.2.0", + "react-dom": "18.2.0", + "tailwind-merge": "^2.2.2", + "tailwindcss": "3.3.3", + "tailwindcss-animate": "^1.0.7", + "typescript": "5.1.3" + }, + "devDependencies": { + "@chromatic-com/storybook": "^1.2.25", + "@playwright/test": "^1.42.1", + "@storybook/addon-essentials": "^8.0.4", + "@storybook/addon-interactions": "^8.0.4", + "@storybook/addon-links": "^8.0.4", + "@storybook/addon-onboarding": "^8.0.4", + "@storybook/blocks": "^8.0.4", + "@storybook/nextjs": "^8.0.4", + "@storybook/react": "^8.0.4", + "@storybook/test": "^8.0.4", + "@testing-library/jest-dom": "^6.4.2", + "@testing-library/react": "^14.2.2", + "@testing-library/user-event": "^14.5.2", + "@types/jest": "^29.5.12", + "@types/node": "20.3.1", + "@types/react": "18.2.8", + "@types/react-dom": "18.2.5", + "encoding": "^0.1.13", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "storybook": "^8.0.4", + "ts-jest": "^29.1.2", + "ts-node": "^10.9.2", + "typescript": "5.1.3" + } } diff --git a/playwright-report/index.html b/playwright-report/index.html new file mode 100644 index 00000000..c3ea64de --- /dev/null +++ b/playwright-report/index.html @@ -0,0 +1,68 @@ + + + + + + + + + Playwright Test Report + + + + +
+ + + \ No newline at end of file diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000..c18f2181 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,51 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './', + /* 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: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + ], + +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3d335f06..3865477e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,6 +58,9 @@ devDependencies: '@chromatic-com/storybook': specifier: ^1.2.25 version: 1.2.25(react@18.2.0) + '@playwright/test': + specifier: ^1.42.1 + version: 1.42.1 '@storybook/addon-essentials': specifier: ^8.0.4 version: 8.0.4(@types/react@18.2.8)(encoding@0.1.13)(react-dom@18.2.0)(react@18.2.0) @@ -2127,6 +2130,14 @@ packages: requiresBuild: true optional: true + /@playwright/test@1.42.1: + resolution: {integrity: sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==} + engines: {node: '>=16'} + hasBin: true + dependencies: + playwright: 1.42.1 + dev: true + /@pmmmwh/react-refresh-webpack-plugin@0.5.11(react-refresh@0.14.0)(webpack@5.91.0): resolution: {integrity: sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ==} engines: {node: '>= 10.13'} @@ -5951,6 +5962,14 @@ packages: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true + /fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + /fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -8299,6 +8318,22 @@ packages: find-up: 6.3.0 dev: true + /playwright-core@1.42.1: + resolution: {integrity: sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==} + engines: {node: '>=16'} + hasBin: true + dev: true + + /playwright@1.42.1: + resolution: {integrity: sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==} + engines: {node: '>=16'} + hasBin: true + dependencies: + playwright-core: 1.42.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /pnp-webpack-plugin@1.7.0(typescript@5.1.3): resolution: {integrity: sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==} engines: {node: '>=6'} diff --git a/tests/example.spec.ts b/tests/example.spec.ts new file mode 100644 index 00000000..54a906a4 --- /dev/null +++ b/tests/example.spec.ts @@ -0,0 +1,18 @@ +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(); +});