Skip to content

fix: allow newWindow when the active window was already closed#17766

Open
mvanhorn wants to merge 1 commit into
SeleniumHQ:trunkfrom
mvanhorn:fix/17754-newwindow-after-close
Open

fix: allow newWindow when the active window was already closed#17766
mvanhorn wants to merge 1 commit into
SeleniumHQ:trunkfrom
mvanhorn:fix/17754-newwindow-after-close

Conversation

@mvanhorn

Copy link
Copy Markdown

🔗 Related Issues

Fixes #17754

💥 What does this PR do?

RemoteWebDriver$RemoteTargetLocator.newWindow(WindowType) no longer throws NoSuchWindowException: target window already closed when the caller has already closed the currently-focused window. Previously newWindow began by calling getWindowHandle() to remember the current window (so it could switch back on failure), which threw in the legal W3C state where the driver is not focused on any open window. The reporter's repro — newWindow(WINDOW)switchTo().close()newWindow(WINDOW) — now succeeds as long as other windows remain open.

🔧 Implementation Notes

Removed the leading getWindowHandle() call and the try-catch that restored that stored handle. Switching to a just-created window handle is expected to succeed; in the rare case it fails, the driver is still on its previous handle, so there is nothing to restore — the stored handle only existed to serve a restore path that was never actually reachable in a useful way, and it was the thing that threw when no window was focused. The new-window creation and switch remain; only the redundant pre-fetch and restore wrapper are gone.

🤖 AI assistance

  • No substantial AI assistance used
  • AI assisted (complete below)
    • Tool(s): AI coding assistant
    • What was generated: the code change and this description
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

The reporter noted the try-catch and the handle it depended on were unnecessary; this change reflects that. Added a regression test covering the close-active-window-then-newWindow sequence.

🔄 Types of changes

  • Bug fix (backwards compatible)

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@selenium-ci selenium-ci added the C-java Java Bindings label Jul 11, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Fix RemoteWebDriver.newWindow when the currently-focused window is already closed

🐞 Bug fix 🧪 Tests 🕐 10-20 Minutes

Grey Divider

AI Description

• Avoid pre-fetching the current window handle in newWindow, preventing NoSuchWindowException.
• Always switch to the newly-created window handle returned by the remote end.
• Add regression coverage for close()-then-newWindow() sequences while other windows exist.
Diagram

graph TD
  T(["WindowSwitchingTest"]) --> L["RemoteTargetLocator.newWindow()"] --> C["DriverCommand: SWITCH_TO_NEW_WINDOW"] --> R{{"Remote end / browser"}} --> H["New window handle"]
  H --> L
  subgraph Legend
    direction LR
    _t(["Test"]) ~~~ _m["Client module"] ~~~ _e{{"External system"}}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Catch `NoSuchWindowException` around `getWindowHandle()` and proceed
  • ➕ Preserves the historical 'restore original window' behavior when available
  • ➕ Minimal behavioral delta beyond the exceptional case
  • ➖ Still relies on a potentially-invalid 'original handle' concept when focus is undefined
  • ➖ Adds complexity and branching for a restore path that is rarely actionable
2. Use `getWindowHandles()` to pick a fallback original handle
  • ➕ Avoids failing when the focused window is closed by selecting an existing handle
  • ➕ Keeps a deterministic restore target
  • ➖ May restore to an arbitrary window, potentially surprising users
  • ➖ Extra remote calls and more edge cases (ordering, races, window disappearance)

Recommendation: Proceed with the PR’s approach: removing the pre-fetch/restore wrapper eliminates the primary failure mode (focused window already closed) and keeps newWindow aligned with the W3C-legal state where no current window is focused. The added regression test demonstrates the intended behavior and guards against reintroducing the getWindowHandle() dependency.

Files changed (2) +39 / -12

Bug fix (1) +5 / -11
RemoteWebDriver.javaMake 'newWindow' independent of the current (possibly closed) window handle +5/-11

Make 'newWindow' independent of the current (possibly closed) window handle

• Removes the initial 'getWindowHandle()' call and the try/catch that attempted to switch back to that handle on failure. 'newWindow' now directly creates a new window via 'SWITCH_TO_NEW_WINDOW', switches to the returned handle, and returns the driver instance.

java/src/org/openqa/selenium/remote/RemoteWebDriver.java

