diff --git a/.gitignore b/.gitignore index 58ad0908..8a105f08 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ /dist/*.mts /dist/stats.json /dist/example-assets/migrations.js +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/e2e/demo.spec.ts b/e2e/demo.spec.ts new file mode 100644 index 00000000..2cbffa02 --- /dev/null +++ b/e2e/demo.spec.ts @@ -0,0 +1,9 @@ +import {test, expect} from '@playwright/test'; + +test.describe('Demo page', () => { + // A very basic test to assess the availability of the dev server. + test('should have a title', async ({page}) => { + await page.goto('/'); + await expect(page).toHaveTitle(/Orejime/); + }); +}); diff --git a/package-lock.json b/package-lock.json index a36ad07c..077097f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "js-cookie": "^3.0.1" }, "devDependencies": { + "@playwright/test": "^1.48.0", "@rspack/cli": "^1.0.3", "@rspack/core": "^1.0.3", "@swc/core": "^1.7.23", @@ -21,6 +22,7 @@ "@types/jest": "^27.5.0", "@types/js-cookie": "^3.0.2", "@types/micromodal": "^0.3.5", + "@types/node": "^22.7.5", "cross-env": "^5.2.0", "css-loader": "^0.28.11", "jest": "^28.1.3", @@ -37,8 +39,8 @@ "uneval.js": "^5.7.2" }, "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" + "react": ">=18", + "react-dom": ">=18" } }, "node_modules/@ampproject/remapping": { @@ -2406,6 +2408,21 @@ "node": ">=14" } }, + "node_modules/@playwright/test": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.0.tgz", + "integrity": "sha512-W5lhqPUVPqhtc/ySvZI5Q8X2ztBOUgZ8LbAFy0JQgrXZs2xaILrUcNO3rQjwbLPfGK13+rZsDa1FpG+tqYkT5w==", + "dev": true, + "dependencies": { + "playwright": "1.48.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.25", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", @@ -3174,11 +3191,10 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.5.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", - "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", "dev": true, - "license": "MIT", "dependencies": { "undici-types": "~6.19.2" } @@ -10856,6 +10872,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11114,6 +11131,50 @@ "node": ">= 6" } }, + "node_modules/playwright": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.0.tgz", + "integrity": "sha512-qPqFaMEHuY/ug8o0uteYJSRfMGFikhUysk8ZvAtfKmUK3kc/6oNl/y3EczF8OFGYIi/Ex2HspMfzYArk6+XQSA==", + "dev": true, + "dependencies": { + "playwright-core": "1.48.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.0.tgz", + "integrity": "sha512-RBvzjM9rdpP7UUFrQzRwR8L/xR4HyC1QXMzGYTbf1vjw25/ya9NRAVnXi/0fvFopjebvyPzsmoK58xxeEOaVvA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/postcss": { "version": "8.4.45", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", @@ -13729,18 +13790,6 @@ "node": ">= 6" } }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", - "peer": true, - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -13934,43 +13983,30 @@ } }, "node_modules/react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "license": "MIT", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "peer": true, "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "license": "MIT", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "peer": true, "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^16.14.0" + "react": "^18.3.1" } }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT", - "peer": true - }, "node_modules/readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -14493,14 +14529,12 @@ } }, "node_modules/scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "license": "MIT", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "peer": true, "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { diff --git a/package.json b/package.json index bb5d9da9..9ee2a248 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,10 @@ "scripts": { "start": "rspack --watch", "serve": "rspack serve", - "test": "NODE_OPTIONS=--experimental-vm-modules jest src", + "test-unit": "NODE_OPTIONS=--experimental-vm-modules jest src", + "test-e2e": "playwright test", + "test-e2e-ui": "npm run test-e2e -- --ui", + "test": "npm run test-unit && npm run test-e2e", "clean-build": "shx rm -Rf ./lib ./es ./dist/*.js ./dist/*.css ./dist/*.scss ./dist/stats.json", "build-commonjs": "tsc -p ./build/tsconfig.commonjs.json", "build-module": "tsc -p ./build/tsconfig.module.json", @@ -53,6 +56,7 @@ "js-cookie": "^3.0.1" }, "devDependencies": { + "@playwright/test": "^1.48.0", "@rspack/cli": "^1.0.3", "@rspack/core": "^1.0.3", "@swc/core": "^1.7.23", @@ -61,6 +65,7 @@ "@types/jest": "^27.5.0", "@types/js-cookie": "^3.0.2", "@types/micromodal": "^0.3.5", + "@types/node": "^22.7.5", "cross-env": "^5.2.0", "css-loader": "^0.28.11", "jest": "^28.1.3", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000..ae4320be --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,29 @@ +import {defineConfig, devices} from '@playwright/test'; + +export default defineConfig({ + testDir: './e2e', + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + reporter: 'html', + use: { + baseURL: 'http://127.0.0.1:3000', + trace: 'on-first-retry' + }, + projects: [ + { + name: 'chromium', + use: {...devices['Desktop Chrome']} + }, + { + name: 'firefox', + use: {...devices['Desktop Firefox']} + } + ], + webServer: { + command: 'npm run serve', + url: 'http://127.0.0.1:3000', + reuseExistingServer: !process.env.CI + } +});