apps/web: add playwright

This commit is contained in:
vchikalkin 2024-12-10 18:06:21 +03:00
parent 2b14158d29
commit db2727bed6
9 changed files with 151 additions and 5 deletions

5
apps/web/.gitignore vendored
View File

@ -34,3 +34,8 @@ yarn-error.log*
# typescript # typescript
*.tsbuildinfo *.tsbuildinfo
next-env.d.ts next-env.d.ts
node_modules/
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/

View File

@ -1,9 +1,17 @@
'use client';
import { Button } from '@repo/ui/components/ui/button'; import { Button } from '@repo/ui/components/ui/button';
import { useState } from 'react';
export default function Page() { export default function Page() {
const [clicked, setClicked] = useState(false);
function handleClick() {
setClicked(!clicked);
}
return ( return (
<main> <main>
<Button>Click me</Button> <Button onClick={() => handleClick()}>{clicked ? 'Clicked' : 'Click me'}</Button>
</main> </main>
); );
} }

View File

@ -11,7 +11,8 @@
"check-types": "tsc --noEmit", "check-types": "tsc --noEmit",
"lint-staged": "lint-staged", "lint-staged": "lint-staged",
"graphql:codegen": "graphql-codegen --config graphql.config.cjs", "graphql:codegen": "graphql-codegen --config graphql.config.cjs",
"test:unit": "vitest" "test:unit": "vitest",
"test:e2e": "playwright test"
}, },
"dependencies": { "dependencies": {
"@apollo/client": "catalog:", "@apollo/client": "catalog:",
@ -27,6 +28,7 @@
"@graphql-codegen/typescript": "catalog:", "@graphql-codegen/typescript": "catalog:",
"@graphql-codegen/typescript-operations": "catalog:", "@graphql-codegen/typescript-operations": "catalog:",
"@graphql-typed-document-node/core": "catalog:", "@graphql-typed-document-node/core": "catalog:",
"@playwright/test": "^1.49.1",
"@repo/eslint-config": "workspace:*", "@repo/eslint-config": "workspace:*",
"@repo/lint-staged-config": "workspace:*", "@repo/lint-staged-config": "workspace:*",
"@repo/typescript-config": "workspace:*", "@repo/typescript-config": "workspace:*",

View File

@ -0,0 +1,79 @@
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({
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: Boolean(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://127.0.0.1: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,
// },
});

View File

@ -0,0 +1,7 @@
import test, { expect } from '@playwright/test';
test('should navigate page and click button', async ({ page }) => {
await page.goto('http://localhost:3000/');
await page.getByRole('button', { name: 'Click me' }).click();
await expect(page.getByRole('button', { name: 'Clicked' })).toBeVisible();
});

View File

@ -6,5 +6,7 @@ export default defineConfig({
plugins: [tsconfigPaths(), react()], plugins: [tsconfigPaths(), react()],
test: { test: {
environment: 'jsdom', environment: 'jsdom',
exclude: ['**/e2e/**', '**/*.spec.ts'],
include: ['**/*.test.{ts,tsx}'],
}, },
}); });

View File

@ -9,7 +9,8 @@
"prepare": "husky", "prepare": "husky",
"lint-staged": "turbo lint-staged", "lint-staged": "turbo lint-staged",
"graphql:codegen": "turbo graphql:codegen", "graphql:codegen": "turbo graphql:codegen",
"test:unit": "turbo test:unit" "test:unit": "turbo test:unit",
"test:e2e": "turbo test:e2e"
}, },
"devDependencies": { "devDependencies": {
"husky": "catalog:", "husky": "catalog:",

43
pnpm-lock.yaml generated
View File

@ -148,7 +148,7 @@ importers:
version: 16.9.0 version: 16.9.0
next: next:
specifier: 'catalog:' specifier: 'catalog:'
version: 15.0.4(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) version: 15.0.4(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: react:
specifier: 'catalog:' specifier: 'catalog:'
version: 19.0.0 version: 19.0.0
@ -171,6 +171,9 @@ importers:
'@graphql-typed-document-node/core': '@graphql-typed-document-node/core':
specifier: 'catalog:' specifier: 'catalog:'
version: 3.2.0(graphql@16.9.0) version: 3.2.0(graphql@16.9.0)
'@playwright/test':
specifier: ^1.49.1
version: 1.49.1
'@repo/eslint-config': '@repo/eslint-config':
specifier: workspace:* specifier: workspace:*
version: link:../../packages/eslint-config version: link:../../packages/eslint-config
@ -1673,6 +1676,11 @@ packages:
resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
'@playwright/test@1.49.1':
resolution: {integrity: sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==}
engines: {node: '>=18'}
hasBin: true
'@radix-ui/react-compose-refs@1.1.0': '@radix-ui/react-compose-refs@1.1.0':
resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==}
peerDependencies: peerDependencies:
@ -3169,6 +3177,11 @@ packages:
fs.realpath@1.0.0: fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
fsevents@2.3.3: fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@ -4174,6 +4187,16 @@ packages:
resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==}
engines: {node: '>=10'} engines: {node: '>=10'}
playwright-core@1.49.1:
resolution: {integrity: sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==}
engines: {node: '>=18'}
hasBin: true
playwright@1.49.1:
resolution: {integrity: sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==}
engines: {node: '>=18'}
hasBin: true
pluralize@8.0.0: pluralize@8.0.0:
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -7055,6 +7078,10 @@ snapshots:
'@pkgr/core@0.1.1': {} '@pkgr/core@0.1.1': {}
'@playwright/test@1.49.1':
dependencies:
playwright: 1.49.1
'@radix-ui/react-compose-refs@1.1.0(@types/react@19.0.1)(react@19.0.0)': '@radix-ui/react-compose-refs@1.1.0(@types/react@19.0.1)(react@19.0.0)':
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
@ -8933,6 +8960,9 @@ snapshots:
fs.realpath@1.0.0: {} fs.realpath@1.0.0: {}
fsevents@2.3.2:
optional: true
fsevents@2.3.3: fsevents@2.3.3:
optional: true optional: true
@ -9687,7 +9717,7 @@ snapshots:
natural-orderby@5.0.0: {} natural-orderby@5.0.0: {}
next@15.0.4(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): next@15.0.4(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies: dependencies:
'@next/env': 15.0.4 '@next/env': 15.0.4
'@swc/counter': 0.1.3 '@swc/counter': 0.1.3
@ -9707,6 +9737,7 @@ snapshots:
'@next/swc-linux-x64-musl': 15.0.4 '@next/swc-linux-x64-musl': 15.0.4
'@next/swc-win32-arm64-msvc': 15.0.4 '@next/swc-win32-arm64-msvc': 15.0.4
'@next/swc-win32-x64-msvc': 15.0.4 '@next/swc-win32-x64-msvc': 15.0.4
'@playwright/test': 1.49.1
sharp: 0.33.5 sharp: 0.33.5
transitivePeerDependencies: transitivePeerDependencies:
- '@babel/core' - '@babel/core'
@ -9936,6 +9967,14 @@ snapshots:
dependencies: dependencies:
find-up: 5.0.0 find-up: 5.0.0
playwright-core@1.49.1: {}
playwright@1.49.1:
dependencies:
playwright-core: 1.49.1
optionalDependencies:
fsevents: 2.3.2
pluralize@8.0.0: {} pluralize@8.0.0: {}
possible-typed-array-names@1.0.0: {} possible-typed-array-names@1.0.0: {}

View File

@ -25,6 +25,9 @@
}, },
"test:unit": { "test:unit": {
"cache": false "cache": false
},
"test:e2e": {
"cache": false
} }
} }
} }