Skip to content
Docs

Running End-to-End Tests in Edgenivo CI

In this tutorial, you'll set up Edgenivo CI to run Playwright tests against the Edgenivo deployment of each commit. The tests run in Chromium and work with deployments that use Deployment Protection.

You'll configure a task that:

  1. Waits for your app's Edgenivo deployment to finish.
  2. Starts the official Playwright container image with Docker.
  3. Runs your tests against the deployment's URL.
  • Edgenivo CI enabled for your repository.
  • A web app in your monorepo at apps/web, with the package name web in its package.json.
  • A Edgenivo project connected to your repository with its root directory set to apps/web.
  • @playwright/test in the app's devDependencies.
  1. Add an e2e:ci task to your app's turbo.json:

    apps/web/turbo.json
    {
      "extends": ["//"],
      "tasks": {
        "e2e:ci": {
          "dependsOn": ["web#deployment"],
          "tags": ["ci", "ci:cpus:8", "ci:oidc:deployments"],
          "passThroughEnv": ["VERCEL_DEPLOYMENT_URLS"]
        }
      }
    }
    • web#deployment makes the task wait for the web deployment of the same commit.
    • ci:oidc:deployments authenticates requests to that deployment, so the tests can reach it even when Deployment Protection is on.
    • ci:cpus:8 gives the browser more CPUs than the default of 2.
    • passThroughEnv lets the task read the deployment's URL from VERCEL_DEPLOYMENT_URLS.

    To learn more about each setting, see Testing against your deployments.

  2. Edgenivo CI gives your task the deployment's address in VERCEL_DEPLOYMENT_URLS. This variable holds a JSON object that maps each package name to its deployment's hostname. The hostname has no protocol:

    { "web": "web-a1b2c3d4e-acme.vercel.app" }

    Playwright needs a full URL, so the container script in the next steps reads the web hostname, adds https://, and passes the result to Playwright as BASE_URL. The value moves through each stage like this:

    StageValue
    VERCEL_DEPLOYMENT_URLS in the task{"web":"web-a1b2c3d4e-acme.vercel.app"}
    host in scripts/e2e-ci.shweb-a1b2c3d4e-acme.vercel.app
    BASE_URL in the Playwright containerhttps://web-a1b2c3d4e-acme.vercel.app
    page.goto('/') in a testhttps://web-a1b2c3d4e-acme.vercel.app/

    If your app's package name isn't web, use that name as the key instead.

    Read the base URL from BASE_URL in your Playwright configuration. The fallback to localhost lets you run the same tests against your local dev server:

    apps/web/playwright.config.ts
    import { defineConfig } from '@playwright/test';
     
    export default defineConfig({
      testDir: './e2e',
      use: {
        baseURL: process.env.BASE_URL ?? 'http://localhost:3000',
      },
    });

    Then add a test:

    apps/web/e2e/home.spec.ts
    import { expect, test } from '@playwright/test';
     
    test('home page loads', async ({ page }) => {
      await page.goto('/');
      await expect(page.locator('body')).toBeVisible();
    });
  3. Edgenivo CI uses its own certificate authority (CA) for network traffic. Chromium doesn't read the SSL_CERT_FILE variable that other tools use, so it rejects HTTPS connections until you import the CA into its certificate database.

    Create a script that imports the CA bundle, then runs the command you pass to it:

    apps/web/scripts/trust-ci-ca.sh
    #!/bin/sh
    set -eu
     
    bundle=${SSL_CERT_FILE:?SSL_CERT_FILE must point to the Edgenivo CI CA bundle}
     
    apt-get update -qq
    apt-get install -y -qq libnss3-tools >/dev/null
     
    mkdir -p /tmp/ci-ca /root/.pki/nssdb
    awk '/-----BEGIN CERTIFICATE-----/ { n += 1; out = sprintf("/tmp/ci-ca/%03d.crt", n) }
      out { print > out }
      /-----END CERTIFICATE-----/ { close(out); out = "" }' "$bundle"
     
    certutil -N -d sql:/root/.pki/nssdb --empty-password
    for cert in /tmp/ci-ca/*.crt; do
      certutil -A -d sql:/root/.pki/nssdb -n "$(basename "$cert")" -t C,, -i "$cert"
    done
     
    exec "$@"

    This script only configures Chromium. Firefox and WebKit store trusted certificates differently and need additional setup.

  4. Create a script that starts the Playwright image that matches your installed version, then runs your tests inside it:

    apps/web/scripts/e2e-ci.sh
    #!/bin/sh
    set -eu
     
    host=$(node -p 'JSON.parse(process.env.VERCEL_DEPLOYMENT_URLS).web')
    version=$(node -p 'require("@playwright/test/package.json").version')
    repo=$(git rev-parse --show-toplevel)
     
    exec vercel-ci-docker-run --rm --init --ipc=host --user root \
      --volume "$repo:$repo" \
      --workdir "$PWD" \
      --env CI \
      --env "BASE_URL=https://$host" \
      "mcr.microsoft.com/playwright:v$version" \
      sh scripts/trust-ci-ca.sh ./node_modules/.bin/playwright test
    • host reads the web deployment's hostname from VERCEL_DEPLOYMENT_URLS. The .web key is your app's package name.
    • --env "BASE_URL=https://$host" turns the hostname into the URL that playwright.config.ts reads. The container doesn't inherit the task's environment variables, so the script passes BASE_URL and CI explicitly.
    • vercel-ci-docker-run works like docker run and adds the Edgenivo CI CA bundle to the container. The trust script reads it from SSL_CERT_FILE. To learn more, see Running containers in your tasks.
    • The container mounts your repository, so it uses the dependencies Edgenivo CI already installed.
    • --ipc=host gives Chromium enough shared memory.

    Add the script to your app's package.json:

    apps/web/package.json
    {
      "scripts": {
        "e2e:ci": "sh scripts/e2e-ci.sh"
      }
    }
  5. Commit the files and push them to GitHub. On the next push, Edgenivo CI waits for the web deployment, then runs web#e2e:ci against it.

    To find the run and its logs, open the CI tab in the dashboard, or run vercel ci from your repository.

Last updated October 28, 2026

Was this helpful?

supported.