Skip to main content
SeleniumDecoded

Navigation and Browser Control

Open URLs, move back and forward, refresh, read the title and URL, manage window size and position, maximise, full-screen, and close cleanly.

Selenium 3 & 4 Stable Updated 9 Sept 2026 · Verified against Selenium 4.48.0

Every test starts by going somewhere and most end by checking where they ended up. This lesson covers the navigation and window commands you will use in every suite, plus the details that trip people up: what get waits for, the difference between close and quit, and window sizing for consistent screenshots.

Opening a Page

Navigate to a URL
Selenium 3 & 4 Stable
driver.get("https://example.com");
// equivalent:
driver.navigate().to("https://example.com");
driver.get("https://example.com")
await driver.get('https://example.com');
// equivalent:
await driver.navigate().to('https://example.com');
driver.Navigate().GoToUrl("https://example.com");
// shorthand property setter:
driver.Url = "https://example.com";

By default get returns when the browser fires the load event, meaning the HTML and all its subresources (images, scripts, stylesheets) have finished loading. Single-page apps then usually make more requests, so load is not “the page is ready.” Wait for a specific element before interacting; see Page Load Strategy and Timeouts for the eager and none strategies that return earlier.

Always include the scheme. driver.get("example.com") is not a valid URL and behaves differently per browser.

Back, Forward, Refresh

History navigation
Selenium 3 & 4 Stable
driver.navigate().back();
driver.navigate().forward();
driver.navigate().refresh();
driver.back()
driver.forward()
driver.refresh()
await driver.navigate().back();
await driver.navigate().forward();
await driver.navigate().refresh();
driver.Navigate().Back();
driver.Navigate().Forward();
driver.Navigate().Refresh();

These use the browser’s history, so single-page apps that manage history with pushState behave as they would for a user pressing the buttons. A refresh re-runs the page and invalidates every WebElement you hold; re-find elements afterwards.

Reading Where You Are

Title and URL
Selenium 3 & 4 Stable
String title = driver.getTitle();
String url = driver.getCurrentUrl();
// Common assertion pattern: wait for the URL to change after an action
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.urlContains("/dashboard"));
assertTrue(driver.getCurrentUrl().endsWith("/dashboard"));
title = driver.title
url = driver.current_url
# Wait for the URL to change after an action
WebDriverWait(driver, 10).until(EC.url_contains("/dashboard"))
assert driver.current_url.endswith("/dashboard")
const title = await driver.getTitle();
const url = await driver.getCurrentUrl();
// Wait for the URL to change after an action
await driver.wait(until.urlContains('/dashboard'), 10000);
string title = driver.Title;
string url = driver.Url;
// Wait for the URL to change after an action
new WebDriverWait(driver, TimeSpan.FromSeconds(10))
.Until(d => d.Url.Contains("/dashboard"));

Asserting on the title immediately after a click is a classic flaky pattern: the click returns before navigation completes. Wait on the URL or title with an explicit wait first.

Window Size and Position

Layout-dependent tests (responsive menus, relative locators, screenshots) need a known viewport. Set it explicitly rather than relying on whatever size the driver picked.

Sizing and positioning the window
Selenium 3 & 4 Stable
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
driver.manage().window().maximize();
driver.manage().window().fullscreen();
driver.manage().window().minimize(); // Selenium 4
driver.manage().window().setSize(new Dimension(1366, 768));
driver.manage().window().setPosition(new Point(0, 0));
Dimension size = driver.manage().window().getSize();
System.out.println(size.getWidth() + "x" + size.getHeight());
driver.maximize_window()
driver.fullscreen_window()
driver.minimize_window() # Selenium 4
driver.set_window_size(1366, 768)
driver.set_window_position(0, 0)
size = driver.get_window_size()
print(size["width"], size["height"])
# Or set everything at once
driver.set_window_rect(x=0, y=0, width=1366, height=768)
await driver.manage().window().maximize();
await driver.manage().window().fullscreen();
await driver.manage().window().minimize();
await driver.manage().window().setRect({ x: 0, y: 0, width: 1366, height: 768 });
const { width, height } = await driver.manage().window().getRect();
driver.Manage().Window.Maximize();
driver.Manage().Window.FullScreen();
driver.Manage().Window.Minimize();
driver.Manage().Window.Size = new System.Drawing.Size(1366, 768);
driver.Manage().Window.Position = new System.Drawing.Point(0, 0);
var size = driver.Manage().Window.Size;

