How To Handle WebElements In Selenium Python
Selenium automation testing is the common term used to describe a test run using Selenium. When it comes to automation testing, Selenium is a popular open-source testing tool used to automate different web browsers, such as Chrome, Firefox, Microsoft Edge, and Safari, among others, across multiple platforms. The Selenium WebDriver allows you to execute test scripts in various programming languages such as Java, Python, C#, JavaScript, PHP, and Ruby.
In Selenium, a WebElement represents an HTML element of a web page. WebElements are the building blocks of the web page. For example, anything on a web page, like a text box, button, links, dropdown buttons, etc., comes under WebElements.
Selenium WebDriver takes every single element and encapsulates it as an object of the WebElement. It provides an API to locate the web page elements and take a specific action like entering text into text boxes, clicking the buttons, etc. Using the Selenium framework, you can easily locate and interact with WebElements while performing Selenium Python testing.
Handling WebElements is important when automating web application testing. In this blog, we will look at how to handle WebElements in Selenium Python.
Automate Cypress testing and perform browser automation testing with LambdaTest. Our cloud infrastructure has 3000+ desktop & mobile environments. Try for free.
What are WebElements in Selenium?
WebElements in Selenium are HTML elements that make up the web page’s content. Each HTML document consists of several HTML elements. An HTML element comprises a start tag and an end tag determining its position in the document. Between those HTML tags lies the content of the document.
Syntax:
content comes here
</end tag>
The WebElement interface in Selenium allows you to interact with both visible and invisible elements on a web page. In Selenium, all the methods return a value or no value (null/void). Similarly, the WebElement command returns either null/void or the element being searched for.
Shown below is the command of a WebElement in Selenium:
WebElement element = driver.findElement(By.id(“UserName“));
%[INVALID_URL]Subscribe to the LambdaTest YouTube Channel and get the latest tutorials around automation testing, Selenium testing, Playwright, Appium, and more.
Handling WebElements in Selenium Python
Selenium makes it simple for developers to automate web testing and help you handle WebElements in Selenium Python when performing Python automation testing. Here are some of the best approaches to handling WebElements in Selenium Python.
Alert Pop-Ups
Alerts and pop-ups are notification messages that alert a user about information or request authorization to carry out certain tasks. The appearance of an alert while performing Python web automation hinders the Selenium WebDriver from interacting with the webpage’s elements until the alert is dismissed. This leads to tests stalling or failing if the alerts or pop-ups are not handled.
When an alert is prompted, the alert pop-up window is displayed on the current webpage. Since the Selenium WebDriver’s context is on the current page, we need to switch the WebDriver’s focus to the new alert window.
This is done using the switch_to.alert() code command:
alert_object = driver.switch_to.alert
The other alert handling methods include:
- accept()
alert_object = Alert(driver)
alert_object.accept()
- dismiss()
The dismiss() method cancels the alert prompt.
alert_object = Alert(driver)
alert_object.dismiss()
- send_keys()
The send_keys() method accepts an argument, which will be entered in the alert pop-up.
alert_object = Alert(driver)
alert_object.send_keys("Okay")
- text()
The text() method retrieves and displays the text that is in the alert pop-up.
alert_object = Alert(driver)
print(alert_object.text)
Demonstration: How to handle an Alert in Selenium Python
Let us look at an example of a prompt alert and how we can handle it in Selenium Python.
Test Case:
To demonstrate how to handle an alert, we will use the example of the JavaScript Alert Box Demo from the LambdaTest Selenium Playground.
Go to the JavaScript Alert Box demo page.
Click on the Click Me button in the last JavaScript Alert Box page
Enter your name on the alert pop-up.
Click on the OK button.
Implementation (Test Case on the Chrome Browser):
Let us write a test script to handle a simple alert.
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options as ChromeOptions
def test_handling_simple_alert():
options = ChromeOptions()
options.browser_version = "108.0"
options.platform_name = "Windows 10"
lt_options = {};
lt_options["username"] = os.environ.get('LT_USERNAME');
lt_options["accessKey"] = os.environ.get('LT_ACCESS_KEY');
lt_options["build"] = "Handling Alerts";
lt_options["project"] = "Handling Alerts";
lt_options["name"] = "Handling Alerts";
lt_options["w3c"] = True;
lt_options["plugin"] = "python-python";
options.set_capability('LT:Options', lt_options);
# LambdaTest Profile username
user_name = os.environ.get('LT_USERNAME')
# LambdaTest Profile access_key
accesskey = os.environ.get('LT_ACCESS_KEY')
remote_url = "https://" + user_name + ":" + accesskey + "@hub.lambdatest.com/wd/hub"
driver = webdriver.Remote(remote_url, options=options)
driver.get("https://www.lambdatest.com/selenium-playground/javascript-alert-box-demo")
# Locate the button that prompts the alert
alert_button = WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="__next"]/section[4]/div/div/div[2]/div[3]/p[3]/button')))
alert_button.click()
# Switch the webdriver's control to the alert pop-up
alert_object = driver.switch_to.alert
# Show the alert message
print("This is the alert message: " + alert_object.text)
#Enter text into the Alert using send_keys()
alert_object.send_keys('Eugene')
print("Entered my name in the prompt box")
# Use the alert.accept() method to accept the alert
alert_object.accept()
print("Alert pop-up accepted by clicking the 'OK' button")
# End the driver session
driver.quit()
This Playwright browser testing tutorial will guide you through the setup of the Playwright framework, which will enable you to write end-to-end tests for your future projects.
Code Execution:
We then run the test script by running the following command in the terminal.
python -m pytest test_handling_alerts.py
Once the test is executed, the following output is displayed to show that the Selenium automated test was successful.
You can view the test logs in the build section from the LambdaTest Automation Dashboard.
Code Walkthrough:
Let us review the code for the test script we wrote in the section above.
Step 1: Import the Selenium libraries needed to run the test.
In this case, we import pytest, a testing framework for Python that enables us to write unit tests. The By query helps us locate web elements within the Document Object Model (DOM) using the find_element() method in Selenium.
The WebDriverWait class combined with expected_conditions allows us to specify the period of time the script should wait for a given condition to occur before continuing with the code. Finally, the Options (ChromeOptions) class customizes the ChromeDriver sessions and helps us perform operations like opening the Chrome browser.
Step 2: Generate the options using the LambdaTest Capabilities Generator to run the test in the Chrome browser.
Step 3: Create a remote_url variable that connects to the Remote Selenium Grid (@hub.lambdatest.com/wd/hub) using the username and accesskey listed on the LambdaTest Profile page. We then pass the options and the remote_url to instantiate the driver constructor.
Step 4: Open the LambdaTest Playground website and locate the button that prompts the alert using its XPath Selector in the browser inspect tools, then click it to initiate the alert.
When the Click Me button is clicked, the below window will be shown with the prompt alert.
The WebDriver’s focus is then switched to the alert prompt using the switch_to.alert method. Since the alert requires an input, we use the send_keys() method in Selenium to pass a value (in this case, your name), and then we accept the alert pop-up using the accept() method. The WebDriver session is then closed using the driver.quit() method.
Drag and Drop Operations
The drag and drop operation in Selenium Python allows users to use a mouse to move (drag) web elements from one location to another. In test automation using Selenium Python, the drag and drop function can be difficult to automate since it necessitates several actions and interactions.
The ActionChains class in Selenium Python provides methods to simulate the mouse events required for drag-and-drop. The methods are typically used to automate actions like mouse movements, keystrokes, context menu clicks, and mouse button events. The ActionChains object implements the class as a queue and calls the perform() method, which executes the actions together to prevent the test failure.
The syntax for creating an ActionChains object is:
from selenium.webdriver import ActionChains
action = ActionChains(driver)
The drag_and_drop(source, target) method performs the action of holding the left mouse button on the source element and releasing the mouse button at the target element.
action.drag_and_drop(source, target).perform()
Demonstration: How to perform a Drag-and-Drop Operation in Selenium Python
Let us look at how we can handle a drag-and-drop operation in Selenium using Python.
Test Case:
To implement drag and drop, we will use the example of Drag Drop Range Sliders from the LambdaTest Selenium Playground.
Navigate to the Drag Drop Range Sliders demo page.
Locate the drag pointer and drag it from 5 (source) to 50 (target)
Implementation (Test Case on the Chrome Browser):
import os
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver import ActionChains
def test_handling_drag_and_drop():
options = ChromeOptions()
options.browser_version = "106.0"
options.platform_name = "Windows 10"
lt_options = {};
lt_options["username"] = os.environ.get("LT_USERNAME");
lt_options["accessKey"] = os.environ.get("LT_ACCESS_KEY");
lt_options["visual"] = True;
lt_options["build"] = "Handling Drag & Drop";
lt_options["project"] = "Handling Drag & Drop";
lt_options["name"] = "Handling Drag & Drop";
lt_options["w3c"] = True;
lt_options["plugin"] = "python-python";
options.set_capability('LT:Options', lt_options);
# LambdaTest Profile username
user_name = os.environ.get('LT_USERNAME')
# LambdaTest Profile access_key
accesskey = os.environ.get('LT_ACCESS_KEY')
remote_url = "https://" + user_name + ":" + accesskey + "@hub.lambdatest.com/wd/hub"
driver = webdriver.Remote(remote_url, options=options)
driver.get("https://www.lambdatest.com/selenium-playground/drag-drop-range-sliders-demo")
source = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, "input[value='5']")))
print("I am dragging the mouse from: ", source.get_attribute("value"))
target = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, "input[value='50']")))
print("I'm dropping the mouse at: ", target.get_attribute("value"))
driver.implicitly_wait(10)
action = ActionChains(driver)
action.drag_and_drop(source, target).perform()
print("The mouse dragged from 5 to 50")
driver.close()
Code Execution:
Pass the following command in the command line to execute the test script.
python -m pytest test_handling_drag_and_drop.py
The test passes once it runs and displays the following output in the terminal.
In the LambdaTest Automation Dashboard, you can see the results of the test execution. You can also see the live recordings of the test with detailed reports and logs.
Do you need to gather more knowledge on testing web? LambdaTest is here to explain further.
Code Walkthrough:
Step 1: Import the Selenium libraries essential to the test script, including the ActionChains class that replicates mouse events for our test automation.
Step 2: Using the driver.get(url) method, we navigate to the URL where our automated test will simulate the drag and drop operation.
Step 3: Next, locate the source web element and the target elements the mouse will drag and drop onto. We use the elements’ CSS Selectors to locate them from the web browser’s inspect tools. The source element has an input value of 5, which will be moved to the target element, which has an input value of 50.
Locating the source element using the CSS Selector in the Browser Inspect Tools:
Locating the target element using the CSS Selector in Browser Inspect Tools:
Step 4: You then create an object of ActionChains and invoke drag_and_drop(source, target).perform() method to execute the mouse movement from 5 to 50 in the draggable slide.
Step 5: We finally close the webdriver session using the driver.close() method.
Selecting Multiple Values in Drop-Down Menus
A drop-down is a navigation element of a website that can be used in forms, search filter features and the Navbar. It allows the selection of one or more options from a list of options.
Choosing multiple values from a drop-down menu while running automated tests in Selenium Python can be a challenge for testers. Automating the selection of multiple choices is complex, as the test script needs to identify the drop-down element with its options and then search through the list of options before selecting them.
In some instances, the drop-down menu options are dynamically generated and rendered differently based on the web browser or operating system used. This can make writing robust and efficient scripts challenging.
Below are screenshots of the same drop-down menu in Chrome and Firefox browsers on a Windows OS.
Drop-down menu in a Chrome browser:
Drop-down menu in a Firefox browser:
The drop-down menu background color and font type are different in both browsers.
We use the Select class when testing with Selenium Python to address this issue. The Selenium WebDriver provides the Select class to handle single-select and multiple-select drop-downs with the < select >
HTML tag. In Selenium Python, there are several methods for selecting dropdowns.
We will implement the following three methods to select multiple values in our test scenario:
- select_by_index(index)
This method uses the get_attribute(“index”) of a < option >
tag to determine its index and return the matching option.This method uses the get_attribute(“index”) of a < option >
tag to determine its index and return the matching option.
multi_select = Select(dropdown)
multi_select.select_by_index(0)
- select_by_visible_text(text)
This method selects the options that display text that matches the argument passed. For example, the argument “Iowa” will select an option tag with < option > Iowa < /option >
.
multi_select = Select(dropdown)
multi_select.select_by_visible_text(“Iowa”)
- select_by_value(value)
This method selects the options whose value corresponds to the value argument.
For example:< option value=”AZ”> Arizona < /option >
multi_select = Select(dropdown)
multi_select.select_by_value(“AZ”)
Demonstration: How to handle Multiple Values in a Drop-Down Menu using Selenium Python
Let us look at how to automate the selection of multiple values in the following test case scenario.
Test Case:
Navigate to the jQuery Dropdown Search demo page.
Go to the Multi Select section on the web page to choose multiple states.
Select 3 states from the dropdown menu.
Print the states selected.
Implementation (Test Case on the Chrome Browser):
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.support.select import Select
def test_multiple_values_dropdown():
options = ChromeOptions()
options.browser_version = "107.0"
options.platform_name = "Windows 10"
lt_options = {};
lt_options["username"] = os.environ.get("LT_USERNAME");
lt_options["accessKey"] = os.environ.get("LT_ACCESS_KEY");
lt_options["build"] = "Handling Multiple Values Selection in Dropdowns";
lt_options["project"] = "Handling Multiple Values Selection in Dropdowns";
lt_options["name"] = "Handling Multiple Values Selection in Dropdowns";
lt_options["selenium_version"] = "4.0.0";
lt_options["w3c"] = True;
options.set_capability('LT:Options', lt_options);
# LambdaTest Profile username
user_name = os.environ.get('LT_USERNAME')
# LambdaTest Profile access_key
accesskey = os.environ.get('LT_ACCESS_KEY')
remote_url = "https://" + user_name + ":" + accesskey + "@hub.lambdatest.com/wd/hub"
driver = webdriver.Remote(remote_url, options=options)
driver.get("https://www.lambdatest.com/selenium-playground/jquery-dropdown-search-demo")
# Find the multiselect dropdown element in the page
dropdown = WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.XPATH, '//*[@id="__next"]/div/section[3]/div/div/div[2]/div[2]/div[2]/select')))
# Using the webdriver Select class to select multiple values
multi_select = Select(dropdown)
driver.implicitly_wait(3)
multi_select.select_by_index(0)
driver.implicitly_wait(3)
multi_select.select_by_value("AZ")
driver.implicitly_wait(3)
multi_select.select_by_visible_text("Iowa")
print("All selected values using the SELECT Class in the dropdown are: \n")
for option in multi_select.all_selected_options:
print(option.get_attribute('innerText'))
driver.close()
Code Execution:
Type the command below in the terminal to run the test script.
python -m pytest test_multiple_values_dropdowns.py
The test executes successfully and displays the three selected states as the output.
You can view the status of your successful test run on your LambdaTest Automation Dashboard.
Inspect web elements to help developers and testers to debug UI flaws or make modifications in HTML or CSS files. Learn how to inspect element on Mac-Book.
Code Walkthrough:
Step 1: In the test script above, we import the necessary Selenium libraries required to run the script, including the Select class that will automate the selection of multiple options from a drop-down.
Step 2: Navigate to the website where we will run the test script using the driver.get() method. Using the Explicit wait with WebDriverWait, we wait for the drop-down element to appear and then locate it using XPath.
Step 3: We create an instance of the Select class using the Select() method by passing the multi_select element as its argument. We select multiple values from the drop-down menu using the select_by_index(), select_by_value(), and select_by_visible_text() methods.
Step 4: Then, use all_select_options() to iterate through the selected options and print the individual options we chose. The option tag’s text string will be printed by the get_attribute(“innerText”) function.
Step 5: Finally, calling the driver.close() ends the driver session.
jQuery Date Pickers
When automating an airline or hotel website or filling up a form on a website, you might come across a date picker or calendar to pick dates or even time. The jQuery calendar is the most commonly used date picker control. These calendars significantly enhance the user experience by making choosing dates easier and more dynamic.
jQuery date pickers can pose a challenge when automating web applications using Selenium Python.
The date pickers could implement multiple date and time formats, making it challenging as the test implementation will need to be adjusted to match the calendar’s style and appearance. The calendar may also require navigation controls such as previous and next buttons to choose different months and years to select the dates. The calendar date pickers may also be rendered differently depending on the browser.
Booking.com datepicker in the Chrome browser:
Booking.com datepicker in Firefox browser:
Demonstration: How to handle a jQuery Calendar in Selenium Python
Let’s look at a scenario on how to automate a jQuery calendar in Selenium Python.
Test Case:
Navigate to the jQuery Date Picker demo page.
Go to the Date Range Picker.
In the From date picker field, select 05/10/2023 as the date.
In the To date picker field, select 06/25/2023 as the date.
Print the dates selected.
Implementation (Test Case on the Chrome Browser):
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def test_handling_jquey_datepicker():
options = ChromeOptions()
options.browser_version = "107.0"
options.platform_name = "Windows 10"
lt_options = {};
lt_options["username"] = os.environ.get('LT_USERNAME');
lt_options["accessKey"] = os.environ.get('LT_ACCESS_KEY');
lt_options["build"] = "Handling Date Pickers";
lt_options["project"] = "Handling Date Pickers";
lt_options["name"] = "Handling Date Pickers";
lt_options["w3c"] = True;
lt_options["plugin"] = "python-python";
options.set_capability('LT:Options', lt_options)
# LambdaTest Profile username
user_name = os.environ.get('LT_USERNAME')
# LambdaTest Profile access_key
accesskey = os.environ.get('LT_ACCESS_KEY')
remote_url = "https://" + user_name + ":" + accesskey + "@hub.lambdatest.com/wd/hub"
driver = webdriver.Remote(remote_url, options=options)
# Handling JQuery DatePicker
driver.get('https://www.lambdatest.com/selenium-playground/jquery-date-picker-demo')
# expected dates to be selected
from_date_target = '05/10/2023'
to_date_target = '06/25/2023'
from_date = '10'
to_date = '25'
# From date
# clicking on the from_date picker
from_date_picker = driver.find_element(By.XPATH, "//input[@id='from']")
from_date_picker.click()
from_month = driver.find_element(By.XPATH, "//select[@class='ui-datepicker-month']")
# We use the Select() method to select the target month we want
from_month_selected = Select(from_month)
from_month_selected.select_by_visible_text('May')
from_day = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH,"//td[not(contains(@class,'ui-datepicker-month'))]/a[text()='" + from_date + "']")))
from_day.click()
# To date
to_date_picker = driver.find_element(By.XPATH, "//input[@id='to']")
to_date_picker.click()
to_month = driver.find_element(By.XPATH, "//select[@class='ui-datepicker-month']")
to_month_selected = Select(to_month)
to_month_selected.select_by_visible_text('Jun')
to_day = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH,"//td[not(contains(@class,'ui-datepicker-month'))]/a[text()='" + to_date + "']")))
to_day.click()
# Assert the selected dates
expected_from_date = from_date_picker.get_attribute('value')
if expected_from_date == from_date_target:
print("From date selected:", expected_from_date)
expected_to_date = to_date_picker.get_attribute('value')
if expected_to_date == to_date_target:
print("To date selected:", expected_to_date)
driver.close()
Code Execution:
To run the test script above in the terminal, run the following command:
python -m pytest test_handling_datepickers.py
The test script executes successfully and will display the following output.
You can also view test results on the LambdaTest Dashboard.
Video recording of From date selection:
Video recording of To date selection:
Code Walkthrough:
Step 1: Import the Select class from Selenium WebDriver to help us implement the < select >
tag, which provides the helper methods with select and deselect options.
Step 2: Define the from_date target and to_date_target date targets that we want to select from the datepicker.
Step 3: The from_date_picker element is located using XPath in the Chrome Developer Tools and clicked to open the calendar.
Step 4: From the calendar, we locate from_month using XPath and select the month using the Select() method. In this instance, we select the month of May using the select_by_visible_text() method.
Step 5: Since we have specified the precise value of the from_date, the 10th day is located from the month using a dynamic XPath, and the contains() method. We then click on the day.
Given that the datepicker provides date range capability, the procedures implemented for the from_date are also applied to the to_date. The only difference comes from the months and locators used to locate the “from” and “to” dates. We selected June and the sixth day for the to_ date.
Step 6: Finally, we ascertain that the from_date_picker and the to_date_picker variables have the exact value we specified in the from_date_target and the to_date_target variables using the get_attribute(‘value’) method.
We store these values in the expected_from_date and expected_to_date variables and print the output.
Step 7: We then close the WebDriver session with the driver.close() method.
Mouse Hover Elements
A mouse hover action is an action taken when a user moves a mouse cursor over a designated part of a webpage, and it triggers a specific event. For example, in the Selenium eCommerce Playground website, hovering over a product element will show a sub-menu of a user’s actions, such as the “Add to Cart” function.
Mouse hover can also be used on banks’ websites to show different services the bank offers, as well as on hotel websites to zoom in on a location’s picture or add the location to likes.
Mouse hover on product item showing “Add to Cart” action:
Mouse hover on the bank website showing the bank’s services:
Hover elements can pose a challenge while writing automated tests using Selenium Python. Some elements are often hidden and only become visible when the mouse hovers over some other element, making it difficult to locate them using the standard find_element() method.
Additionally, hover events can be unstable as they depend on the mouse movement speed and the timing of triggering the hover event. In the case of slow internet speeds, the mouse cursor movements might lag. This may result in the tests being flaky.
To handle mouse hover actions, we implement the methods from the ActionChains class. The class methods will simulate the mouse movement.
Demonstration: How to handle Mouse Hover Actions in Selenium Python
Let us look at a test case scenario that requires handling a mouse hover action.
Test Case:
Navigate to the LambdaTest Selenium eCommerce Playground.
Go to product items and hover the mouse on the item.
Click on the Add to Cart button that hovers over the product item.
Print that the item has been added to the cart successfully.
Implementation (Test Case on the Chrome Browser):
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
def test_mouse_hover():
options = ChromeOptions()
options.browser_version = "107.0"
options.platform_name = "Windows 10"
lt_options = {};
lt_options["username"] = os.environ.get("LT_USERNAME");
lt_options["accessKey"] = os.environ.get("LT_ACCESS_KEY");
lt_options["build"] = "MouseHoverHandling";
lt_options["project"] = "MouseHoverHandling";
lt_options["name"] = "MouseHoverHandling";
lt_options["selenium_version"] = "4.0.0";
lt_options["w3c"] = True;
options.set_capability('LT:Options', lt_options);
# LambdaTest Profile username
user_name = os.environ.get('LT_USERNAME')
# LambdaTest Profile access_key
accesskey = os.environ.get('LT_ACCESS_KEY')
remote_url = "https://" + user_name + ":" + accesskey + "@hub.lambdatest.com/wd/hub"
driver = webdriver.Remote(remote_url, options=options)
driver.get("https://ecommerce-playground.lambdatest.io/")
driver.implicitly_wait(10)
# Find the element we want to hover
product_item = driver.find_element(By.XPATH, '//*[@id="mz-product-listing-image-37213259-0-0"]/div/div[1]/img')
# Create a sequence of actions through the ActionsChains class
driver.implicitly_wait(10)
actions = ActionChains(driver)
# Perform triggers the actions
actions.move_to_element(product_item).perform()
driver.implicitly_wait(10)
# find the add_to_cart element we want to click on the product elementa
add_to_cart = driver.find_element(By.CSS_SELECTOR, 'button[title="Add to Cart"]')
# The mouse will click the add_to_cart element to complete the sequence.
driver.implicitly_wait(10)
actions.click(add_to_cart)
print("Item moved to the cart")
driver.close()
Code Execution:
Type the following command in the terminal to run the test script.
python -m pytest test_mouse_hover.py
The test successfully executes on the terminal, displaying the output as shown below.
The test results can be viewed in the LambdaTest Dashboard.
Code Walkthrough:
Step 1: Import the ActionChains class from the Selenium WebDriver, which provides a variety of APIs for keyboard and mouse actions.
Step 2: Navigate to the Selenium eCommerce Playground website using the driver.get() method. We first locate a product element in the webpage using its XPath from the Chrome Browser’s Inspect Tools to display the hover effect.
Step 3: Using the ActionChains class, we create an object of the class and use the move_to_element() method with the product_item element as its parameter. The move_to_element() method moves the mouse to the middle of the element. Then apply the perform() method to implement the mouse action.
Once the mouse cursor is on the product_item element, we locate the add_to_cart button using its CSS Selector. The add_to_cart element becomes visible when the mouse hovers over the product_item and then clicks on it using the actions class object.
Step 4: We finally close the webdriver session using the driver.close() method.
Perform manual or automated cross browser test on 3000+ browsers online. Deploy and scale faster with the most powerful cross browser testing tool online.
AJAX Form Submission
AJAX forms are a challenge in automation testing using Selenium Python because of the asynchronous nature of AJAX calls. AJAX calls can be used in web apps to enable features such as autocomplete search, which displays results as you type, or infinite scrolling to fetch additional content in social media apps without reloading the page.
When you fill in and submit the traditional forms, the page reloads, and the refreshed page can be interacted with easily using Selenium. AJAX forms, on the other hand, do not require a page reload because the form data is delivered and handled asynchronously in the background. As new content is received from the server, a part of the web page’s DOM is updated rather than the entire DOM state changing. This can make it difficult to determine whether the form has completed processing and if the refreshed page content is accessible to be interacted with through Selenium.
To automate handling AJAX form submissions, we use the explicit wait functions to wait for the refreshed page to load before proceeding with the code. On the other hand, implicit waits are not recommended for handling AJAX form submissions because they do not wait for a specific form submission to complete before continuing with the test script. The test script will continue to execute without waiting for the request to complete. This causes the test to be flaky because of wait time issues.
Demonstration: How to handle AJAX Form Submission using Selenium Python
To demonstrate handling AJAX form submissions, we will use the AJAX contact form by Getform.io.
Test Case:
Navigate to the Getform CodePen URL.
Fill in the form details and click on the Submit button.
Wait for the submission response and print it.
Implementation (Test Case on the Chrome Browser):
import os
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.support.select import Select
def test_AJAX_forms():
options = ChromeOptions()
options.browser_version = "107.0"
options.platform_name = "Windows 10"
lt_options = {};
lt_options["username"] = os.environ.get("LT_USERNAME");
lt_options["accessKey"] = os.environ.get("LT_ACCESS_KEY");
lt_options["build"] = "Handling AJAX Forms";
lt_options["project"] = "Handling AJAX Forms";
lt_options["name"] = "Handling AJAX Forms";
lt_options["w3c"] = True;
lt_options["plugin"] = "python-python";
options.set_capability('LT:Options', lt_options);
# LambdaTest Profile username
user_name = os.environ.get('LT_USERNAME')
# LambdaTest Profile access_key
accesskey = os.environ.get('LT_ACCESS_KEY')
remote_url = "https://" + user_name + ":" + accesskey + "@hub.lambdatest.com/wd/hub"
driver = webdriver.Remote(remote_url, options=options)
driver.get("https://codepen.io/getform/pen/jRoexL")
# Get into the iFrame
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))
# Locate the Form
form = driver.find_element(By.XPATH, '//*[@id="AJAXForm"]')
# Identify the forms inputs and enter data through send_keys
email_element = form.find_element(By.XPATH, '//*[@id="exampleInputEmail1"]')
email_element.send_keys('youremail@gmail.com')
name_element = form.find_element(By.XPATH, '//*[@id="exampleInputName"]')
name_element.send_keys('yourname')
# Locate the dropdown
platform_element = Select(form.find_element(By.XPATH, '//*[@id="exampleFormControlSelect1"]'))
platform_element.select_by_visible_text('Github')
submit = form.find_element(By.XPATH, '//*[@id="AJAXForm"]/button')
submit.click()
# Wait for the AJAX request to complete
response = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//*[@id="AJAXForm"]/div[4]')))
print(response.text)
driver.quit()
Code Execution:
Let us run the test script in the terminal using the following command:
python -m pytest test_handling_AJAX_forms.py
The test executes successfully, and the terminal displays the form’s response.
We can view the test results in the LambdaTest Automation Dashboard.
Code Walkthrough:
Step 1: To get started with the automated testing of an AJAX form submission test scenario in Selenium Python, we import the necessary Selenium libraries, including WebDriverWait, and the expected conditions for the explicit wait. The explicit wait will enable the WebDriver to wait until the form submission returns the response, and it becomes visible in the DOM.
Step 2: We also import the Select class to handle the drop-down input menu in the form.
Step 3: The AJAX form is inside an iFrame, and the test script cannot continue to run until we switch the WebDriver’s context to the iFrame. In the Inspect Tool, the iFrame is identified by its TAG_NAME. We then switch to the iFrame using the driver.switch_to.frame() method with the iFrame element as its parameter.
Step 4: After switching to the iFrame, we locate the form using XPath from the Inspect Tools. After locating the email and name inputs, we use the send_keys() method to fill in the email and name details.
Step 5: The Select class we imported will select an option from the platform_element drop-down menu using the select_by_visible_text() method. Finally, click on the Submit button to submit the form details.
Step 6: After submitting the form, we use explicit wait to wait for the web page to load asynchronously until the response element is present in the DOM. Then print the response’s text.
Step 7: The driver.quit() closes the driver session.
Dynamic Page Elements
If an element in a web application has attributes such as Class, ID, or XPath that change when the web application is reloaded, such elements are known as dynamic web elements. For example, the login web element ID on the Facebook login page changes every time the page is reloaded.
In the below image, the login button ID is “u 0 5 aj.”
After the page is reloaded, the login button ID is now “u 0 5 Hg.”
Dynamic content can be challenging to automate with Selenium Python because it requires the automated test to identify and interact with the dynamic web elements. When a dynamic page element on a web page loads, not all elements are available immediately. When the WebDriver tries to interact with an element before it is present, it results in a NoSuchElementException.
Stale elements, on the other hand, are elements that are no longer attached to the web page’s DOM because the page has been reloaded or the element has been removed and replaced by another element. If the WebDriver tries to interact with a stale element, it results in a StaleElementReferenceException.
You can learn more about it through this blog on handling Errors and Exceptions in Selenium Python.
To address this challenge, automated test scripts need to implement explicit waits to wait until the page has finished loading before interacting with elements, as well as dynamic locators to locate and interact with elements that may not exist when the test is initially executed.
Demonstration: How to handle Dynamic Content with Selenium Python
Let us look at a test scenario to handle dynamic content on a website.
Test Case:
Navigate to the Internet HerokuApp link.
Click on the Start button and wait for the web page to load.
Print the response displayed.
Implementation (Test Case on the Chrome Browser):
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options as ChromeOptions
def test_dynamic_content():
options = ChromeOptions()
options.browser_version = "107.0"
options.platform_name = "Windows 10"
lt_options = {};
lt_options["username"] = os.environ.get("LT_USERNAME");
lt_options["accessKey"] = os.environ.get("LT_ACCESS_KEY");
lt_options["build"] = "Handling Dynamic Content";
lt_options["project"] = "Handling Dynamic Content";
lt_options["name"] = "Handling Dynamic Content";
lt_options["w3c"] = True;
lt_options["plugin"] = "python-python";
options.set_capability('LT:Options', lt_options);
# LambdaTest Profile username
user_name = os.environ.get('LT_USERNAME')
# LambdaTest Profile access_key
accesskey = os.environ.get('LT_ACCESS_KEY')
remote_url = "https://" + user_name + ":" + accesskey + "@hub.lambdatest.com/wd/hub"
driver = webdriver.Remote(remote_url, options=options)
driver.get("https://the-internet.herokuapp.com/dynamic_loading/2")
# locate the button start to dynamically
start_button = driver.find_element(By.XPATH, '//*[@id="start"]/button')
start_button.click()
# Waiting for the text to appear after clicking the start_button
finish_element = WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.XPATH, '//*[@id="finish"]/h4')))
print(finish_element.text)
driver.quit()
Code Execution:
Run the command below in the terminal to execute the test script.
python -m pytest test_handling_dynamic_content.py
Once the test runs, the following output will be displayed in the terminal.
We can see the status of the test execution and logs in the LambdaTest Automation Dashboard.
Code Walkthrough:
Step 1: Import the necessary Selenium libraries to run the test script, including the WebDriverWait class and expected_conditions that provide the explicit wait.
The WebDriver navigates to the website using the driver.get() method, locates the start_button element using its XPath in the Inspect Tools, and clicks on it.
Step 2: Using the WebDriverWait class, the WebDriver waits for the visibility of the response (finish_element) using an explicit wait. Once the element is present in the DOM, we print its text. The WebDriver will raise a TimeoutException, and the code will stop running if the finish_element is not visible in the DOM after the explicit wait period. The exception can be caught using a try-except block.
Step 3: Finally, the driver.close() method ends the WebDriver session.
Uploading Files
Uploading a file involves searching for a file at the required location or on your computer and uploading it to the website. This action can be done on specific websites, such as forms, document uploaders, and registration pages.
Uploading files can be challenging when performing automation tests with Selenium Python. The file dialog box that appears when you click the upload button is a native OS-level component and can be difficult to interact with programmatically, making it difficult to simulate the file selection process.
Additionally, different web applications might support various file formats for upload, and the same file upload element might behave differently depending on the file type. This can make writing reliable tests that function across several programs and file types difficult.
To handle this challenge, we will use the send_keys() method to upload the file. This approach is applicable to file upload elements with the tagname input and the type attribute set to the file. The send_keys() method will take the absolute path of the file as its argument and upload it to the web application we are testing.
Demonstration: How to Upload a File with Selenium Python
Let us look at a scenario for uploading a file when conducting automation testing with Selenium Python.
Test Case:
Navigate to the jQuery File Upload Demo page.
Locate and click on the Add files button on the webpage.
Choose a file you want to upload and click on Open.
Click on the Start button to upload the file.
Print that the file has been uploaded successfully.
Implementation (Test Case on a Chrome Browser):
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def test_file_uploads():
options = ChromeOptions()
options.browser_version = "107.0"
options.platform_name = "Windows 10"
lt_options = {};
lt_options["username"] = os.environ.get("LT_USERNAME");
lt_options["accessKey"] = os.environ.get("LT_ACCESS_KEY");
lt_options["build"] = "Handling File Upload";
lt_options["project"] = "Handling File Upload";
lt_options["name"] = "Handling File Upload";
lt_options["w3c"] = True;
lt_options["plugin"] = "python-python";
options.set_capability('LT:Options', lt_options);
# LambdaTest Profile username
user_name = os.environ.get('LT_USERNAME')
# LambdaTest Profile access_key
accesskey = os.environ.get('LT_ACCESS_KEY')
remote_url = "https://" + user_name + ":" + accesskey + "@hub.lambdatest.com/wd/hub"
driver = webdriver.Remote(remote_url, options=options)
# Access website to automate file upload
driver.get("https://blueimp.github.io/jQuery-File-Upload/")
# locate the file upload button on the page using XPATH
file_upload = WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.XPATH, "//input[@name='files[]']")))
# The Send Keys method will include the path for the file that will be uploaded.
file_upload.send_keys(r"C:\Users\Pictures\Saved Pictures\logo.jpg")
start_upload = WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.XPATH,'//*[@id="fileupload"]/table/tbody/tr/td[4]/button[2]')))
start_upload.click()
# is_displayed method is used to check if an element is visible to the user or not.
if driver.find_element(By.XPATH, '//*[@id="fileupload"]/table').is_displayed:
print("file uploaded successfully")
else:
print("File not uploaded")
driver.close()
Code Execution:
Let us run the test script in the terminal with the following command:
python -m pytest test_upload_files.py
The test executes successfully and returns the following output in the terminal.
The test execution status can be viewed on the LambdaTest Automation Dashboard.
Code Walkthrough:
Step 1: After creating an instance of the WebDriver, we navigate to the URL link using the driver.get() method. The file_upload element is then located using XPath. To upload a file, the send_keys() method takes an absolute path from the operating system’s directory, where the file is stored as its argument. The file_upload element has a tagname of input and a type attribute of the file; hence, we could use the send_keys() method to upload the file.
Step 2: We locate the start_upload button element by using an explicit wait to wait for the element to appear on the DOM after the file is selected from the file upload window. Once the button appears, we click on it to upload the file to the website.
Step 3: To check if the file uploaded is in the web application’s DOM, we use the is_displayed() method. If the uploaded file is present, we print that the file has been uploaded successfully. If not, the test prints that the file has not been uploaded. Finally, the WebDriver is closed using the driver.close() method.
If you want to automate user actions on a website to verify its functionality, commands for WebElements in Selenium Python play an important role. These commands can help you automate website testing in a more detailed manner. It’s recommended to run Selenium tests on real browsers, and operating systems will help you get accurate results.
Digital experience testing platforms like LambdaTest enables developers and QA to perform automated Selenium testing using Python on an online browser farm of 3000+ real browsers and OS combinations. LambdaTest offers support for different Python testing frameworks, including pytest, Robot, Behave, and more. In addition, you can perform parallel test execution to expedite your software release cycle.
Test your native, hybrid, and web apps across all legacy and latest mobile operating systems on the most powerful online Android emulator.
Conclusion
In this blog on WebElements in Selenium Python, we have demonstrated different ways to handle WebElements in Selenium Python. These include handling alert pop-ups, drag-and-drop operations, jQuery datepickers, hover elements, AJAX forms, etc. We have also looked at the approaches to handle them, such as the use of explicit waits, the ActionChains class, Select, and send_keys methods.
Subscribe to my newsletter
Read articles from Eugene Kwaka directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by