Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
If a w2ui overlay appears in headed Cypress but not in cypress run, first find out whether it was never created, was created but is hidden or clipped, or was dismissed before the assertion. Trigger it with a real Cypress action, let Cypress retry a query for the overlay in the application document, and assert visibility. Then reproduce with the same browser as CI and control both the Cypress viewport and the headless browser’s screen size; they are separate settings.
What is actually missing: the overlay node, or its visible rendering?
w2ui describes an overlay as a popup within the page, implemented by w2utils rather than by the separate w2popup object. The w2overlay plugin positions an overlay under or above a target element. It normally shows one overlay at a time, hides it on an outside click, and can use a unique name when multiple overlays are intentional. Its placement and appearance can depend on alignment, offsets, dimensions, CSS classes, styles, callbacks, and the openAbove option.
That distinction matters in a failing test: an overlay can exist in the DOM without being visible or clickable. Cypress uses real browser rendering and layout checks, so existence alone does not prove that an element has usable geometry, is unobscured, or can be interacted with. First test existence; then test visibility. That tells you whether to investigate lifecycle and selectors or instead CSS, geometry, stacking, dismissal, or browser differences.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Also distinguish a w2ui tag from an overlay. A tag follows its target and is destroyed if that target is destroyed. If the application re-renders or replaces an input, transient UI associated with the old target may not carry over to the newly rendered one.
#1 Best Overall
Use this debugging sequence
-
Confirm the target and use the application’s real trigger
Assert that the target exists and is interactable, then use the action that opens the overlay in normal use: for example,
click(),focus(), or the relevant application event. Avoid opening it only through a test-only shortcut unless that shortcut is what the product is meant to use. -
Wait for a UI condition, not a guessed duration
After triggering the control, query a stable overlay selector or distinctive overlay text and assert the condition you need. Cypress retries queries and assertions while waiting. An arbitrary sleep can make a slow run pass occasionally without proving the overlay is ready, so use one only when there is a specific delay the application intentionally requires.
-
Check the application document
Use
cy.get()orcy.contains()to query the application DOM. Cypress re-queries while commands are waiting and checks that elements belong to the document. Prefer a stable ID, role, or distinctive text to a positional selector. Avoid assuming that an overlay is a child of the triggering control: a popup can be positioned outside the usual document flow.Recommended: Fix Windows Errors and Clear Junk Files in Minutes - Free Scan →Recommended: Crashes or Glitches? A Free Driver Scan Usually Finds the Culprit →Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy. -
Separate existence from visibility
Start with
should('exist'). If it passes, checkshould('be.visible')separately. A present-but-hidden node shifts the diagnosis away from a missing selector and toward CSS, geometry, timing, or dismissal. If visibility fails, inspect computeddisplay,visibility, andopacity; dimensions; the bounding rectangle; position andz-index; and any element covering the overlay. -
Check whether another action dismissed it
w2ui hides an overlay after an outside click. A later Cypress click, blur, or application re-render can therefore close it before the assertion. Keep the open action and overlay assertion adjacent while diagnosing. Use w2ui’s
nameoption only if the application intentionally needs concurrent overlays; it is not a general fix for a timing or visibility failure. -
Inspect clipping, stacking, and target replacement
Look for
overflow: hiddenon a container, transformed ancestors, a conflicting stacking context orz-index, and placement beyond a viewport edge. Check whether a re-render replaced the target between the trigger and assertion. If so, inspect the application’s event and render lifecycle rather than trying to preserve a transient overlay attached to an obsolete element. -
Match both kinds of browser dimensions
Set the application viewport with
cy.viewport(width, height)or the project’sviewportWidthandviewportHeightconfiguration. Separately, Cypress documents a 1280 × 720 headless rendering screen default and device pixel ratio 1. If screenshot or video dimensions affect the failure, configure browser screen dimensions inbefore:browser:launch. Changing the application viewport does not, by itself, change the browser screen size used for screenshots and videos.Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy. -
Reproduce the CI browser and compare artifacts
cypress runlaunches browsers headlessly by default. Re-run headed and headless with the same browser used in CI, then compare screenshots or video. Cypress documents headless support for Electron, Chrome/Chromium/Edge, Firefox, and experimental WebKit. Browser choice matters: Cypress describes its bundled Electron browser as deprecated and notes that its embedded Chromium trails current Chrome. If local debugging uses Chrome but CI uses Electron, reproduce with the CI browser before attributing the issue to headless mode itself.
A minimal Cypress test pattern
Replace the example selectors and text with stable values from your application and the w2ui version it uses. Keep the trigger, existence check, and visibility check explicit so a failure identifies its layer.
Rank #4
it('shows the options overlay', () => {
cy.viewport(1280, 720)
cy.get('#input-overlay')
.should('be.visible')
.click()
cy.get('.w2ui-overlay')
.should('exist')
.and('be.visible')
cy.contains('.w2ui-overlay', 'Expected overlay text')
.should('be.visible')
})
The class shown is an example, not a promise that every w2ui release or application emits the same markup. Confirm the actual overlay selector in the version under test. If the overlay is outside the normal flow, query it in the application document rather than assuming it is nested beneath the input. Add a click assertion only after visibility is working; otherwise, a failed click gives less diagnostic information than a failed visibility assertion.
Set consistent dimensions in Cypress
There are two geometry controls to consider. The application viewport governs the page layout and can be set in test code or Cypress configuration. Browser screen dimensions govern the headless rendering environment used for screenshots and videos and can be set in the browser launch hook. Choose values that match the environment you are trying to reproduce, and record both when comparing runs.
Free tools Windows power users keep installed
One-click scans. No signup required.
// In a test: control the application viewport
cy.viewport(1280, 720)
// In cypress.config.js: control browser screen dimensions for artifacts
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('before:browser:launch', (browser, launchOptions) => {
launchOptions.args.push('--window-size=1280,720')
return launchOptions
})
}
}
})
Browser launch arguments can vary by browser and version; verify the resulting screenshot or video rather than assuming an argument changed the dimensions as intended. The launch hook example is for the screen-size setting, not a replacement for cy.viewport(). If the page layout is wrong, inspect the application viewport; if the captured artifact dimensions are wrong, inspect the browser screen configuration.
Classify the failure before changing code
| What you observe | Likely layer | Next check |
|---|---|---|
| The overlay query never finds a node | Trigger, selector, lifecycle, or wait condition | Confirm the real event opens it; check the selector against rendered markup and whether a re-render replaces the target. |
| The node exists but is not visible | CSS, geometry, stacking, or timing | Inspect computed styles, dimensions, bounding rectangle, clipping, covering elements, and z-index. |
| The overlay appears and then vanishes | Outside click, blur, or re-render | Keep the assertion adjacent to the trigger and inspect intervening Cypress actions and application updates. |
| It works headed, fails headless, or differs between browsers | Screen/viewport geometry or browser parity | Compare artifacts with matching viewport and screen dimensions, then reproduce using the CI browser. |
Common fixes and recovery checks
- Selector returns nothing: inspect the rendered application DOM after the trigger and update the selector to a stable element actually emitted by the app’s w2ui version. Do not infer that the overlay is missing just because it is not nested under the input.
- Existence passes but visibility fails: inspect geometry and computed styles in the browser. Correct the clipping container, conflicting stacking context, or edge placement in the application; do not weaken the test to accept an invisible overlay if visibility is what the user needs.
- Visibility passes but click fails: check whether another element covers the overlay and whether the test clicks a genuinely interactable part. Cypress visibility and click commands check visibility and interactability, not just DOM presence.
- Overlay closes before assertion: remove or relocate intervening outside clicks and blur actions, and check whether a render replaces the target. Re-open using the normal control before testing the overlay content.
- Only CI fails: record the browser name, version, viewport, and screen dimensions, then run the same browser locally if available. Compare screenshots or video to determine whether the overlay is absent, clipped, obscured, or simply positioned differently.
- Electron differs from local Chrome: reproduce with the browser CI actually launches. Also compare with installed Chrome or Chromium when useful; do not assume the bundled Electron’s embedded Chromium behaves like current Chrome.
Capture a reference screenshot without changing the Cypress diagnosis
For a page that is publicly reachable, an external screenshot can help you inspect its rendered appearance at a URL and compare it with a Cypress artifact. It does not run Cypress, access a local-only test server, or repair a w2ui overlay. Keep Cypress screenshots and video as the evidence for the actual test environment.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. A GET request returns an image or PDF for a URL that the service can reach; use a publicly accessible page, not a localhost URL or a page that exists only inside the Cypress runner. The example below captures a reference image, not a Cypress test artifact. See the ScreenshotNeo documentation for API parameters.
curl -G "https://api.screenshotneo.com/v1/shot"
-d access_key=YOUR_API_KEY
--data-urlencode url=https://example.com
-o shot.webp
ScreenshotNeo removes cookie/consent banners, newsletter popups, and chat widgets before capture; those steps can be turned off. Bot checks, blank pages, and failed loads are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. These are ScreenshotNeo plan terms, not Cypress pricing.
To capture the specific page, replace https://example.com with its reachable URL. An API key is required. You can also call the same endpoint from Python or Node.js:
# Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
// Node.js
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://example.com'
})
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`)
Sign up for ScreenshotNeo for 1,000 free screenshots a month with no card.
Keep the diagnosis reproducible
When a fix appears to work, preserve the relevant evidence: browser and version, headless or headed mode, application viewport, browser screen dimensions, the overlay selector, and a screenshot or video. This makes it possible to tell whether a later failure is a changed selector, a layout regression, an accidental dismissal, or a different browser environment—without treating all headless failures as the same problem.
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.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →

