diff --git a/.gitignore b/.gitignore index 002bc35..82cb425 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,7 @@ next-env.d.ts # storybook /storybook-static +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/jest.config.ts b/jest.config.ts index c356d49..a11989f 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -8,7 +8,11 @@ const createJestConfig = nextJest({ // Add any custom config to be passed to Jest const config: Config = { - collectCoverageFrom: ['src/**/*.ts*'], + collectCoverageFrom: [ + 'src/**/*.ts*', + '!src/app/**/layout.tsx', + '!src/app/**/page.tsx', + ], coveragePathIgnorePatterns: [ 'src/components/*', 'src/lib/prisma.ts', @@ -18,6 +22,7 @@ const config: Config = { '/test-setup/fetch-polyfill.setup.ts', '/test-setup/prisma-mock.setup.ts', ], + testPathIgnorePatterns: ['/tests/'], }; // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async diff --git a/package.json b/package.json index 7c95b0a..513e1e1 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "zod-validation-error": "3.0.0" }, "devDependencies": { + "@playwright/test": "1.41.2", "@storybook/addon-essentials": "7.6.10", "@storybook/addon-interactions": "7.6.10", "@storybook/addon-links": "7.6.10", @@ -43,8 +44,6 @@ "@storybook/nextjs": "7.6.10", "@storybook/react": "7.6.10", "@storybook/test": "7.6.10", - "@testing-library/jest-dom": "6.2.1", - "@testing-library/react": "14.1.2", "@types/jest": "29.5.11", "@types/lodash": "4.14.202", "@types/node": "20", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..779203d --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,78 @@ +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({ + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Run tests in files in parallel */ + fullyParallel: true, + + /* 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' }, + // }, + ], + + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + testDir: './tests', + /* 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', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + + /* 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/tests/app.spec.ts b/tests/app.spec.ts new file mode 100644 index 0000000..f8caebd --- /dev/null +++ b/tests/app.spec.ts @@ -0,0 +1,13 @@ +import { test, expect } from '@playwright/test'; + +test.describe('app', () => { + test('functions properly', async ({ page }) => { + await page.goto('/'); + + await expect(page.getByRole('main')).toHaveText('Welcome'); + + await page.getByText('List').click(); + + await expect(page.getByRole('heading')).toHaveText('Books'); + }); +}); diff --git a/yarn.lock b/yarn.lock index f632ade..125962c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2512,6 +2512,17 @@ __metadata: languageName: node linkType: hard +"@playwright/test@npm:1.41.2": + version: 1.41.2 + resolution: "@playwright/test@npm:1.41.2" + dependencies: + playwright: "npm:1.41.2" + bin: + playwright: cli.js + checksum: 071fe307e7e46f550e8608ce3c2c207b7cfbda37b39f3dcbe3875eaa18e79f2a768a5795a8cfe21df9361ec63594de0359f5542dd3a3a7f6625300a98452a344 + languageName: node + linkType: hard + "@pmmmwh/react-refresh-webpack-plugin@npm:^0.5.11": version: 0.5.11 resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.11" @@ -4251,7 +4262,7 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:^9.0.0, @testing-library/dom@npm:^9.3.1": +"@testing-library/dom@npm:^9.3.1": version: 9.3.4 resolution: "@testing-library/dom@npm:9.3.4" dependencies: @@ -4267,39 +4278,6 @@ __metadata: languageName: node linkType: hard -"@testing-library/jest-dom@npm:6.2.1": - version: 6.2.1 - resolution: "@testing-library/jest-dom@npm:6.2.1" - dependencies: - "@adobe/css-tools": "npm:^4.3.2" - "@babel/runtime": "npm:^7.9.2" - aria-query: "npm:^5.0.0" - chalk: "npm:^3.0.0" - css.escape: "npm:^1.5.1" - dom-accessibility-api: "npm:^0.6.3" - lodash: "npm:^4.17.15" - redent: "npm:^3.0.0" - peerDependencies: - "@jest/globals": ">= 28" - "@types/bun": "*" - "@types/jest": ">= 28" - jest: ">= 28" - vitest: ">= 0.32" - peerDependenciesMeta: - "@jest/globals": - optional: true - "@types/bun": - optional: true - "@types/jest": - optional: true - jest: - optional: true - vitest: - optional: true - checksum: ade94aa06af3910e471f4728f300518f662fc745e95d158a6edf51223ad75b64e7a92714976bd8ab75ddc8b4b733dc53ece7f709a5ceeb365844b00ee1c4ff68 - languageName: node - linkType: hard - "@testing-library/jest-dom@npm:^6.1.3": version: 6.3.0 resolution: "@testing-library/jest-dom@npm:6.3.0" @@ -4333,20 +4311,6 @@ __metadata: languageName: node linkType: hard -"@testing-library/react@npm:14.1.2": - version: 14.1.2 - resolution: "@testing-library/react@npm:14.1.2" - dependencies: - "@babel/runtime": "npm:^7.12.5" - "@testing-library/dom": "npm:^9.0.0" - "@types/react-dom": "npm:^18.0.0" - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - checksum: b5b0990d3aa0ea8b37c55804e0d5d584fc638a5c7d4df90da9a0fdb00bc981b27b6991468b2dc719982a5d0b0107a41596063ce51ad519eeab47b22bc04d6779 - languageName: node - linkType: hard - "@testing-library/user-event@npm:14.3.0": version: 14.3.0 resolution: "@testing-library/user-event@npm:14.3.0" @@ -4808,7 +4772,7 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:18.2, @types/react-dom@npm:^18.0.0": +"@types/react-dom@npm:18.2": version: 18.2.18 resolution: "@types/react-dom@npm:18.2.18" dependencies: @@ -6203,6 +6167,7 @@ __metadata: version: 0.0.0-use.local resolution: "bookstore@workspace:." dependencies: + "@playwright/test": "npm:1.41.2" "@prisma/client": "npm:5.8.1" "@radix-ui/react-icons": "npm:1.3.0" "@radix-ui/react-slot": "npm:1.0.2" @@ -6213,8 +6178,6 @@ __metadata: "@storybook/nextjs": "npm:7.6.10" "@storybook/react": "npm:7.6.10" "@storybook/test": "npm:7.6.10" - "@testing-library/jest-dom": "npm:6.2.1" - "@testing-library/react": "npm:14.1.2" "@types/jest": "npm:29.5.11" "@types/lodash": "npm:4.14.202" "@types/node": "npm:20" @@ -9163,6 +9126,16 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" + dependencies: + node-gyp: "npm:latest" + checksum: be78a3efa3e181cda3cf7a4637cb527bcebb0bd0ea0440105a3bb45b86f9245b307dc10a2507e8f4498a7d4ec349d1910f4d73e4d4495b16103106e07eee735b + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": version: 2.3.3 resolution: "fsevents@npm:2.3.3" @@ -9173,6 +9146,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin": + version: 2.3.2 + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" @@ -12895,6 +12877,30 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.41.2": + version: 1.41.2 + resolution: "playwright-core@npm:1.41.2" + bin: + playwright-core: cli.js + checksum: 1e80a24b0e93dd5aa643fb926d23c055f2c1a0a1e711c0d798edcfd8c3e46a6716d4ca59d72ed076191e6c713d09a0f14387d96e60f5221abd4ff65aef1ac3b3 + languageName: node + linkType: hard + +"playwright@npm:1.41.2": + version: 1.41.2 + resolution: "playwright@npm:1.41.2" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.41.2" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 1b487387c1bc003291a9dbd098e8e3c6a31efbb4d7a2ce4f2bf9d5e7f9fbf4a406352ab70e5266eab9a2a858bd42d8955343ea30c0286c3912e81984aa0220a3 + languageName: node + linkType: hard + "pnp-webpack-plugin@npm:^1.7.0": version: 1.7.0 resolution: "pnp-webpack-plugin@npm:1.7.0"