Skip to content

fix(wdio): support v9 wdio switchFrame and switchWindow#1302

Merged
scottmries merged 30 commits into
developfrom
v9-wdio
Apr 9, 2026
Merged

fix(wdio): support v9 wdio switchFrame and switchWindow#1302
scottmries merged 30 commits into
developfrom
v9-wdio

Conversation

@straker
Copy link
Copy Markdown
Contributor

@straker straker commented Mar 20, 2026

  • Replace client as any with 'switchFrame' in client / 'switchToWindow' in client in clientSwitchFrame and clientSwitchWindow
  • Use getWindowHandle() instead of getWindowHandles()[0] in runPartialRecursive
  • Use dynamic ephemeral port in esmTest.mjs via getFreePort() helper
  • Add stdio: 'inherit' to ChromeDriver spawn call in esmTest.mjs
  • Add unit tests for clientSwitchFrame (v9 BiDi and v8 classic paths)
  • Update WDIO typing (WdioBrowser) to model v5–v9 API differences
  • Remove all remaining as any casts: replace with unknown as Record<string, unknown> for proxy-safe typeof checks, remove unnecessary cast on import('node:module'), use 'switchFrame' in this.client narrowing in index.ts

Fixes: #1164

@straker straker requested a review from a team as a code owner March 20, 2026 15:30
@straker straker requested a review from scottmries March 20, 2026 15:30
In WDIO v9 WebDriver Classic (non-BiDi), switchFrame(null) calls the
WebDriver "Switch To Frame" command with id=null which switches to the
top-level frame rather than the immediate parent. This broke nested
frame injection and runPartialRecursive traversal, causing timeouts
and wrong selector paths in the results.

Fix clientSwitchParentFrame to prefer switchToParentFrame() (available
in both v8 and v9 via @wdio/protocols) which correctly targets the
immediate parent frame.

Also skip the devtools protocol test suite on WDIO v9+ since
automationProtocol: 'devtools' was removed in v9.
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 2, 2026

CLA assistant check
All committers have signed the CLA.

scottmries and others added 5 commits April 2, 2026 15:49
Replace clientSwitchParentFrame with getWindowHandles+switchToWindow+re-traverse
to avoid the BiDi race condition where switchToParentFrame synchronously resets
#currentContext before the async parent lookup resolves, causing subsequent BiDi
calls to run in the wrong browsing context.

Also fix clientSwitchWindow to prefer switchToWindow (handle-based) over
switchWindow (pattern match by title/URL/name in v8).
Two fixes for WDIO v9 WebDriver BiDi mode:

1. inject() re-entry: capture the BiDi context ID when entering each
   frame (returned by switchFrame), then use that string ID for re-entry
   after deep injection instead of the original element reference.

   In BiDi mode, Chrome may assign new document IDs to intermediate frame
   contexts after switchFrame(null) from deep nesting. An element's
   SharedId encodes the document ID at query time; if that ID has since
   changed, Chrome rejects it with "no such node - SharedId belongs to
   different document". Passing a context ID string instead causes WDIO to
   re-query fresh element references via browsingContextLocateNodes,
   bypassing the stale-ID issue.

2. assertFrameReady(): add document.URL !== 'about:blank' to the
   readiness check.

   In BiDi mode, script.callFunction can execute in cross-origin frames
   (BiDi bypasses same-origin restrictions). A lazy-loaded cross-origin
   iframe that hasn't fetched its content yet has readyState 'complete'
   on its blank document, so the old check passed and the frame was never
   reported as frame-tested incomplete. Classic WebDriver throws on
   cross-origin execution, which triggered the correct frame-tested path.
   Checking for about:blank replicates that behavior.
automationProtocol: 'devtools' was removed in WDIO v9. Switch the ESM
export integration test to use webdriver protocol with ChromeDriver,
matching the approach used in the main test suite.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds WebdriverIO v9 compatibility for frame/window switching by introducing wrapper helpers and updating injection/navigation logic to work across WDIO v5–v9 (including BiDi-specific behavior), while updating tests and dev dependencies accordingly.

Changes:

  • Introduce clientSwitchFrame / clientSwitchWindow helpers and refactor frame/window navigation to use them.
  • Update WDIO typing (WdioBrowser) to better model v5–v9 API differences and reduce casting.
  • Adjust test setup to account for WDIO v9 devtools removal and update local ESM integration test to run against a spawned ChromeDriver.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/webdriverio/src/utils.ts Adds frame/window switch wrappers and updates client validation + script execution calls.
