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.

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

A “blank page” in a Selenium or Codeception acceptance test is a symptom, not a diagnosis. The browser may be on the wrong host, the WebDriver session may never have started, PhpBrowser may be unable to execute JavaScript, or the application may still be rendering when the assertion runs. Triage the failure in this order: identify the Codeception module, verify the URL from the browser’s network environment, confirm session creation, inspect the loaded document, then wait for client-side content and collect logs.

1. Identify what your acceptance test is actually running

Start with the suite configuration, not the screenshot. Codeception’s PhpBrowser and WebDriver modules exercise different layers of an application.

PhpBrowser is not a real browser

PhpBrowser sends HTTP requests with Guzzle and parses responses with Symfony BrowserKit. It does not execute JavaScript. A single-page application that returns an almost empty HTML shell can therefore look blank in a PhpBrowser scenario even though it renders normally in Chrome after JavaScript runs. Use PhpBrowser for server responses, redirects, cookies, status codes and static HTML; do not use it to verify a client-rendered interface.

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

WebDriver controls Chrome or Firefox

WebDriver starts or connects to a real browser through Selenium and a browser-specific driver. JavaScript, layout, network requests and user-visible rendering occur in that browser. If the acceptance test is meant to reproduce what a visitor sees, enable WebDriver and remove competing web modules.

 // tests/Support/Suites/Acceptance.suite.yml
actor: AcceptanceTester
modules:
    enabled:
        - WebDriver:
            url: 'http://app.test'
            browser: chrome
            window_size: 1440x900
            # headless: true   # enable when your driver supports it
        - HelperAcceptance

Do not enable PhpBrowser or a framework module that implements the same web interface alongside WebDriver in the same acceptance suite. Codeception documents that these modules conflict and can create ambiguous shared actions. An explicitly supported dependent module, such as REST using PhpBrowser, is a different arrangement; follow that module’s documented dependency pattern.

2. Verify the URL from the browser’s point of view

The WebDriver module’s url is the application’s base URL. amOnPage() opens a path relative to that value, so a correct-looking test can still navigate to the wrong origin.

Check the resolved address

  1. Read the acceptance suite’s url exactly, including scheme, host and port.
  2. Inspect every amOnPage('/path') call. Confirm the resulting URL is the route you intend, rather than a development hostname or a path served by a different virtual host.
  3. Use an absolute URL temporarily when diagnosing: $I->amOnPage('http://app.test/login');. If that works while the relative path fails, fix the base URL or the path.

Test reachability inside the browser environment

Your test runner, Selenium service, browser and application may be separate containers or hosts. localhost inside a Chrome container means that container, not your laptop and not necessarily the application container. A hostname resolvable by PHP on the runner may not resolve from the remote browser.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • From the machine or container hosting the browser, resolve the application hostname and request the exact URL.
  • Use the service name and shared Docker network when the application and browser are Compose services.
  • Expose the application on an address reachable from the Selenium host; do not bind it only to loopback on another machine.
  • Check HTTP versus HTTPS, non-default ports, certificates and authentication gateways.

Codeception’s WebDriver documentation calls out networking for local sites in Docker examples. Treat “the URL works in my test runner” and “the URL works in the browser container” as separate facts.

3. Confirm Selenium and the browser session before debugging rendering

Selenium commands reach a browser through a browser-specific executable driver. If the driver cannot start, no page can render, regardless of your application code.

Validate the endpoint and session settings

Compare the WebDriver configuration with the Selenium endpoint: host, port and any path required by your Selenium deployment. Then run the suite with verbose output and look for a successful session creation before the first navigation command. A refused connection, an empty server reply, an incompatible browser/driver pair or a missing executable is a session problem, not a blank-page rendering problem.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

The Selenium installation guide explains the role of browser drivers and current installation approaches: installing browser drivers. Ensure the browser and driver versions are compatible and that the driver is on the executable path used by the Selenium service.

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

Separate historical errors from current diagnosis

A Codeception issue from the 2.5.3/ChromeDriver era shows a failed session request with an empty server reply. It is useful as an example of a connection-layer failure, but it is not evidence of a current, universal Codeception defect. Diagnose the versions and endpoint you run today.

