Skip to content

Selenium

perfshop-selenium provides a standalone Chrome Selenium Grid that serves as the WebDriver backend for all E2E test executions in the QA stack (Robot Framework + SeleniumLibrary, pytest + selenium, possibly Cypress or Playwright later).

Source of truth

This page is drawn from the perfshop-selenium block of the compose files.

Image and mode

perfshop-selenium:
  image: selenium/standalone-chrome:latest
  container_name: perfshop-selenium
  shm_size: 2gb
  environment:
    - SE_NODE_MAX_SESSIONS=2
    - SE_VNC_NO_PASSWORD=1
    - SE_START_XVFB=true
  ports:
    - "${SELENIUM_HTTP_PORT:-4444}:4444"
    - "${SELENIUM_VNC_PORT:-7900}:7900"

PerfShop uses the official selenium/standalone-chrome:latest image. "Standalone" mode means that hub, node, and browser all run in the same container — no distributed Grid to manage. This is more than enough for PerfShop's pedagogical needs (one or two concurrent tests), and it dramatically simplifies deployment.

Critical environment variables

Variable Value Effect
SE_NODE_MAX_SESSIONS=2 Maximum 2 concurrent WebDriver sessions per node. Lets a student launch a test through Scripts UI while a Squash TM campaign runs in parallel.
SE_VNC_NO_PASSWORD=1 Disables the noVNC password. This lets a student open http://localhost:7900 without having to enter "secret" (the default image password), which would be a pedagogical obstacle.
SE_START_XVFB=true Forces the start of a virtual X server (Xvfb). Required for Chrome to run in headless-compatible mode in the container while remaining capturable through VNC.

shm_size: 2gb — shared memory

shm_size: 2gb

This Docker option allocates 2 GB of shared memory (/dev/shm) to the Selenium container. It is a hard constraint of Chrome: without this allocation, Chrome crashes unpredictably when opening tabs or running complex JavaScript, with errors such as DevToolsActivePort file doesn't exist or silent segfaults.

The official Selenium image documents this requirement. PerfShop applies it systematically.

Two exposed ports

flowchart LR
  TR["perfshop-test-runner<br/>(Robot Framework / pytest)"]

  subgraph SEL["perfshop-selenium"]
    direction TB
    WD["WebDriver endpoint<br/>:4444/wd/hub"]
    VNC["noVNC server<br/>:7900"]
    CHROME["Google Chrome<br/>(headless / Xvfb)"]
    WD --> CHROME
    VNC --> CHROME
  end

  USER["Instructor<br/>or student"]

  TR -->|"POST /wd/hub/session<br/>GET /wd/hub/status"| WD
  USER -->|"http://localhost:7900<br/>(noVNC web client)"| VNC

Port 4444 — WebDriver

This is the standard Selenium port. All WebDriver clients (Java, Python, JavaScript, Robot Framework) talk to this endpoint over HTTP. The full hub URL is http://perfshop-selenium:4444/wd/hub (on internal DNS) or http://localhost:4444/wd/hub (from the host).

This URL is passed to the test runner through the SELENIUM_REMOTE_URL environment variable (see test-runner.md).

Port 7900 — noVNC

Port 7900 is a major pedagogical feature. It exposes a noVNC client (VNC over WebSocket in the browser) that lets anyone open a http://localhost:7900 tab and watch live the Chrome session running the test.

sequenceDiagram
  autonumber
  actor S as Student
  participant NAV as Browser<br/>(tab 1)
  participant SEL as perfshop-selenium<br/>:7900 noVNC
  participant CHROME as Chrome inside the container<br/>(Xvfb)
  participant TR as perfshop-test-runner

  S->>NAV: Opens http://localhost:7900
  NAV->>SEL: noVNC WebSocket
  SEL->>CHROME: Captures framebuffer
  CHROME-->>SEL: Pixels
  SEL-->>NAV: Video stream over WebSocket
  NAV-->>S: Displays Chrome live

  Note over S,TR: Meanwhile, a test runs

  TR->>SEL: POST /wd/hub/session (launch Chrome)
  SEL->>CHROME: Navigates, clicks, fills forms
  Note over NAV,CHROME: Student sees everything in real time<br/>in the noVNC tab

Concretely, while a Robot Framework test runs from the test runner, the student can open noVNC on a second screen and watch Chrome navigate, click, and fill forms — exactly as if they were screen-sharing a virtual machine.

This is especially useful for:

  • Debugging a failing test: seeing where Chrome stops, which element is not found
  • Demoing a scenario: the instructor launches a test, students watch it unfold live
  • Understanding WebDriver: visualizing concretely that a test drives a real browser

No noVNC password

With SE_VNC_NO_PASSWORD=1, the noVNC client opens directly on the Chrome session without a password prompt. This is a pedagogical choice: a student discovering the tool should not run into an undocumented secret password prompt.

Alternative ports depending on the environment

The SELENIUM_HTTP_PORT (default 4444) and SELENIUM_VNC_PORT (default 7900) variables allow host ports to be remapped in case of conflict. The internal ports (4444 and 7900) are fixed — they are defined by the official Selenium image.

No declared dependency

Selenium has no depends_on in the compose file: it starts in parallel with the other services. This is consistent — the test runner will send it a WebDriver request only when a test starts, and if Selenium is not yet ready at that moment, the test runner will retry or fail cleanly.

In practice, Selenium starts in 10 to 20 seconds (Chrome download, Xvfb startup, hub launch). This is faster than Squash TM which has a start_period: 120s, so Selenium is always ready before the first execution.

Typical use case — Robot Framework

Here is what using Selenium looks like from a Robot Framework test running in the test runner:

*** Settings ***
Library    SeleniumLibrary

*** Variables ***
${SELENIUM_URL}    %{SELENIUM_REMOTE_URL}
${FRONTEND_URL}    %{PERFSHOP_FRONTEND_INTERNAL}

*** Test Cases ***
Student Login
    Open Browser    ${FRONTEND_URL}/login    chrome
    ...    remote_url=${SELENIUM_URL}
    ...    options=add_argument("--no-sandbox"); add_argument("--disable-dev-shm-usage")
    Input Text    id=email    demo@perfshop.io
    Input Password    id=password    demo
    Click Button    Sign in
    Wait Until Page Contains    My account
    Close Browser

Key points:

  • ${SELENIUM_URL} is read from the SELENIUM_REMOTE_URL=http://perfshop-selenium:4444/wd/hub environment variable passed to the test runner by compose.
  • --no-sandbox and --disable-dev-shm-usage are the classic Chrome flags for running inside a container (even with shm_size: 2gb, some execution patterns benefit from them).
  • ${FRONTEND_URL} points to the frontend using internal Docker DNS (http://perfshop-frontend:80), not to localhost. The Chrome container sees the Docker network, not the host network.

Ports

Service Default host port Container port Environment variable
perfshop-selenium 4444 4444 SELENIUM_HTTP_PORT
perfshop-selenium 7900 7900 SELENIUM_VNC_PORT

Going further