In Selenium, what profile does a Chrome session use by default, and what changes when ChromeOptions adds --user-data-dir?
answer
- Stateless by default, and deliberately so
- The driver makes a temporary directory
- The switch replaces it with yours
- One process may hold the directory
- State the test never created is unreproducible
basics
~20 sBy default the driver creates a throwaway user-data directory per session, so every run starts with no cookies, extensions or history. Adding --user-data-dir points Chrome at a directory you keep, carrying state in and writing it back out.
solid answer
~40 sWith no profile options set, the driver creates a fresh temporary user-data directory for each Chrome session, which is why a session starts stateless: no cookies, no extensions, no history, nothing carried in from the last run. Adding `addArguments("--user-data-dir=<path>")` replaces that with a directory you name, and `--profile-directory=<name>` picks one profile inside it. The trade is real state you did not create: the profile drifts as it ages, a failure that depends on it cannot be reproduced from the repository, and tests write back into it. Chrome also locks the directory it opens, so a path a running browser or another session already holds fails the new session with a session-not-created error naming the user data directory as already in use. Firefox's equivalent is `setProfile(new FirefoxProfile(dir))`, which treats the directory as a template.
code
java · 22 linesimport java.nio.file.Files;
import java.nio.file.Path;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class RecipeCollectionProfileTest {
public static void main(String[] args) throws Exception {
Path profileDir = Files.createTempDirectory("recipe-suite-profile");
ChromeOptions options = new ChromeOptions();
options.addArguments("--user-data-dir=" + profileDir.toAbsolutePath());
WebDriver driver = new ChromeDriver(options);
try {
driver.get("https://recipes.example.com/collections/weeknight-dinners");
System.out.println(driver.getTitle());
} finally {
driver.quit();
}
}
}go deeper
Know that a Selenium-started browser does not use your everyday profile: the driver makes a temporary one, so cookies and extensions you have locally are simply not there during a run.
Explain what the temporary directory buys — a stateless, repeatable start — and what --user-data-dir replaces it with, including that Chrome locks the directory it opens so two sessions cannot share one path.
Be ready to diagnose the works-locally, fails-in-the-pipeline report end to end, and to argue why state a test did not create is a reproducibility problem rather than a convenient shortcut.
Own the position on browser state as a whole: what a suite is allowed to inherit, whether template profiles are kept in version control, and how a team migrates off a shared profile without stopping feature work.
## The default: a throwaway profile per session When a Chrome session is started through Selenium with no profile options set, the driver creates a **fresh temporary user-data directory** for that session and launches Chrome against it. The consequences are the point of the design: - No cookies, so no logged-in recipe account carried in from yesterday. - No extensions, no toolbars, no settings picked up from a personal profile. - No history, no autofill, no saved passwords. - Nothing left behind that the next session can read. That is why two engineers on two machines get the same result: the browser under test is **stateless by default**, and every piece of state a test relies on has to be state the test created. ## What `--user-data-dir` changes `--user-data-dir=<path>` is Chrome's own switch, added like any other through `ChromeOptions.addArguments`. It replaces the driver's temporary directory with a path you name. Everything above inverts: the session starts with whatever that directory holds, writes back into it, and the next run inherits the result. A second switch, `--profile-directory=<name>`, selects one named profile *inside* the user-data directory rather than choosing a different directory. | Need | Chrome and Edge | Firefox | |---|---|---| | Fresh disposable profile | the default, nothing to set | the default, nothing to set | | Use a specific directory | `addArguments("--user-data-dir=<path>")` | `addArguments("-profile", "<path>")` | | Pick a profile inside it | `addArguments("--profile-directory=<name>")` | not applicable | | Start from a template | copy the directory yourself first | `setProfile(new FirefoxProfile(dir))`, which treats it as a template | | Change one setting only | the `prefs` map | `addPreference(key, value)` | ## The failure you will actually see The classic report is "it works on my laptop and dies in the pipeline", and the sequence is usually this: 1. Someone points `--user-data-dir` at their everyday Chrome profile so the recipe app is already signed in and the suite can skip the sign-in step. 2. Chrome is open on that machine, holding a lock on the directory. 3. The new session fails to start: Chrome will not open a user-data directory another process already has, and the request comes back as a session-not-created error whose message names the user data directory as already in use. 4. On the pipeline host the directory does not exist at all, so the session starts but the "already signed in" assumption evaporates and every case fails at its first assertion. The same lock is why two sessions cannot share one path. If a directory is genuinely wanted, give each session one of its own: ```java Path profileDir = Files.createTempDirectory("recipe-suite-profile"); ChromeOptions options = new ChromeOptions(); options.addArguments("--user-data-dir=" + profileDir.toAbsolutePath()); ``` ## Judgment: state a test did not create A profile is a bundle of state nobody in the repository wrote down. Reusing a real one buys a shortcut and pays for it in three places: - **Reproducibility.** A failure that depends on the contents of one machine's profile cannot be reproduced by a colleague from the repository alone. - **Drift.** The profile ages. An extension update, an expired cookie or a changed setting silently changes what the suite exercises, with no commit to point at. - **Blast radius.** Tests write into it. A run that clears the recipe collection is now clearing a human being's real one. The defensible uses are narrow and deliberate: a profile built by a script and committed as a template, a directory copied fresh per run, or a browser configuration that genuinely cannot be expressed as arguments and preferences. ## Practical patterns - Prefer **preferences and arguments** over a whole profile. They are explicit, reviewable, and survive a machine rebuild. - If a real profile is needed, build it from a **template directory kept in version control** and copy it per run so nothing writes back into the template. Firefox does the copy for you when a `FirefoxProfile` is constructed from a directory; on Chrome the copy is yours to make. - Give any session that uses `--user-data-dir` a **path of its own**, never a shared one and never a directory a human's browser might have open. - Remember the temporary directory belongs to the driver: it is created for the session and cleaned up when the session ends properly, so shutting sessions down cleanly is a prerequisite for the default behaviour working as advertised. - When you inherit a suite that depends on a real profile, migrate incrementally: name each piece of state the profile was providing, re-create it explicitly, and drop the directory once the list is empty.
- What does --profile-directory do that --user-data-dir does not?`--user-data-dir` names the directory Chrome keeps all its profile data in; `--profile-directory` selects one named profile inside that directory, such as Default. Given only `--profile-directory`, Chrome looks inside whichever user-data directory is in force, which in a driver-started session is the throwaway one the driver made.
- Two sessions are started with the same --user-data-dir value. What happens?The second usually fails to start. Chrome will not open a user-data directory another process already holds, so the new-session request comes back as a session-not-created error whose message names that directory as already in use. Each session needs a path of its own.
- Does Firefox behave the same way?It defaults the same way — a fresh profile per session — but the knobs differ. `FirefoxOptions.setProfile(new FirefoxProfile(dir))` treats the directory as a template rather than using it in place, so the original is not locked, and individual settings are usually better expressed with `addPreference` than with a whole profile.
saying these in an interview costs you the question
- Assumes a Selenium session reuses the developer's everyday Chrome profile
- Points --user-data-dir at a directory a running Chrome already holds
- Treats one user-data directory as safe for two sessions at once
- Ships a real logged-in profile instead of setting the state explicitly
- Believes --profile-directory alone selects a directory outside the user-data dir