Skip to content

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

flowchart LR
    DD[deploy-dev] --> VD[verify-dev] --> E2E[e2e-test]
    style E2E stroke-dasharray: 5 5

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:

  1. Open the pipeline in GitLab.
  2. Click the e2e-test job.
  3. Click Browse under Job Artifacts on the right panel.
  4. Open playwright-report/index.html.

Playwright Docker Image

The job uses a pre-built Playwright image pulled from the Nexus Docker registry:

nexus.shared.cwiq.io:8444/playwright:v1.58.2-noble

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.