diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 00000000..964692d4 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,28 @@ +name: Playwright Tests +on: + push: + branches: [master] + pull_request: + branches: [master] +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Install dependencies + run: npm install -g pnpm && pnpm install + - name: Install Playwright Browsers + run: pnpm exec playwright install --with-deps + working-directory: ./app/registry + - name: Run Playwright tests + run: turbo test:e2e + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/apps/registry/.gitignore b/apps/registry/.gitignore index 1437c53f..30dbebad 100644 --- a/apps/registry/.gitignore +++ b/apps/registry/.gitignore @@ -32,3 +32,7 @@ yarn-error.log* # vercel .vercel +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/apps/registry/package.json b/apps/registry/package.json index cf56750d..8d0cebb1 100644 --- a/apps/registry/package.json +++ b/apps/registry/package.json @@ -8,7 +8,8 @@ "start": "next start", "lint": "next lint --max-warnings=0", "postinstall": "prisma generate --data-proxy", - "db:generate": "prisma generate" + "db:generate": "prisma generate", + "test:e2e": "playwright test" }, "dependencies": { "@faker-js/faker": "^8.0.2", @@ -111,6 +112,9 @@ "uuid": "^9.0.0" }, "devDependencies": { - "eslint-config-custom": "workspace:*" + "@playwright/test": "^1.40.0", + "@types/node": "^20.10.0", + "eslint-config-custom": "workspace:*", + "playwright": "^1.40.0" } } diff --git a/apps/registry/playwright.config.js b/apps/registry/playwright.config.js new file mode 100644 index 00000000..b719d17a --- /dev/null +++ b/apps/registry/playwright.config.js @@ -0,0 +1,81 @@ +// @ts-check +const { defineConfig, devices } = require('@playwright/test'); + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * @see https://playwright.dev/docs/test-configuration + */ +module.exports = defineConfig({ + webServer: { + command: 'npm run dev', + }, + 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: '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/apps/registry/tests/example.spec.js b/apps/registry/tests/example.spec.js new file mode 100644 index 00000000..4d2c7595 --- /dev/null +++ b/apps/registry/tests/example.spec.js @@ -0,0 +1,9 @@ +// @ts-check +const { test, expect } = require('@playwright/test'); + +test('has title', async ({ page }) => { + await page.goto('http://localhost:3002/thomasdavis'); + + // Expect a title "to contain" a substring. + await expect(page).toHaveTitle(/Thomas Davis/); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 932ac396..0dab0025 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -324,9 +324,18 @@ importers: specifier: ^9.0.0 version: 9.0.0 devDependencies: + '@playwright/test': + specifier: ^1.40.0 + version: 1.40.0 + '@types/node': + specifier: ^20.10.0 + version: 20.10.0 eslint-config-custom: specifier: workspace:* version: link:../../packages/eslint-config-custom + playwright: + specifier: ^1.40.0 + version: 1.40.0 packages/eslint-config-custom: dependencies: @@ -1980,6 +1989,14 @@ packages: tslib: 2.5.0 dev: false + /@playwright/test@1.40.0: + resolution: {integrity: sha512-PdW+kn4eV99iP5gxWNSDQCbhMaDVej+RXL5xr6t04nbKLCBwYtA046t7ofoczHOm8u6c+45hpDKQVZqtqwkeQg==} + engines: {node: '>=16'} + hasBin: true + dependencies: + playwright: 1.40.0 + dev: true + /@primer/css@14.4.0: resolution: {integrity: sha512-o9DwcAH43jZNDC/rPLjsYTU/I1LsHIgIQlSO3X8vZV2u65LmWeA5jHI2cSadZYN3N0Gm0Soh0zVYuhh7kMskXA==} hasBin: true @@ -2061,6 +2078,12 @@ packages: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: false + /@types/node@20.10.0: + resolution: {integrity: sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==} + dependencies: + undici-types: 5.26.5 + dev: true + /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: false @@ -4948,7 +4971,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true - dev: false optional: true /fstream@1.0.12: @@ -8887,6 +8909,22 @@ packages: requiresBuild: true dev: false + /playwright-core@1.40.0: + resolution: {integrity: sha512-fvKewVJpGeca8t0ipM56jkVSU6Eo0RmFvQ/MaCQNDYm+sdvKkMBBWTE1FdeMqIdumRaXXjZChWHvIzCGM/tA/Q==} + engines: {node: '>=16'} + hasBin: true + dev: true + + /playwright@1.40.0: + resolution: {integrity: sha512-gyHAgQjiDf1m34Xpwzaqb76KgfzYrhK7iih+2IzcOCoZWr/8ZqmdBw+t0RU85ZmfJMgtgAiNtBQ/KS2325INXw==} + engines: {node: '>=16'} + hasBin: true + dependencies: + playwright-core: 1.40.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /pluralize@4.0.0: resolution: {integrity: sha512-yldjGERgycMeEPPtACWJe3sPwp4j0Jp1ae/z/JYcATdDqeV90gOSQaGFWsLDEh5R2boRF4iV0h+WCSQSz8Qxog==} dev: false @@ -10839,6 +10877,10 @@ packages: resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} dev: false + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + /unicode-canonical-property-names-ecmascript@2.0.0: resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} engines: {node: '>=4'} diff --git a/turbo.json b/turbo.json index 16dec3b7..f1cb0219 100644 --- a/turbo.json +++ b/turbo.json @@ -14,6 +14,10 @@ "dev": { "cache": false, "persistent": true + }, + "test:e2e": { + "cache": false, + "persistent": true } }, "globalEnv": [