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

Codeception documents automatic screenshots for failed acceptance tests: they appear in the HTML report. For a record of the steps leading up to a failure, enable Recorder in a suite that uses WebDriver. If your suite uses PhpBrowser, its documented failure artifact is the last page shown—not an image. The right method therefore depends on the suite’s browser module and whether you need a final state, a sequence of states, or page content.

What Codeception captures by default

Codeception’s Reporting documentation says that, by default, it saves a screenshot for a failed acceptance test and shows it in the HTML report. Treat that as a documented behavior for failed acceptance tests, not a guarantee that every test error in every suite produces an image.

The wording matters: the documentation says “failed test.” It does not enumerate which assertion failures, uncaught exceptions, setup or teardown errors, or runner-level errors are covered. If one of those paths matters to your team, verify it with your installed Codeception and module versions and the specific suite configuration.

First identify the module used by the suite. Check the relevant suite file, such as Acceptance.suite.yml, for its enabled modules. A WebDriver suite operates through a browser and supports screenshot capture. PhpBrowser is a different module; its failure artifact is a saved page, not a browser screenshot.

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

Find the default failure screenshot and report

Codeception’s global output directory defaults to tests/_output. The HTML report is where the Reporting documentation says the default acceptance-test failure screenshot is displayed. Open the report for the run that failed and inspect that test’s entry. If you do not see an image, confirm that you are looking at an acceptance suite, that its browser module is configured as expected, and that the failure follows a path covered by the behavior documented for your installed version.

Global configuration and suite configuration have different scopes. The global codeception.yml sets shared configuration, including the output path; a suite file can enable modules and can override shared settings. If you change the output directory or configure an extension only for one suite, look in the effective location and configuration for that suite rather than assuming every run uses the same settings.

Record every WebDriver step with Recorder

A final screenshot tells you what the page looked like at the end. Recorder is more useful when you need to reconstruct how the test reached that state: it takes a screenshot after each step and presents the images as a slideshow. The extension requires a suite with WebDriver enabled.

Enable it in the global codeception.yml or in the acceptance suite configuration, for example:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
extensions:
  enabled:
    - CodeceptionExtensionRecorder

The extension documentation also shows module-specific configuration. Its documented defaults include:

  • module: WebDriver selects the module Recorder observes.
  • delete_successful: true removes recordings for successful tests by default. If you need recordings from passing tests for comparison, configure this option accordingly.
  • delete_orphaned: false is the documented default for orphaned recordings.

Recorder writes image files under tests/_output/record_* and provides an index.html slideshow. Since successful-test recordings are deleted by default, a missing recording for a passing test may be expected. The extension documentation also describes an error_color setting in relation to an issue while generating a recording; that is not evidence that every test error automatically results in a screenshot.

Use the slideshow to follow the UI state around the point where the test stops succeeding. Recorder captures per-step images, but those images do not replace assertions, logs, or application-side diagnostics: they show visual states, not the underlying cause of a failure.

Take a screenshot at a chosen point in a WebDriver test

When you know which point is useful, call WebDriver’s public actor action in the test:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
$I->makeScreenshot('edit_page');

The documented example writes edit_page.png under tests/_output/debug. Place the call after the UI has reached the state you want to inspect; it captures the current page rather than an earlier point in the test.

For helper or module implementation code that needs to supply a filename, the WebDriver documentation also lists the hidden API _saveScreenshot($filename). Its example is:

$this->getModule('WebDriver')->_saveScreenshot(codecept_output_dir() . 'screenshot_1.png');

Prefer $I->makeScreenshot() in ordinary test code when it meets the need. The hidden API is a lower-level implementation detail; check it against the WebDriver module version installed in your project before building helper behavior around it.

Know what PhpBrowser saves

PhpBrowser does not provide the same browser-image artifact described for WebDriver. Its module documentation says that, if a test fails, it stores the last shown page in the output directory. Read this as a page artifact, not a PNG screenshot or a browser-rendered image. It can help you inspect the response or page content reached before failure, but it is not interchangeable with a visual capture.

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

