name: 'Test: E2E' on: workflow_call: inputs: branch: description: 'GitHub branch to test.' required: false type: string test-mode: description: 'Test mode: local or docker-artifact' required: false default: 'local' type: string test-command: description: 'Test command to run' required: false default: 'pnpm --filter=n8n-playwright test:local' type: string workers: description: 'Number of parallel workers' required: false default: '' type: string runner: description: 'GitHub runner to use' required: false default: 'blacksmith-2vcpu-ubuntu-2204' type: string timeout-minutes: description: 'Job timeout in minutes' required: false default: 30 type: number upload-failure-artifacts: description: 'Upload test failure artifacts (screenshots, traces, videos). Enable for community PRs without Currents access.' required: false default: false type: boolean currents-project-id: description: 'Currents project ID for reporting' required: false default: 'LRxcNt' type: string pre-generated-matrix: description: 'Pre-generated shard matrix JSON. Defaults to 1 shard; multi-shard callers pass their own.' required: false default: '[{"shard":1,"images":""}]' type: string n8n-env: description: 'JSON string of n8n env vars to inject into test containers, e.g. {"N8N_EXPRESSION_ENGINE":"vm"}' required: false default: '' type: string env: NODE_OPTIONS: ${{ contains(inputs.runner, '2vcpu') && '--max-old-space-size=6144' || '' }} PLAYWRIGHT_WORKERS: ${{ inputs.workers != '' && inputs.workers || '2' }} # Browser cache location - must match install-browsers script PLAYWRIGHT_BROWSERS_PATH: packages/testing/playwright/.playwright-browsers # docker-artifact loads the image locally as n8nio/n8n:local; unused in local mode. TEST_IMAGE_N8N: 'n8nio/n8n:local' N8N_SKIP_LICENSES: 'true' CURRENTS_CI_BUILD_ID: ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }} CURRENTS_PROJECT_ID: ${{ inputs.currents-project-id }} jobs: test: runs-on: ${{ vars.RUNNER_PROVIDER == 'github' && 'ubuntu-latest' || inputs.runner }} timeout-minutes: ${{ inputs.timeout-minutes }} permissions: contents: read strategy: fail-fast: false matrix: include: ${{ fromJSON(inputs.pre-generated-matrix) }} name: Shard ${{ matrix.shard }} steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 1 ref: ${{ inputs.branch || github.ref }} - name: Setup Environment uses: ./.github/actions/setup-nodejs env: QA_METRICS_WEBHOOK_URL: ${{ secrets.QA_METRICS_WEBHOOK_URL }} QA_METRICS_WEBHOOK_USER: ${{ secrets.QA_METRICS_WEBHOOK_USER }} QA_METRICS_WEBHOOK_PASSWORD: ${{ secrets.QA_METRICS_WEBHOOK_PASSWORD }} - name: Install Browsers run: pnpm turbo run install-browsers --filter=n8n-playwright - name: Load n8n image from cache if: ${{ inputs.test-mode == 'docker-artifact' }} uses: ./.github/actions/load-n8n-docker - name: Pre-pull Test Container Images if: ${{ !contains(inputs.test-command, 'test:local') }} run: npx tsx packages/testing/containers/pull-test-images.ts ${{ matrix.images }} || true - name: Run Tests run: | # shellcheck disable=SC2086 $TEST_COMMAND --workers="$WORKERS" $SHARD_ARGS env: # Protect args from template injections TEST_COMMAND: ${{ inputs.test-command }} # Uses pre-distributed specs if orchestration enabled, otherwise falls back to Playwright sharding WORKERS: ${{ env.PLAYWRIGHT_WORKERS }} SHARD_ARGS: ${{ matrix.specs || format('--shard={0}/{1}', matrix.shard, strategy.job-total) }} # Args for actual test command runner CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }} QA_METRICS_WEBHOOK_URL: ${{ secrets.QA_METRICS_WEBHOOK_URL }} QA_METRICS_WEBHOOK_USER: ${{ secrets.QA_METRICS_WEBHOOK_USER }} QA_METRICS_WEBHOOK_PASSWORD: ${{ secrets.QA_METRICS_WEBHOOK_PASSWORD }} N8N_LICENSE_ACTIVATION_KEY: ${{ secrets.N8N_LICENSE_ACTIVATION_KEY }} N8N_LICENSE_CERT: ${{ secrets.N8N_LICENSE_CERT }} N8N_ENCRYPTION_KEY: ${{ secrets.N8N_ENCRYPTION_KEY }} N8N_TEST_ENV: ${{ inputs.n8n-env }} - name: Upload Failure Artifacts if: ${{ failure() && inputs.upload-failure-artifacts }} uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: playwright-report-shard-${{ matrix.shard }} path: | packages/testing/playwright/test-results/ packages/testing/playwright/playwright-report/ retention-days: 7 - name: Cancel Currents run if workflow is cancelled if: ${{ cancelled() }} env: CURRENTS_API_KEY: ${{ secrets.CURRENTS_API_KEY }} run: | if [ -n "$CURRENTS_API_KEY" ]; then curl --location --request PUT \ "https://api.currents.dev/v1/runs/cancel-ci/github" \ --header "Authorization: Bearer $CURRENTS_API_KEY" \ --header "Content-Type: application/json" \ --data "{\"githubRunId\": \"${{ github.run_id }}\", \"githubRunAttempt\": \"${{ github.run_attempt }}\"}" fi