packages/webdriverio/src/index.ts Refactors frame injection and partial recursion to use wrappers; adds BiDi context-id re-entry logic.
packages/webdriverio/src/types.ts Reworks WDIO browser/element typing to cover v5–v9 API differences.
packages/webdriverio/test/axe-webdriverio.spec.ts Skips devtools protocol tests on WDIO v9; adjusts typings and adds validation coverage for v9 API.
packages/webdriverio/test/esmTest.mjs Spawns ChromeDriver and runs ESM integration test via webdriver protocol.
packages/webdriverio/package.json Bumps devDependency webdriverio to ^9.22.0.
package-lock.json Updates lockfile to reflect WDIO v9 dependency graph.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/webdriverio/src/index.ts Outdated
Comment thread packages/webdriverio/test/esmTest.mjs Outdated
Comment thread packages/webdriverio/test/esmTest.mjs Outdated
Comment thread packages/webdriverio/src/index.ts

This comment was marked as duplicate.

5 similar comments

This comment was marked as duplicate.

This comment was marked as duplicate.

This comment was marked as duplicate.

This comment was marked as duplicate.

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 6, 2026

@scottmries Unfortunately I hit an unexpected error while processing your comment. I've automatically reported this to GitHub.

You can ask me to try again later by mentioning me in a new comment.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 0e7e324d-7096-47a8-a254-a42d3fa25f14

Sorry for the inconvenience!

Comment thread packages/webdriverio/src/utils.ts
Copilot AI requested a review from Garbee April 7, 2026 13:21
Copy link
Copy Markdown
Member

@Garbee Garbee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Copy link
Copy Markdown
Contributor Author

@straker straker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't request changes on my own pr

Comment thread packages/webdriverio/test/axe-webdriverio.spec.ts
Comment thread packages/webdriverio/test/esmTest.mjs Outdated
@straker
Copy link
Copy Markdown
Contributor Author

straker commented Apr 7, 2026

There's also a few places where the code uses switch(to)Frame in client but @wdio/globals uses proxies and I know that returned false. Are we certain we can use in lookups in those cases?

Garbee
Garbee previously requested changes Apr 7, 2026
Copy link
Copy Markdown
Member

@Garbee Garbee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address feedback from @straker

@Garbee
Copy link
Copy Markdown
Member

Garbee commented Apr 7, 2026

There's also a few places where the code uses switch(to)Frame in client but @wdio/globals uses proxies and I know that returned false. Are we certain we can use in lookups in those cases?

The tests passed. So, are we saying the coverage isn't where we need it to be?

- Add unit tests for clientSwitchWindow
- Remove browser-driver-manager dependency from esmTest; use chromedriver package directly
Replace `as any` casts in clientSwitchFrame and clientSwitchWindow with
`as unknown as Record<string, unknown>` to avoid unsafe any usage.
@straker
Copy link
Copy Markdown
Contributor Author

straker commented Apr 7, 2026

That's what I'm curious about. I had added the proxy comment because I ran into it as a problem, so it's interesting that we can still use it in other parts of the code.

…when available

Fall back to the chromedriver npm package when CHROMEDRIVER_TEST_PATH is
not set, so the test works without browser-driver-manager installed.
@scottmries
Copy link
Copy Markdown
Contributor

@straker I'd assumed it was working since tests were passing, but I changed it to check for functions just in case. Tests still passing, so I think we're good.

Copy link
Copy Markdown
Contributor Author

@straker straker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (I can't approve my own pr)

Copy link
Copy Markdown
Member

@Garbee Garbee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. We should set up a test matrix to ensure we still work on 8 and 9 going forward with any changes. But that can be done separately I feel.

@scottmries scottmries enabled auto-merge (squash) April 9, 2026 18:34
@scottmries scottmries merged commit 4689273 into develop Apr 9, 2026
39 checks passed
@scottmries scottmries deleted the v9-wdio branch April 9, 2026 18:52
@github-actions github-actions Bot mentioned this pull request Apr 14, 2026
straker added a commit that referenced this pull request Apr 14, 2026
##
[4.11.2](v4.11.1...v4.11.2)
(2026-04-14)


### Bug Fixes

* Update axe-core to v4.11.3
([#1306](#1306))
([71c4179](71c4179))
* **wdio:** support v9 wdio switchFrame and switchWindow
([#1302](#1302))
([4689273](4689273)),
closes [#1164](#1164)

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Steven Lambert <2433219+straker@users.noreply.github.com>
Co-authored-by: Jonathan Garbee <jonathan.garbee@deque.com>
Co-authored-by: JustasM <59362982+JustasMonkev@users.noreply.github.com>
Co-authored-by: attest-team-ci <48030122+attest-team-ci@users.noreply.github.com>
Co-authored-by: Zidious <41127686+Zidious@users.noreply.github.com>
Co-authored-by: API Team CI User <aciattestteamci@deque.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Garbee <868301+Garbee@users.noreply.github.com>
Co-authored-by: Scott Ries <scottmries@gmail.com>
Co-authored-by: Scott Ries <scott.ries@deque.com>
Co-authored-by: scottmries <1245800+scottmries@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WDIO v9 deprecates switchToFrame and switchToWindow

6 participants