diff --git a/.github/workflows/endform-desktop-smoke.yml b/.github/workflows/endform-desktop-smoke.yml new file mode 100644 index 00000000000..231480d32a8 --- /dev/null +++ b/.github/workflows/endform-desktop-smoke.yml @@ -0,0 +1,59 @@ +name: Endform Desktop Smoke E2E +on: + pull_request: + workflow_dispatch: + inputs: + concurrency: + description: Max concurrent tests on Endform + default: "20" + args: + description: Extra endform test arguments (file filters, --grep) + default: "" + +permissions: + contents: read + id-token: write # Endform GitHub App OIDC + +concurrency: + group: endform-desktop-smoke-${{ github.ref }} + cancel-in-progress: true + +jobs: + smoke: + name: Desktop Smoke E2E (Endform) + runs-on: ubuntu-latest + timeout-minutes: 30 + env: + ENDFORM_CONCURRENCY: ${{ inputs.concurrency || '50' }} + ENDFORM_ARGS: ${{ inputs.args || '' }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1 + - name: Get pnpm store directory + id: pnpm-cache + run: echo "STORE_PATH=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT" + - name: Restore pnpm store cache + uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5 + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: pnpm-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: pnpm-${{ runner.os }}- + - name: Install desktop dependencies + run: just desktop-install-ci + - name: Desktop E2E build + run: pnpm -C desktop build:e2e + - name: Desktop smoke e2e on Endform + working-directory: desktop + run: | + npx --yes endform@latest test \ + --config playwright.endform.config.ts \ + --project smoke \ + $ENDFORM_ARGS + - name: Upload Playwright report + if: ${{ !cancelled() }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: endform-desktop-smoke-report + path: desktop/playwright-report + if-no-files-found: ignore + retention-days: 7 diff --git a/desktop/endform.config.ts b/desktop/endform.config.ts new file mode 100644 index 00000000000..0f2b900df65 --- /dev/null +++ b/desktop/endform.config.ts @@ -0,0 +1,20 @@ +// Endform reads this file only for `npx endform test`; local Playwright runs +// ignore it. ENDFORM_CONCURRENCY caps how many smoke tests share the local +// static server at once. +export default { + // Files specs read through fs or resolve through tsconfig `@/` paths, + // which Endform's import tracing does not pick up on its own. + additionalFiles: [ + "tsconfig.json", + "src/**/*", + "src-tauri/tauri.conf.json", + "tests/fixtures/*", + "tests/e2e/*-snapshots/*", + ], + concurrentTestLimits: [ + { + scope: "within-suite-run", + limit: Number(process.env.ENDFORM_CONCURRENCY ?? "20"), + }, + ], +}; diff --git a/desktop/playwright.endform.config.ts b/desktop/playwright.endform.config.ts new file mode 100644 index 00000000000..b8d4bf6f7ba --- /dev/null +++ b/desktop/playwright.endform.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from "@playwright/test"; + +import baseConfig from "./playwright.config"; + +// Runs the desktop smoke project on Endform: one CI job, every test on its +// own machine, against the production `build:e2e` bundle served locally. +// Endform proxies the runners' traffic back to this `webServer`. +export default defineConfig({ + ...baseConfig, + fullyParallel: true, + retries: 2, + workers: undefined, + use: { ...baseConfig.use, trace: "retain-on-failure" }, + projects: baseConfig.projects?.filter(({ name }) => name === "smoke"), + // http.server logs every request to stderr; keep the CI log readable. + webServer: { ...baseConfig.webServer, stderr: "ignore" }, +});