Minimal session smoke test

 // tests/acceptance/SessionCest.php
class SessionCest
{
    public function canStart(AcceptanceTester $I): void
    {
        $I->amOnPage('/');
        $I->seeInCurrentUrl('/');
        $I->makeScreenshot('session-started');
    }
}

If this test cannot create a session or save a screenshot, stop and repair Selenium, the driver, browser startup flags or networking before investigating frontend code.

4. Inspect what the browser actually loaded

Once a session exists, gather evidence from the real browser instead of inferring from a failed assertion.

Compare URL, source and screenshot

Save a screenshot and page source at the failure point. The combination distinguishes several cases:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Unexpected URL: a redirect, base-URL error or authentication wall sent the browser elsewhere.
  • Source contains an error document: the server, proxy or route failed before the frontend ran.
  • Source is only an application shell: JavaScript did not execute, crashed, or has not completed.
  • Screenshot is white while source has content: CSS, a browser crash, a blocked resource, an overlay or a rendering error may be hiding it.

In a Cest, use Codeception’s screenshot and source helpers where available in your version, or configure the WebDriver module to preserve artifacts in the HTML report. Keep the artifact from the exact failing step, not only from teardown.

Turn on browser and JavaScript diagnostics

The WebDriver module supports options such as debug_log_entries and log_js_errors. Enable them when needed so JavaScript errors can appear in the HTML report, then rerun the smallest failing test. A message such as “container is null,” a failed module import or a blocked script points to application or environment configuration; a navigation timeout points to reachability or server response time.

5. Wait for a meaningful condition, not an arbitrary sleep

Modern interfaces often load a shell first and populate it after API calls. An immediate assertion can report a blank page even when the UI is healthy.

Wait for a visible element or text

public function dashboardRenders(AcceptanceTester $I): void
{
    $I->amOnPage('/dashboard');
    $I->waitForElementVisible('[data-testid="dashboard"]', 15);
    $I->see('Dashboard');
}

Use a stable selector tied to the interface contract, such as a role, test ID or unique heading. Codeception documents explicit waits for asynchronous JavaScript behavior. A generic pause can help prove that timing is involved, but it should not be the final synchronization strategy:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
$I->wait(2); // diagnostic only; replace with a condition

Make the condition reflect readiness

  • Wait for a visible application landmark, not the disappearance of a spinner alone.
  • Assert the expected text after the element is present.
  • If data arrives through an API, ensure the test account and backend fixtures make that request succeed.
  • Increase the condition timeout only after measuring realistic startup and network delays; excessive timeouts hide failures and slow feedback.

6. Remove module ambiguity and configuration drift

Review every enabled module in the acceptance suite, including inherited configuration and environment-specific overrides. Codeception says WebDriver conflicts with modules implementing its web interface, including PhpBrowser and framework modules. Duplicate modules can cause the actor’s shared actions to target an unintended implementation.

Configuration checklist

  • Exactly one primary web module is enabled for this acceptance suite.
  • The suite you run is the suite whose configuration you edited.
  • The configured url includes the reachable origin.
  • Browser name, headless flags, window size and Selenium endpoint match the environment.
  • Timeouts and logging options are defined at the active configuration level.
  • Environment variables are populated in the test process, not only in your interactive shell.

Codeception’s Modules and Helpers documentation explains module conflicts and shared actions. The WebDriver module guide covers URL, browser, headless, Docker networking, timeout and logging settings.

PhpBrowser or WebDriver: choose the diagnostic tool

Axis PhpBrowser WebDriver
Execution model Guzzle and Symfony BrowserKit request/HTML simulation Real Chrome or Firefox controlled through WebDriver
JavaScript Not executed Browser executes JavaScript
Best diagnostic use Server responses and HTML-level behavior User-visible UI and client-side rendering
Trade-off Faster; exposes response headers and status Slower; requires browser session and driver setup

A practical strategy is to keep fast PhpBrowser tests for backend contracts and add WebDriver coverage only for flows whose correctness depends on JavaScript, layout or browser behavior.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Common blank-page failures and fixes

