diff --git a/.github/workflows/upload-canyon-report-coverage-map.yml b/.github/workflows/upload-canyon-report-coverage-map.yml index 3e1c82d4..00fc7bf0 100644 --- a/.github/workflows/upload-canyon-report-coverage-map.yml +++ b/.github/workflows/upload-canyon-report-coverage-map.yml @@ -36,6 +36,26 @@ jobs: - name: Upload coverage report run: cd packages/canyon-report && npm install canyon-uploader -g && canyon-uploader map --dsn=https://collect.canyonjs.org/coverage/map/client + - name: Start Vite Server + run: cd packages/canyon-report && npm run dev & + shell: bash + continue-on-error: true + + - name: Wait for Vite Server to Start + run: | + while :; do + if nc -z localhost 3000; then + break + fi + sleep 1 + end + shell: bash + + - name: Run Playwright Tests + run: cd packages/canyon-report && npx playwright test + + + # 保存构建结果到工作空间 # - name: Upload build artifact # uses: actions/upload-artifact@v3 diff --git a/packages/canyon-report/package.json b/packages/canyon-report/package.json index 85ceec30..3158e6ee 100644 --- a/packages/canyon-report/package.json +++ b/packages/canyon-report/package.json @@ -7,7 +7,8 @@ "scripts": { "dev": "rsbuild dev --open", "build:report": "rsbuild build", - "build": "rslib build" + "build": "rslib build", + "playwright": "playwright test" }, "exports": { ".": { @@ -45,6 +46,7 @@ "postcss": "^8.4.47", "swc-plugin-coverage-instrument": "^0.0.25", "tailwindcss": "^3.4.14", - "typescript": "^5.6.3" + "typescript": "^5.6.3", + "@playwright/test": "^1.48.2" } } diff --git a/packages/canyon-report/tests/baseFixtures.ts b/packages/canyon-report/tests/baseFixtures.ts new file mode 100644 index 00000000..0d3ec1da --- /dev/null +++ b/packages/canyon-report/tests/baseFixtures.ts @@ -0,0 +1,30 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import {test as baseTest} from '@playwright/test'; + +const canyonOutputDirPath = path.join(process.cwd(), '.canyon_output'); + +export const test = baseTest.extend({ + context: async ({context}, use) => { + await context.addInitScript(() => + window.addEventListener('beforeunload', () => + (window as any).collectIstanbulCoverage((window as any).__coverage__, (window as any).__canyon__) + ), + ); + await fs.promises.mkdir(canyonOutputDirPath, {recursive: true}); + await context.exposeFunction('collectIstanbulCoverage', (coverageJSON, canyonJSON) => { + if (coverageJSON) { + fs.writeFileSync(path.join(canyonOutputDirPath, `${new Date().valueOf()}.json`), JSON.stringify({ + ...(canyonJSON||{}), + coverage: coverageJSON + })); + } + }); + await use(context); + for (const page of context.pages()) { + await page.evaluate(() => (window as any).collectIstanbulCoverage((window as any).__coverage__, (window as any).__canyon__)) + } + } +}); + +export const expect = test.expect; diff --git a/packages/canyon-report/tests/example.spec.ts b/packages/canyon-report/tests/example.spec.ts new file mode 100644 index 00000000..710ef6db --- /dev/null +++ b/packages/canyon-report/tests/example.spec.ts @@ -0,0 +1,6 @@ +import { test, expect } from './baseFixtures'; + +test('has title', async ({ page }) => { + await page.goto('http://localhost:3000/login'); + expect(await page.title()).toBe('Rsbuild App'); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cf9db983..289c52d5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -137,7 +137,7 @@ importers: dependencies: '@ant-design/nextjs-registry': specifier: ^1.0.1 - version: 1.0.2(@ant-design/cssinjs@1.22.0(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(antd@5.22.1(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(next@15.0.3(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) + version: 1.0.2(@ant-design/cssinjs@1.22.0(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(antd@5.22.1(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(next@15.0.3(@playwright/test@1.48.2)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) '@monaco-editor/react': specifier: ^4.6.0 version: 4.6.0(monaco-editor@0.52.0)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) @@ -164,7 +164,7 @@ importers: version: 0.460.0(react@19.0.0-rc-66855b96-20241106) next: specifier: 15.0.3 - version: 15.0.3(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) + version: 15.0.3(@playwright/test@1.48.2)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) prisma: specifier: ^5.22.0 version: 5.22.0 @@ -263,6 +263,9 @@ importers: specifier: ^1.22.1 version: 1.23.1 devDependencies: + '@playwright/test': + specifier: ^1.48.2 + version: 1.48.2 '@rsbuild/core': specifier: ^1.1.1 version: 1.1.3 @@ -1328,6 +1331,11 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@playwright/test@1.48.2': + resolution: {integrity: sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==} + engines: {node: '>=18'} + hasBin: true + '@prisma/client@5.16.1': resolution: {integrity: sha512-wM9SKQjF0qLxdnOZIVAIMKiz6Hu7vDt4FFAih85K1dk/Rr2mdahy6d3QP41K62N9O0DJJA//gUDA3Mp49xsKIg==} engines: {node: '>=16.13'} @@ -3156,6 +3164,11 @@ packages: fs.realpath@1.0.0: 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: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -4243,6 +4256,16 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + playwright-core@1.48.2: + resolution: {integrity: sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.48.2: + resolution: {integrity: sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==} + engines: {node: '>=18'} + hasBin: true + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -5666,11 +5689,11 @@ snapshots: react: 19.0.0-rc-66855b96-20241106 react-dom: 19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106) - '@ant-design/nextjs-registry@1.0.2(@ant-design/cssinjs@1.22.0(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(antd@5.22.1(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(next@15.0.3(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106)': + '@ant-design/nextjs-registry@1.0.2(@ant-design/cssinjs@1.22.0(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(antd@5.22.1(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(next@15.0.3(@playwright/test@1.48.2)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106)': dependencies: '@ant-design/cssinjs': 1.22.0(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) antd: 5.22.1(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) - next: 15.0.3(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) + next: 15.0.3(@playwright/test@1.48.2)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) react: 19.0.0-rc-66855b96-20241106 react-dom: 19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106) @@ -6674,6 +6697,10 @@ snapshots: '@pkgr/core@0.1.1': {} + '@playwright/test@1.48.2': + dependencies: + playwright: 1.48.2 + '@prisma/client@5.16.1(prisma@5.16.1)': optionalDependencies: prisma: 5.16.1 @@ -8942,6 +8969,9 @@ snapshots: fs.realpath@1.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -9971,7 +10001,7 @@ snapshots: neo-async@2.6.2: {} - next@15.0.3(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106): + next@15.0.3(@playwright/test@1.48.2)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106): dependencies: '@next/env': 15.0.3 '@swc/counter': 0.1.3 @@ -9991,6 +10021,7 @@ snapshots: '@next/swc-linux-x64-musl': 15.0.3 '@next/swc-win32-arm64-msvc': 15.0.3 '@next/swc-win32-x64-msvc': 15.0.3 + '@playwright/test': 1.48.2 sharp: 0.33.5 transitivePeerDependencies: - '@babel/core' @@ -10191,6 +10222,14 @@ snapshots: dependencies: find-up: 4.1.0 + playwright-core@1.48.2: {} + + playwright@1.48.2: + dependencies: + playwright-core: 1.48.2 + optionalDependencies: + fsevents: 2.3.2 + pluralize@8.0.0: {} possible-typed-array-names@1.0.0: {}