skip to content

Windows and Tabs

Window handles are unordered opaque strings, so finding the tab a click just opened is a set difference rather than an index. Also covers opening one deliberately and closing one safely.

on this pageshow

explore

questions

3

After driver.close() on a tab, a Selenium suite throws NoSuchWindowException on every later command. Why, and what is the fix?

level: seniorimportance: must knowfreq 57%

answer

  1. Focus does not move on its own
  2. The driver still addresses something gone
  3. Every later command fails identically
  4. no such window, not no such element
  5. Pair the close with a switch back

basics

~20 s

Closing a context never moves the driver's focus, so it still addresses a window that no longer exists and every command fails with no such window. Switch explicitly to a surviving handle immediately after the close.

solid answer

~40 s

`close()` disposes of the focused browsing context and nothing else: the session keeps pointing at the context it just destroyed, so the next command raises `NoSuchWindowException` (`no such window` on the wire). It is deterministic, not flaky, and no wait will help. The fix is to pair every `close()` with `switchTo().window(handle)` using a handle captured before you left the original context — ideally inside one small helper so the two calls cannot drift apart. Note the related failure: closing the *last* remaining context ends the session per the W3C specification, and subsequent commands then fail with `NoSuchSessionException` instead. Use `quit()` when you mean to end the session, and `close()` only when other contexts remain.

go deeper

for a junior

Remember that close() shuts only the focused window and quit() ends the whole session. After any close, the driver needs an explicit switch to a handle that is still open before the next command.

for a middle

Explain the mechanics: the session still references the disposed context, so the remote end answers no such window. Distinguish that error from a missing element and from an ended session.

for a senior

Diagnose it from the error alone and name the last context-changing call, then fix it structurally by pairing close and switch in one helper. Cover the case where the application closes its own tab.

for a principal

Own the convention that stops the class of bug: who is allowed to close a context, what a shared cleanup helper must guarantee about focus afterwards, and how failures name the context so triage does not start from scratch.

