The JavaScript steps turn browser-side failures into test failures. From the moment a scenario starts, webship-js attaches Playwright listeners to the page: page.on('pageerror') captures every uncaught exception, and page.on('console') captures console messages at the levels you configure (by default only console.error). Everything is collected into a per-scenario list, so an error thrown by a broken bundle, a failed analytics snippet, or a bad third-party embed is recorded even if the page still looks fine.
What happens with the collected errors depends on the active mode. In warn mode (the default) a yellow warning is printed at the end of the scenario but the scenario still passes. In fail mode any collected error fails the scenario automatically. In off mode collection is disabled entirely. The mode is resolved per scenario, first match wins: scenario tag (@js-fail, @js-warn, @js-off; legacy @javascript means fail and @js-errors means off), then the WEBSHIP_JS_ERROR_MODE environment variable, then the javascript.mode worldParameter, then the default warn.
Reach for the explicit steps below when you want the check at a precise point in the scenario rather than at teardown - for example right after an interaction that historically broke, or to assert a specific error pattern never appears while tolerating known noise. The explicit steps always assert regardless of mode, and calling one suppresses the automatic end-of-scenario report so the same error is never reported twice.
Quick reference
| Step | What it does |
|---|---|
Then there should be no JavaScript errors | Fail if any page error or captured console error has been collected so far. |
Then there should be no JavaScript warnings | Fail if any console.warning message was captured (requires warning in the captured levels). |
Then JavaScript errors should not match "TypeError" | Fail if any collected error message matches the given regular expression. |
Then print JavaScript errors | Print collected errors for debugging; never fails. |
Steps in detail
Then there should be no JavaScript errors
Asserts that no JavaScript errors have been collected so far in the scenario. This is the explicit "hard check": it always fails on error, even when the scenario is running in warn or off mode, and it honors the configured ignore regex so known noise is filtered out. Using it also marks the errors as handled, preventing the automatic report at scenario end.
Given I am on "/index.html"
When I press "Load dashboard"
Then there should be no JavaScript errors
Then there should be no JavaScript warnings
Asserts that no console.warning messages were captured. By default only console.error is captured, so this step only has teeth when warning is included in the captured levels - set WEBSHIP_JS_ERROR_LEVELS=error,warning or add warning to javascript.levels in worldParameters. Useful for keeping deprecation warnings out of a production build.
# Run with WEBSHIP_JS_ERROR_LEVELS=error,warning
Given I am on "/index.html"
Then there should be no JavaScript warnings
Then JavaScript errors should not match "TypeError"
Asserts that no collected error message matches a regular expression. This is the middle ground when a page has unavoidable noise (a chatty third-party script, say) but a specific bug pattern must never reappear. The parameter is compiled with new RegExp(), so patterns like ReferenceError: .* is not defined work; an invalid pattern fails the step with a clear message. Note this variant does not apply the ignore filter - it matches against everything collected.
Given I am on "/dynamic-examples.html"
When I press "Load more"
Then JavaScript errors should not match "is not a function"
And JavaScript errors should not match "Cannot read property"
Then print JavaScript errors
Diagnostic only - prints the errors collected so far (or --- JavaScript errors: none ---) and never fails. Drop it into a scenario you are debugging to see exactly what the browser logged up to that point, then remove it once the mystery is solved.
When I press "Save"
And print JavaScript errors
Then I should see "Saved"
Complete example
Feature: JavaScript error detection
@js-fail
Scenario: Dashboard loads without console errors
Given I am on "/dynamic-examples.html"
When I press "Load Content"
And I wait for the text "Content loaded" to appear
Then there should be no JavaScript errors
And JavaScript errors should not match "Uncaught"
Scenario: Known-noisy page still guards a specific regression
Given I am on "/index.html"
Then JavaScript errors should not match "ReferenceError: .* is not defined"
Configuration
Everything is configurable per project via the javascript block in worldParameters, with environment variables taking precedence:
javascript: {
mode: 'warn', // 'warn' | 'fail' | 'off'
levels: ['error'], // console levels to capture
ignore: '', // regex of messages to drop
beforeScenario: false, // snapshot pre-existing errors
afterScenario: true, // report at scenario end
}
| Setting | Env override | Notes |
|---|---|---|
mode | WEBSHIP_JS_ERROR_MODE | warn (default), fail, or off. Tags win over env and config. |
levels | WEBSHIP_JS_ERROR_LEVELS | Comma-separated console levels, e.g. error,warning. |
ignore | WEBSHIP_JS_ERROR_IGNORE | Regex; matching messages are dropped from reports and the "no errors" step. |
beforeScenario | WEBSHIP_JS_ERROR_BEFORE=1 | Log errors already present when the scenario starts (page reuse). |
afterScenario | WEBSHIP_JS_ERROR_AFTER=0 | Set to 0/false to disable the end-of-scenario report. |
| Tag | Effect |
|---|---|
@js-fail / @javascript (legacy) | Force fail mode for this scenario. |
@js-warn | Force warn mode. |
@js-off / @js-errors (legacy) | Disable capture for this scenario. |