Tests (1) +34 / -1
WindowSwitchingTest.javaAdd regression test for 'close()'-then-'newWindow()' and refactor existing coverage +34/-1

Add regression test for 'close()'-then-'newWindow()' and refactor existing coverage

• Introduces a helper to share logic between tab and window creation tests, and adds a regression test verifying 'newWindow(WINDOW)' succeeds after closing the currently-focused window when another window remains open. Also asserts the new window is usable and switching back to the main window works.

java/test/org/openqa/selenium/WindowSwitchingTest.java

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 18 rules

Grey Divider


Action required

1. Outdated newWindow unit test 🐞 Bug ≡ Correctness
Description
RemoteTargetLocator.newWindow no longer calls GET_CURRENT_WINDOW_HANDLE, but
RemoteWebDriverUnitTest#canHandleSwitchToNewWindowCommand still asserts that command sequence via
strict in-order verification, so this test will fail. Update the unit test expectations to match the
new behavior.
Code

java/src/org/openqa/selenium/remote/RemoteWebDriver.java[R1319-1323]

+      Response response = execute(DriverCommand.SWITCH_TO_NEW_WINDOW(typeHint));
+      String newWindowHandle =
+          ((Map<String, Object>) response.getValue()).get("handle").toString();
+      switchTo().window(newWindowHandle);
+      return RemoteWebDriver.this;
Evidence
The PR removed the initial getWindowHandle() call from newWindow, but the existing unit test
still verifies that GET_CURRENT_WINDOW_HANDLE is sent first; verifyCommands checks commands
strictly in order, so the mismatch will fail.

java/test/org/openqa/selenium/remote/RemoteWebDriverUnitTest.java[287-299]
java/test/org/openqa/selenium/remote/WebDriverFixture.java[85-107]
java/src/org/openqa/selenium/remote/RemoteWebDriver.java[1317-1324]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RemoteWebDriverUnitTest#canHandleSwitchToNewWindowCommand` still expects `GET_CURRENT_WINDOW_HANDLE` to be issued before `SWITCH_TO_NEW_WINDOW`, but the PR removed that call from `RemoteTargetLocator.newWindow`, causing the unit test to fail.

### Issue Context
The test uses `WebDriverFixture.verifyCommands`, which enforces a strict in-order match of the executed commands.

### Fix Focus Areas
- java/test/org/openqa/selenium/remote/RemoteWebDriverUnitTest.java[287-299]

### What to change
- In `canHandleSwitchToNewWindowCommand`, remove the expectation for `DriverCommand.GET_CURRENT_WINDOW_HANDLE`.
- The expected sequence should now be:
 1) `DriverCommand.SWITCH_TO_NEW_WINDOW` with `{type: "tab"}`
 2) `DriverCommand.SWITCH_TO_WINDOW` with `{handle: "new window"}`

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. No focus restore on error 🐞 Bug ☼ Reliability
Description
Removing the try/catch means newWindow no longer attempts to restore the previously focused window
when a WebDriverException occurs after issuing the new-window command, potentially leaving the
session focused on an unexpected window even though the call fails. This is an exception-path
behavior regression versus the prior implementation and differs from other switch logic that
restores focus after fallback attempts.
Code

java/src/org/openqa/selenium/remote/RemoteWebDriver.java[R1319-1323]

+      Response response = execute(DriverCommand.SWITCH_TO_NEW_WINDOW(typeHint));
+      String newWindowHandle =
+          ((Map<String, Object>) response.getValue()).get("handle").toString();
+      switchTo().window(newWindowHandle);
+      return RemoteWebDriver.this;
Evidence
newWindow is documented to create and switch focus; with no exception recovery in the new
implementation, any failure after issuing the command can leave focus changed. Other
window-switching code in the same class explicitly restores the original handle after fallback
logic, illustrating the intended stability pattern on failures.