## What `close()` leaves behind `driver.close()` issues the W3C **Close Window** command against the context the driver is currently focused on. The browser disposes of that window or tab, and its handle vanishes from `driver.getWindowHandles()`. What the command does **not** do is re-point the driver. The session still holds a reference to the context you just destroyed, so the next command — `getTitle()`, `findElement(...)`, anything at all — is addressed to something that no longer exists and comes back as the W3C error **`no such window`**, surfaced by the Java binding as `org.openqa.selenium.NoSuchWindowException`. That is the whole bug. It is not flakiness, not a timing problem, and no wait will fix it: the failure is deterministic and it will happen on every single run. ## The two errors that look alike | Symptom | Error | Cause | |---|---|---| | Every command after a `close()` fails | `NoSuchWindowException` (`no such window`) | focus still points at a disposed context | | Every command fails after closing the **last** context | `NoSuchSessionException` (`invalid session id`) | closing the final window ends the session itself | | One `findElement` fails, others fine | `NoSuchElementException` | the context is alive; the locator matched nothing | The middle row is the senior distinction. Per the W3C specification, when Close Window leaves no open top-level browsing contexts the remote end closes the session, so a suite that "just uses `close()` instead of `quit()`" does not get a reusable driver — it gets a dead one, and the next test's error names the session rather than the window. ## `close()` versus `quit()` - **`close()`** disposes of exactly one browsing context: the focused one. Other tabs keep running, the session survives, and *you* owe it an explicit `switchTo().window(...)`. - **`quit()`** ends the session: every window belonging to it goes, and the driver object is finished. Nothing to switch to afterwards, because there is no session left to switch in. - **They are not interchangeable.** `close()` on the last window happens to end the session as a side effect, which is why the confusion survives — but relying on that leaves the intent unreadable and the failure mode different from the one you meant. ## Diagnosing it on the permit portal A regression suite for the municipal permit portal opens the printable receipt for an approved building-permit application in a second tab, asserts the permit number, closes the receipt, and then asserts a "Receipt printed" badge on the application page. The badge assertion fails with `NoSuchWindowException` every run. The reasoning that finds it: 1. The error names the *window*, not an element — so the locator is innocent; the context is gone. 2. The last context-changing call before the failure was `driver.close()` on the receipt tab. 3. `close()` does not move focus, so the driver is still addressing the receipt tab. 4. The fix is one line: switch back to the handle captured before the receipt tab was opened. ## The safe shape ```java String applicationTab = driver.getWindowHandle(); String receiptTab = openReceiptTab(driver); driver.switchTo().window(receiptTab); assertEquals("BP-2026-0412", driver.findElement(By.id("permit-number")).getText()); driver.close(); driver.switchTo().window(applicationTab); ``` The `close()` and the `switchTo().window(...)` belong together as one two-line idiom; splitting them across helpers is how the bug gets in. Wrapping both in a small `closeAndReturnTo(driver, handle)` method makes the pairing impossible to forget. ## Other ways to land on a dead context - **The application closes the tab itself.** A portal that closes its own receipt window after printing strands the driver exactly the same way, with no `close()` call anywhere in your code to point at. - **A helper closed it.** A shared "clean up stray tabs" utility that closes everything except one handle must also switch to the survivor, or it hands every caller a broken driver. - **A saved handle went stale.** Handles are not reissued: once a context is closed, passing its old handle to `switchTo().window(...)` raises `NoSuchWindowException` rather than reopening anything. - **Focus was never established.** Reading a handle is not switching to it; `getWindowHandles()` tells you what exists, and only `switchTo().window(...)` changes where commands go. The rule that covers all four: **the driver's focus only ever moves because you moved it.** Neither closing a context, nor the browser's own visual focus, nor a page opening a tab will do it for you.

  • How does the failure differ when the closed tab was the last open context?
    Closing the final top-level context ends the session per the W3C specification, so later commands report `invalid session id` and the Java binding raises `NoSuchSessionException` rather than `NoSuchWindowException`. The error names the session, not the window, which is the clue that nothing is left to switch to and a fresh driver is required.
  • The application itself closes a tab your test is focused on. What changes about the fix?
    Nothing about the mechanism, only about where the switch goes. There is no `close()` of yours to pair with, so the step that triggers the self-close must be followed by an explicit switch to a handle read from `getWindowHandles()` before the action. The saved handle for the disappearing context is now dead and must not be reused.
  • Why is retrying the failing command a bad response to NoSuchWindowException here?
    The context is destroyed, so every attempt addresses the same missing target and fails identically. A retry loop converts a one-line diagnosis into a slow, confusing timeout and hides the real defect, which is a missing switch. The condition is deterministic and needs a fix, not a second attempt.

saying these in an interview costs you the question

  • Expects close() to move focus to a remaining window
  • Uses close() where quit() is meant to end the session
  • Reads NoSuchWindowException as a missing element on the page
  • Reuses a saved handle after that context was closed
  • Adds a wait or a retry to a deterministic focus error
open as a page

In Selenium, a portal link opens a second tab. How do you obtain that new tab's window handle?

level: middleimportance: should knowfreq 64%

basics

~20 s

Snapshot getWindowHandles() before the click, take the same set afterwards, and subtract the first from the second. The single handle left over is the new tab. Handles are opaque and unordered, so indexing into the set is unreliable.

open as a page

In Selenium 4, what does driver.switchTo().newWindow(WindowType.TAB) do, and how does WindowType.WINDOW differ?

level: juniorimportance: nice to knowfreq 28%

basics

~20 s

Selenium 4 creates a fresh, blank browsing context and switches the driver to it in one call, so no handle diffing is needed. WindowType.TAB asks for a tab in the current window; WindowType.WINDOW asks for a separate browser window.

open as a page