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.
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
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
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
String title = driver.getTitle();String url = driver.getCurrentUrl();
// Common assertion pattern: wait for the URL to change after an actionnew WebDriverWait(driver, Duration.ofSeconds(10)) .until(ExpectedConditions.urlContains("/dashboard"));assertTrue(driver.getCurrentUrl().endsWith("/dashboard"));title = driver.titleurl = driver.current_url
# Wait for the URL to change after an actionWebDriverWait(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 actionawait driver.wait(until.urlContains('/dashboard'), 10000);string title = driver.Title;string url = driver.Url;
// Wait for the URL to change after an actionnew 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.
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 oncedriver.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
maximizebecause there is no screen. Set an explicit size, or pass--window-size=1920,1080in 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’ssetViewportemulation command.
Closing: close() vs quit()
driver.close(); // closes the current window/tab only; session ends if it was the last onedriver.quit(); // closes every window, ends the session, stops the driver process
// Always quit in a finally block or test framework hooktry { // ... test ...} finally { driver.quit();}driver.close() # closes the current window/tab onlydriver.quit() # closes every window and ends the session
# pytest fixture pattern@pytest.fixturedef driver(): d = webdriver.Chrome() yield d d.quit()await driver.close(); // current window onlyawait driver.quit(); // everything
// MochaafterEach(async () => { await driver.quit(); });driver.Close(); // current window onlydriver.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
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
getwaits for theloadevent, 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. Alwaysquit()in cleanup.