Occasionally you’ll run into a link or action in the application you’re testing that will open a new window. In order to work with both the new and originating windows, you’ll need to switch between them.
On the face of it, this is a pretty straightforward concept. But lurking within it is a small gotcha to watch out for that will bite you in some browsers and not others.
Let’s step through a couple of examples to demonstrate.
Example
Java
// filename: MultipleWindows.java
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import java.util.Set;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.*;
public class MultipleWindows {
WebDriver driver;
@Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
}
@After
public void tearDown() throws Exception {
driver.quit();
}
// Example 1
@Test
public void multipleWindows() {
driver.get("http://the-internet.herokuapp.com/windows");
driver.findElement(By.cssSelector(".example a")).click();
Object[] allWindows = driver.getWindowHandles().toArray();
driver.switchTo().window(allWindows[0].toString());
assertThat(driver.getTitle(), is(not("New Window")));
driver.switchTo().window(allWindows[1].toString());
assertThat(driver.getTitle(), is("New Window"));
}
// Example 2
@Test
public void multipleWindowsRedux() {
driver.get("http://the-internet.herokuapp.com/windows");
String firstWindow = driver.getWindowHandle();
String newWindow = "";
driver.findElement(By.cssSelector(".example a")).click();
Set<String> allWindows = driver.getWindowHandles();
for (String window : allWindows) {
if (!window.equals(firstWindow)) {
newWindow = window;
}
}
driver.switchTo().window(firstWindow);
assertThat(driver.getTitle(), is(not(equalTo("New Window"))));
driver.switchTo().window(newWindow);
assertThat(driver.getTitle(), is(equalTo("New Window")));
}
}
Python
# filename: new_window.py
import unittest
from selenium import webdriver
class Windows(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
def tearDown(self):
self.driver.quit()
def test_example_1(self):
driver = self.driver
driver.get('http://the-internet.herokuapp.com/windows')
driver.find_element_by_css_selector('.example a').click()
driver.switch_to_window(driver.window_handles[0])
assert driver.title != "New Window", "title should not be New Window"
driver.switch_to_window(driver.window_handles[-1])
assert driver.title == "New Window", "title should be New Window"
def test_example_2(self):
driver = self.driver
driver.get('http://the-internet.herokuapp.com/windows')
first_window = driver.window_handles[0]
driver.find_element_by_css_selector('.example a').click()
all_windows = driver.window_handles
for window in all_windows:
if window != first_window:
new_window = window
driver.switch_to_window(first_window)
assert driver.title != "New Window", "title should not be New Window"
driver.switch_to_window(new_window)
assert driver.title == "New Window", "title should be New Window"
if __name__ == "__main__":
unittest.main()
Ruby
# filename: new_window.rb
require 'selenium-webdriver'
require 'rspec/expectations'
include RSpec::Matchers
def setup
@driver = Selenium::WebDriver.for :firefox
end
def teardown
@driver.quit
end
def run
setup
yield
teardown
end
run do
@driver.get 'http://the-internet.herokuapp.com/windows'
@driver.find_element(css: '.example a').click
@driver.switch_to.window(@driver.window_handles.first)
expect(@driver.title).not_to eql 'New Window'
@driver.switch_to.window(@driver.window_handles.last)
expect(@driver.title).to eql 'New Window'
end
run do
@driver.get 'http://the-internet.herokuapp.com/windows'
first_window = @driver.window_handle
@driver.find_element(css: '.example a').click
all_windows = @driver.window_handles
new_window = all_windows.select { |this_window| this_window != first_window }
@driver.switch_to.window(first_window)
expect(@driver.title).not_to eql 'New Window'
@driver.switch_to.window(new_window)
expect(@driver.title).to eql 'New Window'
end
C#
// filename: MultipleWindows.cs
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;
public class MultipleWindows
{
IWebDriver Driver;
[SetUp]
public void SetUp()
{
Driver = new FirefoxDriver();
}
[TearDown]
public void TearDown()
{
Driver.Quit();
}
[Test]
public void MultipleWindowsExample1()
{
Driver.Navigate().GoToUrl("http://the-internet.herokuapp.com/windows");
Driver.FindElement(By.CssSelector(".example a")).Click();
var Windows = Driver.WindowHandles;
Driver.SwitchTo().Window(Windows[0]);
Assert.That(Driver.Title != "New Window");
Driver.SwitchTo().Window(Windows[1]);
Assert.That(Driver.Title.Equals("New Window"));
}
[Test]
public void MultipleWindowsExample2()
{
Driver.Navigate().GoToUrl("http://the-internet.herokuapp.com/windows");
string FirstWindow = Driver.CurrentWindowHandle;
string SecondWindow = "";
Driver.FindElement(By.CssSelector(".example a")).Click();
var Windows = Driver.WindowHandles;
foreach(var Window in Windows)
{
if (Window != FirstWindow)
SecondWindow = Window;
}
Driver.SwitchTo().Window(FirstWindow);
Assert.That(Driver.Title != "New Window");
Driver.SwitchTo().Window(SecondWindow);
Assert.That(Driver.Title.Equals("New Window"));
}
}
If you save this file and run it here is what will happen for either example:
- Open the browser
- Visit the page
- Click to open a new window
- Switch between the windows
- Check the page title to make sure the correct window is in focus
- Close the browser