Recommended Free Tools
When a CodeceptJS test says an element is not visible on Jenkins but passes locally, start by proving which browser mode, display environment, executable, viewport and page state the job actually uses. Keep the run headless on a display-less agent unless the test genuinely requires a headed window. If headed mode is required, provide a virtual display such as Xvfb. Then wait for the UI state you intend to test, distinguish DOM presence from rendered visibility, and preserve logs and screenshots from the failing build.
1. Identify the failure you are actually seeing
“Not visible” is not one diagnosis. A Jenkins run can fail because Chrome cannot launch, because the page has not reached the state your test expects, because the selector matches a hidden node, or because Jenkins is using a different browser binary or viewport. Record the failing step, selector, current URL, browser mode, viewport and a screenshot before changing timeouts.
- Launch/display failure: Chrome reports a display error or never starts.
- Timing failure: the page is still navigating, rendering a modal or loading data.
- Visibility-versus-presence mismatch: the node is in the DOM but hidden by CSS, an overlay, an animation or responsive layout.
- Environment drift: Jenkins resolves a different Chrome/Chromium executable, launch mode or window size than your workstation.
The documentation does not establish one Jenkins-wide root cause. Treat the following as a ranked diagnostic process for your agent and application.
2. Make the headless or headed choice explicit
Use headless mode on a display-less worker
CodeceptJS runs headless by default and documents a CI-conditional configuration:
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →#1 Best Overall
const { setHeadlessWhen } = require('@codeceptjs/configure');
setHeadlessWhen(process.env.CI);
exports.config = {
helpers: {
Puppeteer: {
url: 'https://your-app.example',
show: false
}
}
};
Inspect the codecept.conf.js that Jenkins loads, including any CI-specific file or environment override. Do not infer its values from your local run. For a one-off check, the browser plugin can force headless mode:
npx codeceptjs run -p browser:hide
This is usually the simplest fix when the test does not depend on seeing a browser window.
Use a virtual display when headed behavior is required
If the test must run with show: true, a Linux worker needs a display service. Puppeteer’s CI troubleshooting guidance calls for launching Xvfb for non-headless Chrome for Testing. A typical Jenkins shell step is:
Xvfb :99 -screen 0 1280x1024x24 &
export DISPLAY=:99
npx codeceptjs run
Adapt process supervision and cleanup to your agent image. If the test has no headed-browser requirement, remove this dependency instead of adding a display server.
Free tools Windows power users keep installed
One-click scans. No signup required.
3. Wait for the state, not an arbitrary number of seconds
Wait for asynchronous UI changes
Automatic waiting covers many interactions, but a modal, toast or data-driven component may need an explicit state check. Wait for the element that proves the transition completed:
Rank #2
Scenario('opens the confirmation dialog', async ({ I }) => {
I.click('[data-test="delete"]');
I.waitForVisible('.modal', 10);
I.seeElement('.modal');
});
Use the smallest selector that represents the user-visible state. A long blanket sleep can hide a race and make the whole suite slower. If the application is consistently slower in CI, CodeceptJS’s Puppeteer helper exposes waitForAction; its documented default is 100 milliseconds. Increase it only after confirming that the action itself, rather than navigation or a missing state wait, is the bottleneck.
Choose a navigation condition that matches the application
The Puppeteer helper documents domcontentloaded as its default navigation strategy and allows networkidle0, which can suit a single-page application that becomes usable only after requests finish:
exports.config = {
helpers: {
Puppeteer: {
waitForNavigation: 'networkidle0'
}
}
};
Do not use network-idle blindly: an app with polling, analytics or long-lived connections may never become idle. Prefer a product-specific readiness signal, such as a visible heading or loaded table, after navigation.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall4. Separate DOM presence from user-visible rendering
CodeceptJS treats these as different assertions:
I.seeElement(selector)checks that an element exists and is visible.I.seeElementInDOM(selector)checks DOM presence even when the matching element may be invisible.
Use seeElementInDOM only when presence is the requirement—for example, verifying that a template inserted a hidden panel. Keep seeElement when the acceptance criterion is that a user can see and interact with the control. For a visibility failure, inspect the captured page for display:none, visibility:hidden, zero dimensions, an off-screen responsive layout, a covering overlay or an animation that has not completed. These are diagnostic possibilities, not assumptions about your application.
5. Align Jenkins with the local browser setup
Confirm the executable
A normal Puppeteer installation downloads a matching Chromium. If your job uses an existing Chrome installation, configure its path explicitly:
Rank #3
exports.config = {
helpers: {
Puppeteer: {
chrome: {
executablePath: process.env.CHROME_BIN
}
}
}
};
The exact configuration shape depends on your CodeceptJS version; the important check is the resolved path in the Jenkins log. With puppeteer-core, you must provide the browser executable yourself. Compare the Jenkins install output, browser version and launch flags with the machine where the test passes.
Match the viewport and device scale
Responsive CSS can hide or relocate a target at a different width. Set a known window size, then reproduce that size locally:
npx codeceptjs run -p browser:windowSize=1024x768
You can also set the viewport in the browser helper configuration. Keep headless/headed mode, viewport, timezone and relevant cookies consistent while isolating the failure; otherwise you may be debugging two different page states.
6. Capture evidence from the failing build
Run the smallest failing scenario with CodeceptJS diagnostics and retain the output as Jenkins artifacts:
npx codeceptjs run --debug
npx codeceptjs run --verbose
DEBUG=codeceptjs:* npx codeceptjs run
Enable the screenshot/reporting options used by your project and archive the resulting files. At the assertion, capture or log:
Rank #4
- Used Book in Good Condition
- the current URL and page title;
- the selector and number of matching nodes;
- whether the node has non-zero dimensions and computed visibility;
- the viewport size and user agent;
- the browser executable path and launch mode.
Compare the Jenkins screenshot with a local run using the same mode and viewport. A screenshot showing a login page, consent dialog or error page points to application state or environment setup; a matching page with a hidden target points to selector, CSS or timing logic.
7. A practical decision table
| Observation | First check | Next action |
|---|---|---|
| Chrome reports display errors | Is headed mode enabled on a worker without a display? | Force headless with -p browser:hide, or launch Xvfb for an intentionally headed run. |
| The selector exists but visibility fails | Does the requirement concern presence or visibility? | Use seeElementInDOM for presence; otherwise inspect CSS, overlays, animation and the screenshot, then wait explicitly. |
| Failures occur around navigation or modals | Is the test waiting for the actual completion state? | Add waitForVisible/waitForText for that state and select a suitable navigation condition. |
| Local passes, Jenkins fails | Are executable, mode and viewport identical? | Log the resolved Chrome path, set the same mode and window size, and rerun. |
| The report has no useful context | Are debug logs and screenshots retained? | Use CodeceptJS debug flags and archive the artifacts in Jenkins. |
8. Common fixes that make failures worse
- Adding a global sleep: it slows every test and still may miss a delayed state. Wait on the state you need.
- Forcing headed mode to “see” the problem: without Xvfb, this creates a display failure unrelated to the selector.
- Changing the assertion to presence without checking the requirement: the test may pass while a real user still cannot see the control.
- Assuming local Chrome is used: Jenkins may resolve downloaded Chromium or a system binary with different defaults.
- Choosing
networkidle0for every page: polling applications may never satisfy it; use a concrete readiness element instead.
Or skip the browser setup
For repeatable evidence outside the Jenkins browser process, 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 server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.
One GET request returns PNG, JPEG, WebP or PDF. See the ScreenshotNeo documentation for all options, including selectors, waits, custom headers, cookies, JavaScript, resource blocking, device presets and signed webhooks.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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}`);
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.
FAQ
Should every Jenkins run use headless mode?
No. Use headless unless the test genuinely requires headed browser behavior; headed Linux runs need a display such as Xvfb.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Is a longer timeout always the fix?
No. First verify that the selector and readiness condition represent the state the test needs. Then adjust the relevant wait or action timing.
Best Value
What if the element is in the DOM but hidden?
Use a presence assertion only if that is the requirement. Otherwise inspect the rendered state and wait for visibility after the application removes the hiding condition.
Frequently Asked Questions
Should every Jenkins run use headless mode?
No. Use headless unless the test genuinely requires headed browser behavior; headed Linux runs need a display such as Xvfb.
Is a longer timeout always the fix?
No. First verify that the selector and readiness condition represent the state the test needs. Then adjust the relevant wait or action timing.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsWhat if the element is in the DOM but hidden?
Use a presence assertion only if that is the requirement. Otherwise inspect the rendered state and wait for visibility after the application removes the hiding condition.
The Bottom Line
Make Jenkins’ browser mode, display, executable and viewport explicit; wait for the application state you intend to assert; and preserve screenshots and debug logs. That sequence distinguishes infrastructure failures from genuine visibility defects without hiding races behind arbitrary sleeps.
Quick Recap
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.