The test says “connection refused” or cannot create a session

Cause: Selenium is stopped, the endpoint is wrong, the driver executable is missing, or the browser/driver pair is incompatible.
Fix: Check the Selenium host and port, start the service, verify driver installation and versions, and run the session smoke test before navigating.

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

The browser opens an empty document or an error page

Cause: The base URL, route, DNS, port, TLS certificate or container network is wrong.
Fix: Test the exact URL from the browser environment, inspect the current URL and source, and correct the reachable origin.

PhpBrowser sees no application content

Cause: The page depends on JavaScript, which PhpBrowser does not execute.
Fix: Move the UI assertion to a WebDriver scenario, or test the underlying HTTP/API response separately with PhpBrowser.

Source has an app shell but the screenshot is blank

Cause: A JavaScript exception, blocked asset, CSP problem, failed API request, overlay or delayed render.
Fix: Enable JavaScript logging, inspect browser/network errors, wait for a visible landmark and verify that test data and API hosts are reachable.

Content appears only after a long delay

Cause: The assertion races asynchronous rendering or a slow dependency.
Fix: Wait for a specific element or text with a bounded timeout; repair the slow dependency instead of adding a large fixed sleep.

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

Actions behave inconsistently after adding a module

Cause: WebDriver is loaded with PhpBrowser or a framework web module, creating conflicting shared actions.
Fix: Remove the duplicate web module and keep only the intended browser implementation.

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

A repeatable triage sequence

  1. Open the active acceptance suite configuration and identify PhpBrowser versus WebDriver.
  2. Confirm the configured base URL and resolve the path passed to amOnPage().
  3. From the browser host or container, verify DNS, port, HTTP status and TLS access to that URL.
  4. Confirm Selenium and the browser driver create a session.
  5. Capture current URL, page source, screenshot and JavaScript diagnostics.
  6. Wait for a meaningful visible element or text if the page is asynchronous.
  7. Remove conflicting modules and rerun the smallest reproducible test.

Or skip the browser setup

For a deterministic page image outside the acceptance runner, 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. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP tools—take_screenshot, get_page_info and capture_pdf—let Claude, Cursor and other MCP clients inspect pages.

One-call cURL capture

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 ScreenshotNeo documentation for options and response details.

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('shot.webp', data);

ScreenshotNeo supports full-page and element captures, device presets, custom viewport and retina scale, PDF output, custom CSS and JavaScript, clicks, selector waits, delays, network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can simplify migration.

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

Plans and cost behavior

Plan Allowance Price
Free 1,000 shots/month No card
Starter 3,000 shots/month $5
Growth 15,000 shots/month $15
Pro 60,000 shots/month $39
Scale 250,000 shots/month $99
Business 1,000,000 shots/month $249

Every feature is available on every plan; yearly billing gives two months free. The free plan includes 1,000 screenshots each month with no card, and paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

FAQ

Can I fix a blank page by increasing the WebDriver timeout?

Only when the page is healthy but genuinely slow. First prove that the URL is reachable, the session exists and JavaScript is not failing; then wait for a specific visible condition.

Should acceptance tests use headless Chrome?

Headless mode is appropriate for automated environments, but reproduce the failure in a visible browser when screenshots or layout behavior are unclear. The underlying URL, driver and module checks remain the same.

Is a screenshot enough to diagnose the failure?

No. Pair it with the current URL, page source and browser or JavaScript logs. A white image cannot tell you by itself whether navigation, rendering or timing failed.

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

Frequently Asked Questions

Can I fix a blank page by increasing the WebDriver timeout?

Only when the page is healthy but genuinely slow. First prove that the URL is reachable, the session exists and JavaScript is not failing; then wait for a specific visible condition.

Should acceptance tests use headless Chrome?

Headless mode is appropriate for automated environments, but reproduce the failure in a visible browser when screenshots or layout behavior are unclear. The underlying URL, driver and module checks remain the same.

Is a screenshot enough to diagnose the failure?

No. Pair it with the current URL, page source and browser or JavaScript logs. A white image cannot tell you by itself whether navigation, rendering or timing failed.

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.

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