Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Most Protractor failures in AWS CodeBuild are fixed by making the browser environment explicit: verify the Chrome and ChromeDriver binaries in the image, pin compatible versions, pass --headless through chromeOptions.args, add --disable-dev-shm-usage when shared memory is constrained, and use buildspec 0.2 so setup state persists. Do not add Xvfb unless something really runs Chrome headfully, and reserve --no-sandbox for containers where Chrome’s sandbox cannot operate.

Use this order to fix the build

  1. Identify the actual browser, driver, Protractor and Selenium versions and executable paths inside the CodeBuild image.
  2. Pin compatible Chrome and ChromeDriver versions instead of allowing an unbounded driver download.
  3. Configure Protractor with --headless; add --disable-dev-shm-usage if the container’s shared-memory mount is too small.
  4. Keep Chrome’s sandbox enabled whenever the container user and permissions allow it. Add --no-sandbox only as a narrowly justified workaround.
  5. Use buildspec version 0.2 when commands depend on a previous cd, export, or generated file.
  6. Reproduce the exact commands in the CodeBuild sandbox or through Session Manager before changing more flags.

This sequence separates browser-launch problems from CodeBuild image, proxy, credential, memory and permission failures that can produce similar symptoms.

Verify what CodeBuild is actually running

A local Chrome installation is not evidence that the managed build image contains the same binaries. Add a diagnostic phase before the Protractor command and preserve its output in the build log.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
set -euxo pipefail
printf 'PATH=%sn' "$PATH"
command -v google-chrome || true
command -v chromium || true
command -v chromedriver || true
google-chrome --version 2>/dev/null || true
chromium --version 2>/dev/null || true
chromedriver --version 2>/dev/null || true
node --version
npm --version
npx protractor --version 2>/dev/null || true
npm ls protractor selenium-webdriver --depth=0 || true

Record the full paths, not only the version strings. If Chrome is installed in a nonstandard location, configure that path explicitly in Protractor or the WebDriver capability. A browser that starts successfully with one binary can fail when ChromeDriver launches a different one.

Pin the dependency set

Protractor is archived, so reproducibility matters more than convenience. Commit the lockfile, install with npm ci, and choose a ChromeDriver release compatible with the Chrome version supplied by the selected CodeBuild image. An unconstrained webdriver-manager update can retrieve a driver that no longer matches the image after an update.

npm ci
# Run this only when you intentionally update the pinned driver set:
npx webdriver-manager update

Do not treat the second command as a normal every-build step unless you have separately controlled the resulting versions. If the image changes Chrome, update and review the driver together.

Configure Protractor for genuine headless Chrome

Protractor passes Chrome command-line switches through capabilities.chromeOptions.args. A minimal configuration is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
exports.config = {
  directConnect: true,
  capabilities: {
    browserName: 'chrome',
    chromeOptions: {
      args: [
        '--headless',
        '--disable-dev-shm-usage'
        // Add '--no-sandbox' only when the container setup requires it.
      ]
    }
  },
  specs: ['spec/**/*.js']
};

--headless tells Chrome to run without a visible window. --disable-dev-shm-usage makes Chrome use a temporary location instead of relying on a small /dev/shm area, which is a common constraint in containers. It can reduce the chance of an early crash, but it does not repair a missing binary, an incompatible driver or a broken profile directory.

Use a unique temporary profile

Parallel jobs or repeated retries can collide when they share a profile directory. Give each process its own writable directory and remove it after the run:

const os = require('os');
const path = require('path');
const fs = require('fs');

const profile = fs.mkdtempSync(path.join(os.tmpdir(), 'protractor-chrome-'));

exports.config = {
  directConnect: true,
  capabilities: {
    browserName: 'chrome',
    chromeOptions: {
      args: [
        '--headless',
        '--disable-dev-shm-usage',
        `--user-data-dir=${profile}`
      ]
    }
  },
  onCleanUp: () => {
    fs.rmSync(profile, { recursive: true, force: true });
  }
};

The directory must be writable by the user that CodeBuild uses. A read-only home or temporary directory can look like a DevTools startup failure.

When to use --no-sandbox

Chrome’s sandbox is a security boundary. Keep it enabled when the container user, kernel features and file permissions are correctly configured. Use --no-sandbox only when you have established that the sandbox cannot initialize in this particular container and you understand the reduced isolation. It is not a universal fix for DevToolsActivePort, and adding it first can hide a permissions or image problem.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Buildspec details that change the result

Buildspec version 0.1 starts each command in a separate shell instance. A directory change or exported variable therefore disappears before the next command. Version 0.2 keeps normal sequential setup in one shell, which is usually what a browser test needs.

version: 0.2
phases:
  install:
    runtime-versions:
      nodejs: 18
    commands:
      - npm ci
  pre_build:
    commands:
      - set -euxo pipefail
      - command -v google-chrome || command -v chromium
      - google-chrome --version 2>/dev/null || chromium --version
      - chromedriver --version
  build:
    commands:
      - npx protractor protractor.conf.js
