What is switch command?
Webdriver library contains a set of classes and methods that help us to communicate with the web browser. In most of testing scenarios we find element on the website and then click it in case of buttons or fill the text in case of text boxes. Often it’s enough when you begin to automate your tests in the web browser.
However, at some point you may get stuck discovering that you’re not able to find the element on the page. The first thing that you should ask yourself is: Maybe my application opened a new popup window and the element that I’m trying to find is placed in this new window? If your answer is “YES” - remember one thing:
The new popup window(or new tab) shows another HTML page that opens in a new context, so you should switch context to the new window first and then you can communicate with the new window. This is exactly what switch command comes into play.
Methods available under WebDriver API for Switch Commands
There is a set of methods accessible in the webdriver API. We could use a Visual Studio functionality called intellisense. Intellisense shows all possible methods:
Let’s examine the following methods quickly. We’ll cover some of them in the examples so that you can easily copy code fragments and run in your Visual Studio.
- ActiveElement - Switches focus to element that has focus at the moment. If there’s no element with focus, this method will switch to body element of the page.
- Alert - Switches focus to currently active dialog box
- DefaultContent - Switches focus to the first frame on the page or main document if page contains iframes.
- Frame - Switches focus to frame by given index
- ParentFrame - Switches focus to parent frame of currently selected frame
- Window - Switches focus to the window with specified name
Now let’s see the way to find a list of windows that webdriver can interact with. Such set of windows is called windows handles. Each window handle is identified by random string, which is different on each test run.
Each of the tests in this article should be preceded by special method. Thanks to [TestInitialize] annotation the Setup() method is run before each test method in the class.
[TestInitialize]
public void Setup()
{
_driver = new InternetExplorerDriver();
_driver.Manage().Window.Maximize();
_driver.Url = "https://demoqa.com/browser-windows/";
}
In the code snippet, you can see that we create a new instance of InternetExplorerDriver and maximize the window to see as much website content as possible. The demo page we are using is: https://demoqa.com/browser-windows/
We can distinguish 3 handle types, We’ll cover each of them in the below examples:
- alert
- frame
- Window
How to handle Alert in Selenium using C#?
Alert is a popup window that can be shown by running javascript alert() method. The website that we’re testing makes use of alert(). The result is presented in the following picture:
Let's automate the test
Before we start, we need to be aware that there are various test frameworks that we can use. In the world of .NET, the most popular frameworks are NUnit and Visual Studio Testing tools. In the example, we used the latter because it’s a Visual Studio build-in tool so we don’t need to install additional NuGet packages. You can see How to Configure and Use NUnit Test Framework works.
The first step that we take is creating a new class with tests.
We need to create test method which looks like this:
[TestMethod]
public void OpenJavaScriptAlert()
{
var alertButton = _driver.FindElement(By.Id("alert"));
alertButton.Click();
var alert = _driver.SwitchTo().Alert();
var expectedAlertText = "Knowledge increases by sharing but not by saving. Please share " +
"this website with your friends and in your organization.";
Assert.AreEqual(expectedAlertText, alert.Text);
}
What happens in the code:
- We found Alert button element and later clicked on it.
- Then we switched the context to newly created alert window.
- Finally, we use Assert class to compare the text displayed in the alert window with expected value. The test should pass.
How to handle Frame in Selenium using C#?
Some websites use frames to load fragments of the website. Most of the currently created websites avoid the frames. However, we still need to know how to switch to frame. The solution is really simple and it looks exactly like the above example with Alert. The only difference is that we use Frame method instead of Alert.
- To switch the context to frame : _driver.SwitchTo().Frame()
- To switch back to parent frame : _driver.SwitchTo().ParentFrame()
How to handle Window in Selenium using C#?
We can open a new window in javascript by running the window.open() method. On the website that we test after clicking a button the code that runs is similar to this: window.open("www.toolsqa.com");. When the web browser runs this code the new window opens. The web browser should show the following:
Now let’s create next test to automate the test:
[TestMethod]
public void OpenNewBrowserWindow()
{
//Step 1
var newBrowserWindowButton = _driver.FindElement(By.Id("button1"));
Assert.AreEqual(1, _driver.WindowHandles.Count);
string originalWindowTitle = "Demo Windows for practicing Selenium Automation";
Assert.AreEqual(originalWindowTitle, _driver.Title);
//Step 2
newBrowserWindowButton.Click();
Assert.AreEqual(2, _driver.WindowHandles.Count);
//Step 3
string newWindowHandle = _driver.WindowHandles.Last();
var newWindow = _driver.SwitchTo().Window(newWindowHandle);
string expectedNewWindowTitle = "QA Automation Tools Tutorial";
Assert.AreEqual(expectedNewWindowTitle, newWindow.Title);
}
What happens in the code:
- Step 1: Test is just locating the Button but it is not clicking on it yet. Assert is used to check the number of handles by using driver.WindowHandles property. It should be 1, which is the parent main window. Another assert is used to check the title of main window.
- Step 2: Clicked the button in order to open a new window. Now the Assert is used to check that if the count of windows opened is 2.
- Step 3: WindowHandles.Last() is used to point to last or recent window opened by the driver. Once the handle is recevied, SwichTo() method is used to change the context to the new window. he last statement in this test checks if the title of a new window changed.
How to handle a New Tab in Selenium using C#?
Now we know that we can open a URL in another window. But we can also open it in a new tab. Then a new tab in the browser is created and new window is not created.
Let’s look at the code:
[TestMethod]
public void OpenBrowserTab()
{
//Step 1
var alertButton = _driver.FindElement(By.XPath("/html/body/div[1]/div[5]/div[2]/div/div/p[4]/button"));
alertButton.Click();
string originalTabTitle = "Demo Windows for practising Selenium Automation";
Assert.AreEqual(originalTabTitle, _driver.Title);
//Step 2
string newTabHandle = _driver.WindowHandles.Last();
var newTab = _driver.SwitchTo().Window(newTabHandle);
var expectedNewTabTitle = "QA Automation Tools Tutorial";
Assert.AreEqual(expectedNewTabTitle, newTab.Title);
//Step 3
var originalTab = _driver.SwitchTo().Window(_driver.WindowHandles.First());
Assert.AreEqual(originalTabTitle, originalTab.Title);
}
What happens in the code:
- Step 1: Locate the button and clicked on it to open the new tab. Assert is used to check the original tab title.
- Step 2: This is same as what is done in the above example.
- Step 3: What’s interesting here is that the test can also switch to the First Window using _driver.WindowHandles.First(), the way it switched to the Last Window.
Conclusion
The switch command is a useful tool that you’ll find useful in the cases:
- application under test opens a new popup window(for example javascript alert)
- application opens a new page in a new frame
- applications opens a new page in a new window or browser tab
Working visual studio solution can be downloaded from Bitbucket.