E2E CI Integration¶
How the E2E test job is wired into the CWIQ pipeline: timing, secrets, networking, and artifacts.
The E2E test job is defined in .gitlab-ci-node.yml (in orchestrator/ci-templates) and extends the hidden .e2e-test template. It runs in the verify stage, after verify-dev confirms the DEV deployment is healthy.
Pipeline Position¶
The dashed border indicates allow_failure: true. A failing E2E job is reported in the pipeline UI and its artifacts are available for investigation, but it does not flip the overall pipeline status to failed.
E2E tests run only on the main branch. They do not run on feature branches.
Job Definition¶
The job in your project's .gitlab-ci.yml extends the hidden template and declares its dependency on upstream jobs:
e2e-test:
extends: .e2e-test
needs:
- job: verify-dev
rules:
- if: $CI_COMMIT_BRANCH == "main"
allow_failure: true
The hidden .e2e-test template (from ci-templates) provides the full job definition:
# From .gitlab-ci-node.yml in orchestrator/ci-templates
.e2e-test:
stage: verify
image: nexus.shared.cwiq.io:8444/playwright:v1.58.2-noble
tags:
- small
id_tokens:
VAULT_ID_TOKEN:
aud: https://gitlab.shared.cwiq.io
variables:
PLAYWRIGHT_BASE_URL: "https://${DEV_SERVER_IP}"
NODE_TLS_REJECT_UNAUTHORIZED: "0"
before_script:
- cd platform/ui
- npm ci --prefer-offline
- npx playwright install chromium
- |
# Fetch E2E credentials from Vault
AUTH=$(curl -sf -H "Content-Type: application/json" \
-d "{\"role\":\"nexus-ci\",\"jwt\":\"${VAULT_ID_TOKEN}\"}" \
"${VAULT_ADDR}/v1/auth/jwt/login")
VAULT_TOKEN=$(echo "${AUTH}" | grep -o '"client_token":"[^"]*"' | head -1 | sed 's/"client_token":"//;s/"$//')
E2E_SECRETS=$(curl -sf -H "X-Vault-Token: ${VAULT_TOKEN}" \
"${VAULT_ADDR}/v1/secret/data/orchestrator/e2e-test-user")
export E2E_ADMIN_USERNAME=$(echo "${E2E_SECRETS}" | grep -o '"username":"[^"]*"' | sed 's/"username":"//;s/"$//')
export E2E_ADMIN_PASSWORD=$(echo "${E2E_SECRETS}" | grep -o '"password":"[^"]*"' | sed 's/"password":"//;s/"$//')
RP_SECRETS=$(curl -sf -H "X-Vault-Token: ${VAULT_TOKEN}" \
"${VAULT_ADDR}/v1/secret/data/reportportal/svc-orchestrator")
export RP_API_KEY=$(echo "${RP_SECRETS}" | grep -o '"api_key":"[^"]*"' | sed 's/"api_key":"//;s/"$//')
script:
- npm run e2e
artifacts:
when: always
paths:
- platform/ui/playwright-report/
- platform/ui/test-results/
reports:
junit: platform/ui/results.xml
expire_in: 2 weeks
Networking¶
NODE_TLS_REJECT_UNAUTHORIZED=0 is intentional.
Runner pods connect to the DEV server via its VPC private IP (DEV_SERVER_IP). The TLS certificate on the DEV server is issued for orchestrator.dev.cwiq.io, not for the raw VPC IP. Setting NODE_TLS_REJECT_UNAUTHORIZED=0 suppresses the certificate hostname mismatch error within the VPC. This is safe — traffic stays entirely within the private network.
The PLAYWRIGHT_BASE_URL is set to https://${DEV_SERVER_IP}. The DEV_SERVER_IP variable is defined at the GitLab group level and always holds the VPC private IP of the DEV orchestrator server. Tailscale hostnames are not usable from runner pods because Tailscale is not available inside Kubernetes pods.
Vault Secrets¶
Two sets of secrets are fetched at job start using the nexus-ci Vault role:
| Vault Path | Keys Used | Environment Variables Set |
|---|---|---|
secret/data/orchestrator/e2e-test-user |
username, password |
E2E_ADMIN_USERNAME, E2E_ADMIN_PASSWORD |
secret/data/reportportal/svc-orchestrator |
api_key |
RP_API_KEY |
No E2E credentials are stored as GitLab CI/CD variables. See Vault JWT Auth for the authentication pattern used in all pipeline jobs.
Artifacts¶
All artifacts use when: always, meaning they are retained regardless of whether the job passed or failed. This is critical for debugging failures.
| Artifact Path | Contents | Retained |
|---|---|---|
playwright-report/ |
Full HTML report with test results, screenshots, traces | 2 weeks |
test-results/ |
Per-test subdirectories with screenshots and videos captured on failure | 2 weeks |
results.xml (JUnit) |
Machine-readable test results for GitLab's test summary panel | 2 weeks |
To access the HTML report for a specific pipeline run:
- Open the pipeline in GitLab.
- Click the
e2e-testjob. - Click Browse under Job Artifacts on the right panel.
- Open
playwright-report/index.html.
Playwright Docker Image¶
The job uses a pre-built Playwright image pulled from the Nexus Docker registry:
This image includes:
- Node.js 20
- Playwright v1.58.2
- Chromium browser binaries
- All required system dependencies
The image is pinned to a specific Playwright version to prevent test behaviour from changing unexpectedly when Playwright releases a new version. To upgrade Playwright, update both this image tag and the @playwright/test version in platform/ui/package.json, then rebuild the image.
Do not run npx playwright install with an unspecified version in CI.
The npx playwright install chromium step in before_script installs the browser version that matches the @playwright/test package in package.json. It does not upgrade Playwright itself. Always pin both the Docker image and the npm package to the same Playwright version.
Related Documentation¶
- E2E Testing Overview — Test projects, directory structure, authentication flow
- Playwright Setup — Configuration and running tests locally
- ReportPortal — Viewing test results and launch history
- Vault JWT Auth — How CI jobs authenticate with Vault to fetch secrets
- Runners (EKS K8s) — Why
NODE_TLS_REJECT_UNAUTHORIZED=0is needed from runner pods