If you specifically need a browser screenshot or a step-by-step visual record, use a WebDriver-enabled suite and the corresponding capture method. Do not infer that switching on Recorder will turn PhpBrowser’s saved page into an image: Recorder is documented for a suite using WebDriver.

Choose the capture method by the question you need to answer

Need Method Artifact and location Scope
See the final state of a failed acceptance test Codeception’s documented default Screenshot displayed in the HTML report Failed acceptance tests; documentation does not enumerate every error path
Understand the sequence before a failure Recorder extension Per-step screenshots under tests/_output/record_*, with an index.html slideshow Suite with WebDriver enabled
Capture a known point in a test $I->makeScreenshot('name') Image under tests/_output/debug WebDriver test
Inspect the last page reached PhpBrowser failure behavior Saved page in the output directory, not a screenshot PhpBrowser test failure

Custom failure handling: what is and is not established

Codeception’s module reference lists _failed($test, $fail) as a hook called when a test fails before _after. WebDriver documents _saveScreenshot. Together, these establish a possible extension point for custom failure handling, but they are not a ready-made implementation for all failure scenarios.

A custom handler depends on the test lifecycle and whether the browser session is still available when the hook runs. Setup failures may occur before a usable session exists; teardown or runner-level errors may follow a different path. If you implement a helper or module around this hook, check the installed Codeception and WebDriver module versions, test the exact failure cases you care about, and handle cases where no active browser session or output file can be obtained. Do not present a custom hook as a universal guarantee based only on the documented hook name.

Rank #4
The SQL Programming Language: .
  • Used Book in Good Condition
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot missing or unexpected artifacts

  • No image in the report: confirm the test belongs to an acceptance suite and check that suite’s browser module and generated HTML report. The documented default is for failed acceptance tests, not every suite or every type of error.
  • Recorder produces no slideshow: verify that the extension is enabled in the configuration scope used by the run and that the suite uses WebDriver. Check the run’s effective output directory for a record_* folder and its index.html.
  • Passing tests have no Recorder files: Recorder’s documented delete_successful default is true, so successful-test recordings are removed by default. Change the setting only if retaining them is useful for your workflow.
  • The artifact is page content rather than an image: check whether the suite uses PhpBrowser. Its documented failure behavior saves the last shown page; it does not promise a screenshot.
  • A manual screenshot is absent: confirm the action ran after the relevant page state was reached, inspect the configured output location, and confirm the test is using WebDriver. For code that calls the hidden API, check its availability against the installed module version.
  • A custom failure hook cannot capture: the browser session may no longer be available at that lifecycle point, or the failure may have occurred before the session was established. Test the individual setup, test-body, teardown, and runner failure paths instead of assuming they behave alike.

Version and configuration checks

Codeception’s current documentation and older 4.x getting-started material do not establish when each behavior or default was introduced, or that every detail is identical across releases. Before relying on a default, check the Codeception version and module versions installed in your project against the documentation relevant to those versions.

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

Also distinguish the shared codeception.yml from suite files such as Acceptance.suite.yml. The global output path defaults to tests/_output, but suite settings can enable modules and override shared configuration. Recorder may be enabled globally or for the acceptance suite; enabling it in one scope does not mean it is active for every suite.

Or skip the browser setup

Codeception’s WebDriver and Recorder methods capture a page within a running test. ScreenshotNeo is a separate option for taking screenshots of a URL through an API; it does not attach a capture to Codeception’s failure report or record the test’s browser session. For a URL-based capture, one GET request can return an image or PDF. The call below uses cURL; see the ScreenshotNeo API documentation for request options.

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

Equivalent examples in Python and Node.js:

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)
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 accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, and failed loads are not billed. Its response includes page-verdict and billing headers, and its MCP server provides screenshot tools for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. These URL captures are useful for a separate screenshot workflow, not a substitute for debugging the in-test browser state.

Sign up for ScreenshotNeo to try 1,000 screenshots a month free, with no card required.

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

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.