Two things to know:

  • Headless browsers ignore maximize because there is no screen. Set an explicit size, or pass --window-size=1920,1080 in Chrome options.
  • Window size is not viewport size. Browser chrome (tabs, address bar) takes space. If a test needs an exact viewport, compute it with JavaScript (window.innerWidth) and adjust, or use BiDi’s setViewport emulation command.

Closing: close() vs quit()

Ending the session properly
Selenium 3 & 4 Stable
driver.close(); // closes the current window/tab only; session ends if it was the last one
driver.quit(); // closes every window, ends the session, stops the driver process
// Always quit in a finally block or test framework hook
try {
// ... test ...
} finally {
driver.quit();
}
driver.close() # closes the current window/tab only
driver.quit() # closes every window and ends the session
# pytest fixture pattern
@pytest.fixture
def driver():
d = webdriver.Chrome()
yield d
d.quit()
await driver.close(); // current window only
await driver.quit(); // everything
// Mocha
afterEach(async () => { await driver.quit(); });
driver.Close(); // current window only
driver.Quit(); // everything
// ChromeDriver implements IDisposable; Dispose() calls Quit()
using var driver = new ChromeDriver();

Forgetting quit() is how CI machines end up with hundreds of orphaned chromedriver processes. If you use close() to shut a popup, switch back to a remaining window handle before the next command, or every command fails with no such window.

Putting It Together

A complete navigation flow
Selenium 4 Stable
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
try {
driver.manage().window().setSize(new Dimension(1366, 768));
driver.get("https://example.com/products");
driver.findElement(By.linkText("Laptops")).click();
wait.until(ExpectedConditions.urlContains("/laptops"));
assertEquals("Laptops | Example", driver.getTitle());
driver.navigate().back();
wait.until(ExpectedConditions.urlContains("/products"));
} finally {
driver.quit();
}
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
try:
driver.set_window_size(1366, 768)
driver.get("https://example.com/products")
driver.find_element(By.LINK_TEXT, "Laptops").click()
wait.until(EC.url_contains("/laptops"))
assert driver.title == "Laptops | Example"
driver.back()
wait.until(EC.url_contains("/products"))
finally:
driver.quit()
const driver = await new Builder().forBrowser('chrome').build();
try {
await driver.manage().window().setRect({ width: 1366, height: 768 });
await driver.get('https://example.com/products');
await driver.findElement(By.linkText('Laptops')).click();
await driver.wait(until.urlContains('/laptops'), 10000);
assert.strictEqual(await driver.getTitle(), 'Laptops | Example');
await driver.navigate().back();
await driver.wait(until.urlContains('/products'), 10000);
} finally {
await driver.quit();
}
using var driver = new ChromeDriver();
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
driver.Manage().Window.Size = new System.Drawing.Size(1366, 768);
driver.Navigate().GoToUrl("https://example.com/products");
driver.FindElement(By.LinkText("Laptops")).Click();
wait.Until(d => d.Url.Contains("/laptops"));
Assert.That(driver.Title, Is.EqualTo("Laptops | Example"));
driver.Navigate().Back();
wait.Until(d => d.Url.Contains("/products"));

Summary

  • get waits for the load event, not for your app to be ready; wait for an element or URL before acting.
  • Use navigate() for back, forward and refresh; refreshing invalidates element references.
  • Set an explicit window size, especially headless, and remember viewport differs from window size.
  • close() shuts one window; quit() ends the session. Always quit() in cleanup.

Related lessons