java/src/org/openqa/selenium/WebDriver.java[444-456]
java/src/org/openqa/selenium/remote/RemoteWebDriver.java[1294-1314]
java/src/org/openqa/selenium/remote/RemoteWebDriver.java[1317-1324]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RemoteTargetLocator.newWindow` no longer performs any recovery on `WebDriverException`. If the remote end has already switched focus as part of the new-window command, and a subsequent step throws, the session may be left focused on an unexpected window.

### Issue Context
The original pre-fetch of `getWindowHandle()` was removed to support the legal state where no window is focused. You can preserve that fix while still supporting recovery by capturing the original handle only when available (and skipping recovery when it is not).

### Fix Focus Areas
- java/src/org/openqa/selenium/remote/RemoteWebDriver.java[1317-1324]

### What to change
- Reintroduce a guarded recovery pattern:
 - Attempt to capture `original` using `getWindowHandle()` inside a `try/catch (NoSuchWindowException)` (or broader) and set `original = null` if unavailable.
 - Wrap the new-window flow in `try/catch (WebDriverException ex)`.
 - In the catch block, if `original != null`, attempt `switchTo().window(original)` in a best-effort way (swallow/ignore failures during restore), then rethrow `ex`.
- This keeps the PR’s main fix (don’t fail when no window is focused) while preserving prior exception-path stability when an original handle exists.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +1319 to +1323
Response response = execute(DriverCommand.SWITCH_TO_NEW_WINDOW(typeHint));
String newWindowHandle =
((Map<String, Object>) response.getValue()).get("handle").toString();
switchTo().window(newWindowHandle);
return RemoteWebDriver.this;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

1. Outdated newwindow unit test 🐞 Bug ≡ Correctness

RemoteTargetLocator.newWindow no longer calls GET_CURRENT_WINDOW_HANDLE, but
RemoteWebDriverUnitTest#canHandleSwitchToNewWindowCommand still asserts that command sequence via
strict in-order verification, so this test will fail. Update the unit test expectations to match the
new behavior.
Agent Prompt
### Issue description
`RemoteWebDriverUnitTest#canHandleSwitchToNewWindowCommand` still expects `GET_CURRENT_WINDOW_HANDLE` to be issued before `SWITCH_TO_NEW_WINDOW`, but the PR removed that call from `RemoteTargetLocator.newWindow`, causing the unit test to fail.

### Issue Context
The test uses `WebDriverFixture.verifyCommands`, which enforces a strict in-order match of the executed commands.

### Fix Focus Areas
- java/test/org/openqa/selenium/remote/RemoteWebDriverUnitTest.java[287-299]

### What to change
- In `canHandleSwitchToNewWindowCommand`, remove the expectation for `DriverCommand.GET_CURRENT_WINDOW_HANDLE`.
- The expected sequence should now be:
  1) `DriverCommand.SWITCH_TO_NEW_WINDOW` with `{type: "tab"}`
  2) `DriverCommand.SWITCH_TO_WINDOW` with `{handle: "new window"}`

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +1319 to +1323
Response response = execute(DriverCommand.SWITCH_TO_NEW_WINDOW(typeHint));
String newWindowHandle =
((Map<String, Object>) response.getValue()).get("handle").toString();
switchTo().window(newWindowHandle);
return RemoteWebDriver.this;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remediation recommended

2. No focus restore on error 🐞 Bug ☼ Reliability

Removing the try/catch means newWindow no longer attempts to restore the previously focused window
when a WebDriverException occurs after issuing the new-window command, potentially leaving the
session focused on an unexpected window even though the call fails. This is an exception-path
behavior regression versus the prior implementation and differs from other switch logic that
restores focus after fallback attempts.
Agent Prompt
### Issue description
`RemoteTargetLocator.newWindow` no longer performs any recovery on `WebDriverException`. If the remote end has already switched focus as part of the new-window command, and a subsequent step throws, the session may be left focused on an unexpected window.

### Issue Context
The original pre-fetch of `getWindowHandle()` was removed to support the legal state where no window is focused. You can preserve that fix while still supporting recovery by capturing the original handle only when available (and skipping recovery when it is not).

### Fix Focus Areas
- java/src/org/openqa/selenium/remote/RemoteWebDriver.java[1317-1324]

### What to change
- Reintroduce a guarded recovery pattern:
  - Attempt to capture `original` using `getWindowHandle()` inside a `try/catch (NoSuchWindowException)` (or broader) and set `original = null` if unavailable.
  - Wrap the new-window flow in `try/catch (WebDriverException ex)`.
  - In the catch block, if `original != null`, attempt `switchTo().window(original)` in a best-effort way (swallow/ignore failures during restore), then rethrow `ex`.
- This keeps the PR’s main fix (don’t fail when no window is focused) while preserving prior exception-path stability when an original handle exists.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-java Java Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[🐛 Bug]: can not switch to new window after closing the current window

3 participants