diff --git a/.github/workflows/test-e2e-pr-comment.yml b/.github/workflows/test-e2e-pr-comment.yml new file mode 100644 index 000000000..ede88d374 --- /dev/null +++ b/.github/workflows/test-e2e-pr-comment.yml @@ -0,0 +1,51 @@ +name: test-e2e-pr-comment + +on: + workflow_run: + workflows: ['E2E Test PR'] + types: + - completed + +jobs: + comment: + name: Comment User Tip + runs-on: ubuntu-latest + steps: + - name: Download Pr Artifact + uses: dawidd6/action-download-artifact@v2 + with: + workflow: ${{ github.event.workflow_run.workflow_id }} + name: pr + if_no_artifact_found: success + - name: Save PR Id + id: pr + run: | + if [ -f user-tip.txt ]; then + echo "id=$(cat pr-id.txt)" >> $GITHUB_OUTPUT + fi + + - name: Download user-tip.txt + uses: dawidd6/action-download-artifact@v2 + with: + workflow: ${{ github.event.workflow_run.workflow_id }} + name: user-tip + if_no_artifact_found: success + + - id: txtToOutput + run: | + if [ -f user-tip.txt ]; then + echo 'text<> $GITHUB_OUTPUT + cat user-tip.txt >> $GITHUB_OUTPUT + echo 'EOF' >> $GITHUB_OUTPUT + fi + - run: | + echo ${{ steps.txtToOutput.outputs.text }} + - run: | + echo ${{ steps.pr.outputs.id }} + - uses: thollander/actions-comment-pull-request@v2 + if: ${{ steps.txtToOutput.outputs.text && steps.pr.outputs.id }} + with: + message: | + ${{ steps.txtToOutput.outputs.text }} + comment_tag: e2e-tip + pr_number: ${{ steps.pr.outputs.id }} diff --git a/.github/workflows/test-e2e-pr.yml b/.github/workflows/test-e2e-pr.yml index dd26f32ee..54f5bbf9d 100644 --- a/.github/workflows/test-e2e-pr.yml +++ b/.github/workflows/test-e2e-pr.yml @@ -14,6 +14,7 @@ jobs: runs-on: ubuntu-latest outputs: testComponents: ${{ steps.parseTitle.outputs.testComponents }} + testclis: ${{ steps.parsetestCli.outputs.testClis }} steps: - name: Parse Title id: parseTitle @@ -32,17 +33,53 @@ jobs: components = [...new Set(components)].slice(0, 3).join(' ') core.setOutput('testComponents', components) } else { - const warningString =` + const warningString =`**[e2e-test-warn]** The component to be tested is missing. The title of the Pull request should look like "fix(vue-renderless): [action-menu, alert] fix xxx bug". Please make sure you've read our [contributing guide](https://github.com/opentiny/tiny-vue/blob/dev/CONTRIBUTING.md) ` + core.setOutput('tip', warningString) core.warning(warningString) } + - name: generate user-tip.txt + if: ${{ steps.parseTitle.outputs.tip }} + run: | + cat << EOF > user-tip.txt + ${{ steps.parseTitle.outputs.tip }} + EOF + - name: Upload User Tip + if: ${{ steps.parseTitle.outputs.tip }} + uses: actions/upload-artifact@v4 + with: + name: user-tip + path: user-tip.txt + retention-days: 1 + - name: Save PR number + if: ${{ steps.parseTitle.outputs.tip }} + run: echo ${{ github.event.number }} > ./pr-id.txt + + - name: Upload PR number + if: ${{ steps.parseTitle.outputs.tip }} + uses: actions/upload-artifact@v4 + with: + name: pr + path: ./pr-id.txt + - name: Parse Test Cli + id: parsetestCli + uses: actions/github-script@v6 + with: + script: | + const testClis = '${{ vars.PLAYWRIGHT_CLIS }}' ? '${{ vars.PLAYWRIGHT_CLIS }}'.split(',') : ['pnpm test:e2e3'] + core.setOutput('testclis', JSON.stringify(testClis)) + pr-test: if: ${{ needs.parse-components.outputs.testComponents }} + strategy: + matrix: + testcli: ${{ fromJson(needs.parse-components.outputs.testclis) }} + name: PR E2E Test needs: parse-components runs-on: ubuntu-latest @@ -78,11 +115,8 @@ jobs: - name: Install dependencies run: pnpm i --no-frozen-lockfile - - name: dev start - run: pnpm site & sleep 5 - - name: Install Playwright browsers run: pnpm install:browser --with-deps chromium - name: E2E Test - run: pnpm test:e2e3 ${{ env.TEST_COMPONENTS }} --reporter=line --retries=1 --workers=2 + run: ${{ matrix.testcli }} ${{ env.TEST_COMPONENTS }} --retries=1 --workers=2 diff --git a/examples/vue2/playwright.config.js b/examples/vue2/playwright.config.js index 19a10bec7..85f98e6b3 100644 --- a/examples/vue2/playwright.config.js +++ b/examples/vue2/playwright.config.js @@ -1,6 +1,11 @@ import Config from '@opentiny-internal/playwright-config' +const origin = 'http://localhost:7126' +const baseURL = `${origin}/pc/` +const devServerCommon = 'pnpm run -w dev2' + export default Config({ - testDir: '../docs/resources', - port: 7126 + testDir: '../sites/demos', + baseURL, + devServerCommon }) diff --git a/examples/vue3/playwright.config.js b/examples/vue3/playwright.config.js index fc0cada1c..24b9d567a 100644 --- a/examples/vue3/playwright.config.js +++ b/examples/vue3/playwright.config.js @@ -3,6 +3,7 @@ import Config from '@opentiny-internal/playwright-config' const origin = 'http://localhost:3101' // or 'http://localhost:7130/pc/' const baseURL = `${origin}/tiny-vue/zh-CN/os-theme/components/` +const devServerCommon = 'pnpm run -w site' export default Config({ testDir: '../sites/demos', @@ -17,5 +18,6 @@ export default Config({ ] } ] - } + }, + devServerCommon }) diff --git a/internals/playwright-config/src/index.js b/internals/playwright-config/src/index.js index 5af54f526..8769ca796 100644 --- a/internals/playwright-config/src/index.js +++ b/internals/playwright-config/src/index.js @@ -1,5 +1,5 @@ // import type { PlaywrightTestConfig } from '@playwright/test' -import { devices } from '@playwright/test' +import { devices, defineConfig } from '@playwright/test' /** * Read environment variables from file. @@ -10,88 +10,94 @@ import { devices } from '@playwright/test' /** * See https://playwright.dev/docs/test-configuration. */ -const Config = ({ testDir, baseURL, storageState }) => ({ - testDir, - /* 每个 test 用例最长时间。 */ - timeout: 20 * 1000, - expect: { - // 每个 expect() 用例最长时间。 - timeout: 10 * 1000 - }, - /* 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, - /* playwright 同时可以开启几个浏览器进行测试 */ - workers: process.env.CI ? 1 : 2, - /* 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: { - /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ - actionTimeout: 0, - /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: process.env.PYTEST_BASEURL || baseURL, - storageState: process.env.PYTEST_STORAGE ? JSON.parse(process.env.PYTEST_STORAGE) : storageState, - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', - - /* Only on CI systems run the tests headless */ - headless: !!process.env.CI, - ignoreHTTPSErrors: true, - screenshot: 'only-on-failure', - permissions: ['clipboard-read'], - - /* Emulates the user timezone */ - timezoneId: 'Asia/Shanghai' - }, - - projects: [ - { - name: 'chromium', - use: { - ...devices['Desktop Chrome'] - } +const Config = ({ testDir, baseURL, storageState, devServerCommon }) => + defineConfig({ + testDir, + /* 每个 test 用例最长时间。 */ + timeout: 20 * 1000, + expect: { + // 每个 expect() 用例最长时间。 + timeout: 10 * 1000 }, - { - name: 'mobile-android', - use: { - ...devices['Pixel 5'] - } - }, - { - name: 'mobile-iphone', - use: { - ...devices['iPhone 12'] - } - } - // 以下屏蔽,防止测试目标列表过长 - // { - // name: 'firefox', - // use: { - // ...devices['Desktop Firefox'] - // } - // }, - // { - // name: 'webkit', - // use: { - // ...devices['Desktop Safari'] - // } - // }, + /* 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, + /* playwright 同时可以开启几个浏览器进行测试 */ + workers: process.env.CI ? 1 : 2, + /* 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: { + /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ + actionTimeout: 0, + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: process.env.PYTEST_BASEURL || baseURL, + storageState: process.env.PYTEST_STORAGE ? JSON.parse(process.env.PYTEST_STORAGE) : storageState, + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', - // { - // name: 'edge', - // use: { - // channel: 'msedge' - // } - // }, - // { - // name: 'chrome', - // use: { - // channel: 'chrome' - // } - // } - ] -}) + /* Only on CI systems run the tests headless */ + headless: !!process.env.CI, + ignoreHTTPSErrors: true, + screenshot: 'only-on-failure', + permissions: ['clipboard-read'], + + /* Emulates the user timezone */ + timezoneId: 'Asia/Shanghai' + }, + webServer: { + command: devServerCommon, + url: baseURL, + reuseExistingServer: !process.env.CI, + stdout: 'pipe' + }, + projects: [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'] + } + }, + { + name: 'mobile-android', + use: { + ...devices['Pixel 5'] + } + }, + { + name: 'mobile-iphone', + use: { + ...devices['iPhone 12'] + } + } + // 以下屏蔽,防止测试目标列表过长 + // { + // name: 'firefox', + // use: { + // ...devices['Desktop Firefox'] + // } + // }, + // { + // name: 'webkit', + // use: { + // ...devices['Desktop Safari'] + // } + // }, + + // { + // name: 'edge', + // use: { + // channel: 'msedge' + // } + // }, + // { + // name: 'chrome', + // use: { + // channel: 'chrome' + // } + // } + ] + }) export default Config