reports:
  protractor:
    files:
      - 'test-results/**/*'
    discard-paths: no

The Node.js version in this example is illustrative; select a runtime supported by your project and the image you have chosen. If you must remain on buildspec 0.1, chain dependent operations in one command:

version: 0.1
phases:
  build:
    commands:
      - npm ci && npx protractor protractor.conf.js

Also check the CodeBuild environment itself. Unsupported images, incorrect proxy variables, missing credentials, insufficient memory and Docker privileged-mode requirements can prevent installation or process startup before Protractor is involved.

Do you need Xvfb?

No, not for a true Chrome headless run. Headless Chrome does not create a window, so a display server such as Xvfb is unnecessary. Installing Xvfb can add packages, startup races and another failure point without helping the configuration above.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Add Xvfb only when a test or another browser component is deliberately running headful Chrome. In that case, start the display before the test and point the process at it with DISPLAY; otherwise remove the display dependency and keep the run headless.

Diagnose the common failure signatures

Symptom Likely checks Action
Chrome exits before a WebDriver session exists Binary paths, Chrome/ChromeDriver compatibility, user permissions and browser logs Pin matching versions, verify the executable paths in the image and confirm the profile directory is writable.
DevToolsActivePort or another early startup error Shared memory, temporary profile, headless flag and container user Keep --headless, try --disable-dev-shm-usage, use a unique profile and add --no-sandbox only if the sandbox genuinely cannot run.
The test waits forever for a display Whether the test is actually headful or an unnecessary display wrapper is being invoked Run Chrome in headless mode without Xvfb, or configure Xvfb explicitly for a headful dependency.
Setup appears to vanish between commands Buildspec version and shell boundaries Move to version 0.2 or chain all dependent commands in one version-0.1 command.
Local succeeds but CodeBuild fails Image contents, environment variables, proxy, memory, permissions and logs Re-run the exact install and test commands in the CodeBuild sandbox or with Session Manager and inspect the real container.
Driver download works intermittently Unbounded webdriver-manager updates and changing image versions Commit a lockfile and pin the browser/driver pair; update them deliberately as one change.

Reproduce the failing container instead of guessing

When the log only shows a generic session-creation error, use the CodeBuild sandbox or Session Manager to enter an environment matching the build. Run the version checks, print relevant environment variables, inspect writable temporary locations and launch the same Protractor command manually. Capture ChromeDriver logging and the browser’s stderr where possible. This distinguishes a real Chrome launch fault from a blocked download, proxy misconfiguration or a container that lacks the required privileges.

Compare the successful and failing environments on these axes:

  • Chrome and ChromeDriver versions and absolute executable paths.
  • Node.js, Protractor and Selenium versions installed from the lockfile.
  • Effective user, writable home and temporary directories, and profile ownership.
  • Available memory and shared-memory capacity.
  • Proxy and certificate variables, network access and credentials.
  • Whether the image was updated since the last successful build.

Make the fix durable

Keep image updates intentional

A managed CodeBuild image can change its preinstalled browser. Treat an image update as a dependency change: rerun the version diagnostics, verify the matching driver and review the lockfile before merging.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep security explicit

Document why any sandbox exception exists, which container image requires it and what would allow its removal. Avoid copying a permissive flag from an unrelated Docker recipe.

Keep logs actionable

Print versions once per build, preserve the Protractor and ChromeDriver logs as artifacts, and fail fast on missing binaries. A short, deterministic log is more useful than repeatedly appending Chrome flags.

Plan migration

Protractor is archived. Once the immediate CodeBuild failure is stable, plan a migration to a maintained browser automation stack. The migration is separate from fixing this build, but postponing it increases the chance that a future browser update will become an emergency compatibility exercise.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If the actual requirement is to obtain a screenshot or PDF from a URL rather than execute an end-to-end Protractor test, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Only clean shots are billed, while bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and the response identifies the result with X-Page-Verdict and X-Billed headers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

One request is enough:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the complete parameter list and authentication details in the ScreenshotNeo documentation. The same call from Python is:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also supports full-page captures with lazy images loaded, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF paper and page-range options, custom CSS and JavaScript, clicks, waits, blocked resources, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage reporting and an OpenAPI specification. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.

The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Sign up for the free ScreenshotNeo plan if replacing a screenshot-only browser job makes sense for your pipeline.

Frequently Asked Questions

Can directConnect remove the need for a separate Selenium server?

Yes, when the configured Chrome binary and driver can be launched in the same CodeBuild environment. It does not remove the requirement for compatible versions or writable runtime directories.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I increase the CodeBuild machine size for every Chrome crash?

No. First inspect browser and driver versions, shared memory, profile permissions and the container logs. Increase compute only after those checks show a genuine memory or resource limit.

What should be preserved when a retry passes?

Keep the diagnostic output and the exact image, dependency lockfile and flags from the passing run. A one-off successful retry is not proof that an unpinned driver or changing image is safe.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.