Selenium Focus Issues And How To Solve Them
This is a comprehensive guide to help you understand some common Selenium focus issues and how to solve these issues, with examples.
Join the DZone community and get the full member experience.Join For Free
While performing automation testing in Selenium, your test code or test script could result in erroneous results if it is interacting with a web element that is not yet loaded in the Document Object Model (DOM). Or if it is on another iFrame, tab, or window which is not in focus, or any such scenarios. These types of unexpected erroneous outcomes are known as Selenium focus issues.
Selenium can only control a browser when its window is in focus. How do you ensure that the Selenium test code interacts with web elements when they are in focus? You can use workarounds like the addition of minimal delay (in seconds) to ensure that the element on which the testing is performed has loaded. Still, that solution is not foolproof as any change in web page design could make the test inefficient.
This article will cover what the common Selenium focus issues are and how to solve these issues, with examples.
Before we get started, let’s look at some of the prerequisites required for the development. You need to have Python and Selenium installed on your machine. You can download Python installation files for Windows from here. To install Selenium, you should execute pip install selenium on your terminal. PyCharm IDE (Community Edition) is used for implementation, and you can download it from here. Next, you should download the WebDriver of the browser on which testing is performed; mentioned below are the locations from where you can download WebDriver for browsers like Firefox, Chrome, Internet Explorer, etc.
For in-depth information about Python’s usage with the Selenium framework for automated cross-browser testing, please refer to this blog on our website. Now that the setup is ready let’s look at some of the ways to fix Selenium focus issues.
Selenium Focus Issues With Multiple iFrames
You would have come across many websites that have advertisements or follow a design where an HTML document is embedded inside another HTML document. That particular web element is called an iFrame. iFrame is defined by the
< iframe >< /iframe > tag on a web page. To switch between different iFrames, you can make use of
switch_to(self, frame-reference) API.
For demonstration purposes, we use the webpage, which contains three iFrames. Below is the HTML code of the page, which only details information about the iFrames.
As shown in the HTML code above, the three frames’ names are
classFrame. To understand the Selenium focus issue better, let us see an example. In the below code, we will be using the iFrames of this webpage. We will simply try to click on '
com.thoughtworks.selenium' present on '
Upon execution, the above test gives the following error:
This error occurs because the WebDriver instance is unable to focus on iFrame '
classFrame' upon which the element
com.thoughtworks.selenium is present. Similarly, in many such scenarios, when the instance’s focus is on some other iFrame, and the required element is on another, the Selenium focus issues happen.
How To Solve Selenium Lose Focus Issue With Multiple iFrames
There are several ways through which you can navigate between iFrames on a webpage. One of the most simple and popular methods is by using
switch_to().frame() method is used to conveniently switch between iFrames. Let us see how to use the
switch_to().frame() method to solve the Selenium lose focus issue:
Name of the iFrame — Each iFrame has a name associated with it. You can find the name using the Inspect Tool in the web browser. The name of the iFrame to which you want to switch to can be passed to
driver.switch_to.frame(‘frame_name’) API. In the above case, if you plan to navigate to
classFrame iFrame, you simply have to use
If your focus is already there on another iFrame, you need to switch back to the parent frame using the following APIs
ID of the iFrame — You can also switch between iFrames by using the ID associated with the iFrame.
driver.find_element_by_id(‘frame-id’) where frame-id is used as a locator to switch to a specific iFrame.
Tag name and Index combination — You can make use of the API
driver.find_elements_by_tag_name() along with the index of the destination iFrame.
Now that we have looked into different ways to switch between iFrames let’s look at an example of switching between three iFrames on the webpage.
driver.switch_to.frame() API is used with the frame-name as the parameter to switch between different iFrames. You can use the HTML source of the webpage to get the iFrame related information or hover over the designated iFrame and inspect the element using the Inspect option in the web browser.
Once you are on the required iFrame, search for a particular link using
find_element_by_link_text(), and click operation is performed. An implicit wait of 20 seconds
(driver.implicitly_wait(20)) is added between different operations performed on two iFrames so that there is enough time to switch to the parent frame. You need to do a trial and error before zeroing on the wait time; however, care has to be taken that the wait time is not too high else it would delay the execution of the other tests.
Selenium Focus Issues With Multiple Tabs
There would be multiple test scenarios when using automation testing with Selenium, where tests need to be performed on different browser windows. In such cases, multiple browser windows or multiple tabs have to be opened, and test operations on one browser have to be performed. This is also applicable for automation tests that are done in parallel, which is where Selenium’s focus issues are more common.
Let us see the Selenium lose focus issue with multiple tabs with the help of an example. In the below example, we will try to open multiple tabs (2) and try to run some tests on them:
Upon executing the above test, we will get an error:
This error occurred because the WebDriver instance did not focus on the first tab when we tried to perform tests on it. Instead, the focus was on the second tab because we recently created a new tab. Similarly, when dealing with multiple tabs or windows, this 'Selenium loses focus' issue is very common to occur.
How To Solve Selenium Focus Issue With Multiple Tabs
Each window has a window handle associated with it, and that handle is a unique number. For example, if there are two browser windows/browser tabs opened simultaneously, one window’s window handle will be ‘0’, and the other one will be ‘1’. The window handle will be freed once the browser window/tab is closed. To switch tabs, we make use of the driver.window_handles[handle-number] API. So, for instance, to switch to the window with window handle ‘1’, you can use
driver.execute_script(“window.open(”);”). To open a new browser window, you should use
driver.execute_script(“window.open(‘secondary-url’, ‘new window’)”)
As seen in the execution snapshot below, the parent window with the test URL (https://www.duckduckgo.com) is first opened. The window handle of this browser window is ‘0’. After a sleep of 10 seconds, a new tab is opened with the test URL (https://www.lambdatest.com), and the window handle associated with this tab is ‘1’.
driver.switch_to.window(driver.window_handles) is used to switch back to the parent window (i.e. window handle – 0).
Selenium Focus Issues With onfocus() And onblur() Callbacks
There are many websites where you would have encountered a form validation code. For example, suppose you came across a website asking you to create a desired username as per the set criteria. But as soon as you enter the username and move out of the text box, a warning appears stating the entered username is incorrect along with the rules of setting username. These pop-ups or warnings stating messages like the entered password does not meet the requirements, or the password field is left empty, etc. are created with the help of
onblur() events are used in the majority of websites/web applications.
onfocus() event is fired when a particular web element gets focus. The web element could be a hyperlink (
< a >), input element (
< input >), select element (
< select >), etc. For example, in the below code, the input window’s color would change when it gets focus.
On the other hand, the
onblur() event is fired when the control is shifted from a web element without any change in the web element’s value. For example, the user keeps the user-name field empty, and the focus is shifted to the next field. In the below example, the
onblur() event will convert all input box characters to lowercase as soon as it loses focus.
Now when these events are triggered simultaneously during automation testing in Selenium, there can be situations when one or the other callback event doesn’t happen or gets triggered. One such scenario is with a dropdown. Suppose there is a dropdown whose value you want to select using Selenium, such that the value of the dropdown changes when the
onblur() event is triggered. In such a scenario, the Selenium WebDriver instance might not be able to trigger the
onblur() event, thereby resulting in Selenium lose focus issue.
How To Handle Selenium Lose Focus Issues With onfocus() And onblur() Callbacks
Now let us see an example to see how to handle Selenium focus issues using
onblur() events. The example below shows the demonstration of
onblur() events on the URL https://output.jsbin.com/remozek/1.
execute_script() method through the WebDriver instance is invoked to trigger the required events.
As shown in the implementation above, the textbox element is located using the XPath expression, where the ID of the web element is passed as the input argument.
The code is executed using python
< file-name.py > command, as shown in the output snapshot; the
How To Handle Selenium Focus Issues With Incomplete Page Loading
As mentioned in the blog’s starting, the majority of the Selenium focus issues occur when the operation is performed on a web element that is not yet loaded, or the loading of the web page is not yet complete. In this article, we will see two ways to handle such Selenium lose focus issues:
Wait until the required Web Element’s loading is found, using
Find the Web Element by inspecting HTML Source, using
In the cases mentioned above of Selenium focus issues,
WebDriverWait() with a specified time duration can be used to check the web element’s presence on the page. If the required web element is not present,
TimeoutException is invoked, the next set of instructions is executed.
The unittest framework is used to demonstrate automation testing with Selenium. To fetch details about the web locator, i.e., XPath, CSS Selector, Name, Link Text, ID, etc., we again use the Inspect Element option in the web browser. In the example below, we have used the NAME and XPath locators to perform actions on those web elements.
As seen in the implementation, a
WebDriverWait() of 10 seconds is used for the two web elements. Once the web elements are loaded, the required operations are performed on them. However, if the time duration of 10 seconds elapses,
TimeOutException() occurs, and the error message No element found is printed. Below is the snapshot of the execution window:
Apart from these mechanisms, there are other ways to tackle Selenium focus issues. One of them is inspecting the HTML source code when doing automation testing with Selenium and checking the presence of an element on the page.
How To Handle Selenium Focus Issue By Inspecting HTML Source
Apart from using
presence_of_element_located() to check the presence of web elements to handle Selenium focus issues, another approach is to inspect the HTML source for the presence of the required web element. To get the HTML source of a webpage,
elem.get_attribute(“innerHTML”) is used, and a search for the required web element is performed to check the presence of the element on the web page.
In the example shown below, the HTML source of the URL under test https://www.lambdatest.com is written into an external file (optional step), and a search for the button
home-btn is performed. It matches the string in the HTML source; hence the search operation may take time if the source code is large in size.
These are some mechanisms that can be used in automated cross-browser testing for fixing Selenium focus problems. Selenium focus issues are more prevalent when doing parallel testing since the control might shift from one window to another. This is a common issue when automation testing with Selenium is done using the local Selenium WebDriver. Even if Remote Selenium WebDriver is used for automated cross-browser testing, the approach might not be scalable since you cannot have an in-house setup with different combinations of web browsers, operating systems, and devices.
Parallel testing has to be used when using automation testing with Selenium as it improves the test process’s overall efficiency. Rather than local automated cross-browser testing, a better approach is to use remote automated cross-browser testing on the cloud. Using a platform like LambdaTest, you can perform automated and live interactive automated cross-browser testing on real browsers and operating systems online. Since tests can be executed in parallel, there is a huge reduction in the overall turn-around time of the testing phase. Also, tests being executed can be triggered on different machines, thereby minimizing the chances of Selenium focus problems that you encounter with automation testing with Selenium on a local machine.
Solving Selenium Focus Issues On Cloud Selenium Grid
To get started with automated cross-browser testing on the cloud, you need to create an account on LambdaTest. Once the account is created, you should note the username and access-key are located at https://accounts.lambdatest.com/profile. This combination is used to access the Selenium Grid on LambdaTest. Though we have used the Python language for implementation, you can use other development languages like C#, Perl, Ruby on Rails, etc. to perform automation testing with Selenium on LambdaTest’s Remote Selenium Grid.
Every test that is performed on the LambdaTest grid has a unique
test-id associated with it. The Automation Tab contains the information of all the automated tests that have been executed so far. To set the browser capabilities, you should use the LambdaTest Capability Generator. Select the development language as Python and choose the correct settings of the browser, operating system, resolution, etc.
For demonstration, we use Chrome 67.0 on macOS (OS X Mavericks) operating system. Now that the setup is ready, we port the implementation that demonstrated the usage of onfocus() and onblur() events in automation testing with Selenium.
As seen in the source code, there are minimal changes to port from local Selenium Grid to Selenium Grid on LambdaTest. The combination of username and pass-key is passed to the remote URL where the execution is performed.
remote_url = "http://" + username + ":" + access_key + "@hub.lambdatest.com/wd/hub"
The remote URL and browser capabilities that were generated using the LambdaTest capabilities generator are passed to the Selenium WebDriver API. Apart from these changes, the rest of the implementation is the same. Using parallel testing, you can perform multiple tests that do automation testing with Selenium.
The code is executed in a similar manner using the local terminal window. You should visit the Automation Tab to check the status of the automation test.
In case you want to perform automated cross-browser testing on locally hosted pages, you can use the Lambda Tunnel app. Using the Lambda Tunnel app, you can test your locally hosted pages on the LambdaTest Selenium Automation Platform. You can connect to the LambdaTest servers from your local machine using SSH-based integration. Please refer to this article for more information on leveraging the Lambda Tunnel for automated cross-browser testing.
Though automation testing with Selenium is a very popular approach for automated cross-browser testing, you might encounter Selenium focus issues, which may impact the tests’ efficiency. Selenium focus issues can be more frequent when tests are executed in parallel. You can use Implicit wait or Explicit wait to ensure that the required web element is present in the DOM, but a better approach would be to use a
Thank you for reading. If you have any questions, don’t hesitate to reach out via the comment section below.
Published at DZone with permission of Himanshu Sheth. See the original article here.
Opinions expressed by DZone contributors are their own.