skip to content

In Selenium, what is the difference between calling driver.close() and driver.quit()?

level: juniorimportance: should knowfreq 82%

answer

  1. Two calls, two different scopes
  2. One targets a window, one a session
  3. Close Window versus Delete Session
  4. Only one of them stops chromedriver
  5. Leftover driver process means the wrong call

basics

~20 s

close() shuts only the browser window the driver is focused on and leaves the session running. quit() ends the whole session: every window it owns closes, the browser exits, and the driver process is stopped.

solid answer

~40 s

`close()` maps to the W3C Close Window command and shuts only the top-level browsing context the driver is focused on; the session stays alive and you can switch to another handle. `quit()` maps to Delete Session, so the remote end closes every window the session owns, terminates the browser, and discards the temporary profile directory it generated; the Java client then stops the local driver executable it launched. If `close()` happens to shut the last remaining window the session ends too, but that driver executable is left listening on its port, so a suite that only calls `close()` slowly accumulates driver processes. Rule of thumb for a donation-checkout test that opens the receipt in a second tab: `close()` the tab, `quit()` the run.

code

java · 19 lines
java
WebDriver driver = new ChromeDriver();
try {
    driver.get("https://give.example.org/donate");
    driver.findElement(By.id("amount")).sendKeys("25");
    driver.findElement(By.id("donate-now")).click();

    String checkout = driver.getWindowHandle();
    for (String handle : driver.getWindowHandles()) {
        if (!handle.equals(checkout)) {
            driver.switchTo().window(handle);
        }
    }
    System.out.println(driver.findElement(By.id("receipt-id")).getText());

    driver.close();
    driver.switchTo().window(checkout);
} finally {
    driver.quit();
}

go deeper

for a junior

Be ready to give the difference in one sentence and to say which call belongs in teardown. Interviewers open with this because the two names sound interchangeable and picking the wrong one quietly leaks browsers.

for a middle

Explain the commands underneath the methods: Close Window targets one top-level browsing context, Delete Session ends the whole session. Say what is still running after close() shuts the last window.

for a senior

Show that you have cleaned up after a suite that only called close: stray driver executables holding ports, temporary profile directories filling an agent's disk, and how you proved the leak was gone.

for a principal

Treat it as a resource rule rather than a style preference. Every session ends with quit, and on a shared runner you can demonstrate that no browser or driver process outlives a run.

## Two calls, two different scopes A **WebDriver session** is the entire conversation between your test and one browser instance. The session owns every top-level browsing context - window or tab - that the instance opened, the cookies and storage inside them, the profile directory the browser was started with, and, when the browser was started locally, the **driver executable** (`chromedriver`, `geckodriver`, `msedgedriver`) sitting between your client and the browser. `close()` acts on a single window. `quit()` acts on the whole session. Every other difference follows from that one. | | `driver.close()` | `driver.quit()` | |---|---|---| | W3C command | Close Window, `DELETE /session/{session id}/window` | Delete Session, `DELETE /session/{session id}` | | Scope | the focused top-level browsing context | the entire session | | Response | the window handles that remain | nothing | | Session afterwards | alive, unless that was the last window | ended; the session id is dead | | Browser process | survives while another window is open | terminated by the remote end | | Driver executable | keeps listening on its port | stopped by the client that launched it | | Temporary profile directory | left in place | deleted with the session | | Grid slot | still held | released back to the node | ## What close() actually does - It sends the **Close Window** command, which closes the top-level browsing context currently in focus - the one `getWindowHandle()` returns - and answers with the handles that are still open. - It does not move focus to a survivor for you. The driver still points at a window that no longer exists, so the next command fails until the test switches to one of the returned handles. - If the window it closed was the **last** one the session owned, the WebDriver specification also ends the session, so the browser exits. That is the case which makes `close()` look like sufficient cleanup: the browser really does vanish from the screen. - What does not vanish is the driver executable. `chromedriver` is a small HTTP server; it keeps running and keeps holding its port whether or not it currently hosts a session. ## What quit() actually does `quit()` sends **Delete Session**, and that one command does four things at the remote end: 1. every top-level browsing context the session owns is closed; 2. the browser process the driver started is terminated; 3. the session state is discarded, including the **temporary profile directory** the driver generated for it - ChromeDriver starts Chrome with a generated `--user-data-dir` under the system temp directory whenever you have not supplied a profile of your own; 4. on a Grid, the node that hosted the session marks its slot free again. The Java client then does one more thing on your side of the wire: once the quit command completes it stops the driver service process it launched for a local browser. No other call in the API does that. `quit()` is also safe to call twice - the client drops its session id as part of quitting, so a second call returns without sending anything. ## The donation-checkout flow where the difference bites Take a test that donates to a charity and then verifies the receipt: 1. It fills in the gift amount on the donation form and submits it. 2. The site opens the printable receipt in a **second tab**, so the session now owns two windows. 3. The test switches to the receipt handle and reads the receipt id. 4. It calls `close()` on the receipt tab. That is the right call - it wants one tab gone, not the session. 5. It switches back to the checkout handle and finishes its checks. 6. Teardown calls `quit()`. Also the right call - now the session, both processes and the profile directory go away. ```java driver.close(); // the receipt tab only driver.quit(); // the session, the browser and chromedriver ``` Swap those two responsibilities and you get one of two bugs. `quit()` at step 4 kills the checkout window you were about to return to. `close()` at step 6 leaves a live session behind with the checkout window still open. ## What leaks when quit() never runs - A **browser process**, holding its share of the machine's memory - a real browser is the most expensive thing in the run. - A **driver executable**, still bound to its port; enough of them and new sessions start failing to find a free one. - A **temporary profile directory** under the system temp directory that nothing else will clean up. On a long-lived agent these pile up until the disk fills. - On a Grid, a **held slot**: the node still believes the session is in use and will not hand that slot to the next test until its own session timeout expires. ## Rules that keep the two straight - Reach for `close()` only when you deliberately want one window gone and the session to continue. - End every session with `quit()`, including sessions whose windows you already closed by hand. - Never read "the browser disappeared" as proof the machine is clean - check for the driver process too.

  • If close() shuts the last remaining window, is calling quit() afterwards still worth it?
    Yes. The remote end ends the session when the last window goes, but the `chromedriver` or `geckodriver` executable your client launched keeps listening on its port, and stopping that process is exactly what `quit()` adds. The client also clears its session id while quitting, so the extra call is harmless.
  • What happens to the temporary profile directory when a session is deleted?
    The driver removes it. When you do not supply a profile, ChromeDriver starts Chrome with a generated user-data directory under the system temp directory and geckodriver builds a throwaway Firefox profile; deleting the session deletes them. Kill the driver process instead and the directory simply stays on disk.

close() is shutting one till in the charity shop; quit() is locking the shop, turning off the lights and sending the staff home.

saying these in an interview costs you the question

  • Claims close() and quit() are interchangeable names for the same call
  • Says quit() closes only the last window that was opened
  • Believes close() also stops the chromedriver process
  • Thinks closing every window by hand is complete cleanup
  • Assumes a killed test process always takes the browser with it