Use Selenium for Test Login page with Python
UI Testing (User Interface Testing) is a technique that ensures the UI of a website or mobile application is user-friendly and meets the expected customer or end-user requirements. It validates the visual design and layout, and functionality of the user interface to make sure it performs as intended.
Why is UI Testing important?
A website’s average size has increased over time. As websites grow in size, they now contain hundreds of pages. In addition, a single page contains hundreds of elements required to create a complete website.
This creates a huge load on the server that fetches the website. A slow website is not a good sign for any web developer. The testing of this scenario also falls under UI testing and can undoubtedly improve performance.
According to a survey by Google, 53% of users abandon tasks that take longer than 3 seconds to load. You can reduce this delay by optimizing JavaScript and CSS. It is, therefore, necessary to test the user interface to improve the website’s performance.
Benefits of UI Testing (User Interface Testing)
In this UI testing tutorial, let’s look at some of the benefits of running user-interface tests for your applications.
- It tests the application’s UI from the user’s perspective.
- It helps you ensure cross browser compatibility of different UI components like brand image, buttons, checkboxes, colors, and other design aspects.
- Enhance your product’s stability and quality.
- Automated UI testing is more cost-effective and faster than manual UI testing.
- UI Automation testing expands your test coverage and enables faster debugging.
- Identify and fix errors in the back-end that help testers improve product or application’s performance.
- Conducting UI testing ensures a good customer experience with your product.
Installation Selenium
Selenium Python bindings provides a simple API to write functional/acceptance tests using Selenium WebDriver. Through Selenium Python API you can access all functionalities of Selenium WebDriver in an intuitive way.
Selenium Python bindings provide a convenient API to access Selenium WebDrivers like Firefox, Ie, Chrome, Remote etc. The current supported Python versions are 3.5 and above.
This documentation explains Selenium 2 WebDriver API. Selenium 1 / Selenium RC API is not covered here.
1.2. Installing Python bindings for Selenium
Use pip to install the selenium package. Python 3 has pip available in the standard library. Using pip, you can install selenium like this:
pip install selenium
You may consider using virtualenv to create isolated Python environments. Python 3 has venv which is almost the same as virtualenv.
You can also download Python bindings for Selenium from the PyPI page for selenium package. and install manually.
1.3. Instructions for Windows users
- Install Python 3 using the MSI available in python.org download page.
- Start a command prompt using the
cmd.exe
program and run thepip
command as given below to install selenium.
- C:\Python39\Scripts\pip.exe install selenium
Now you can run your test scripts using Python. For example, if you have created a Selenium based script and saved it inside C:\my_selenium_script.py
, you can run it like this:
C:\Python39\python.exe C:\my_selenium_script.py
1.4. Installing from Git sources
To build Selenium Python from the source code, clone the official repository. It contains the source code for all official Selenium flavors, like Python, Java, Ruby and others. The Python code resides in the /py
directory. To build, you will also need the Bazel build system.Currently, as Selenium gets near to the 4.0.0 release, it requires Bazel 3.2.0 (Install instructions), even though 3.3.0 is already available.
To build a Wheel from the sources, run the following command from the repository root:
bazel //py:selenium-wheel
This command will prepare the source code with some preprocessed JS files needed by some webdriver modules and build the .whl
package inside the ./bazel-bin/py/
directory. Afterwards, you can use pip
to install it.
1.5. Drivers
Selenium requires a driver to interface with the chosen browser. Firefox, for example, requires geckodriver, which needs to be installed before the below examples can be run. Make sure it’s in your PATH, e. g., place it in /usr/bin or /usr/local/bin.
Failure to observe this step will give you an error selenium.common.exceptions.WebDriverException: Message: ‘geckodriver’ executable needs to be in PATH.
Other supported browsers will have their own drivers available. Links to some of the more popular browser drivers follow.
Chrome: https://sites.google.com/chromium.org/driver/ Edge: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ Firefox: https://github.com/mozilla/geckodriver/releases Safari: https://webkit.org/blog/6900/webdriver-support-in-safari-10/
For more information about driver installation, please refer the official documentation.
Login Sample with Selenium
import time
import math
from selenium import webdriver
from selenium.webdriver.common.by import By
digiUser = '' # digikala mobile or username
digiPassword = '' # digikala password
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.digikala.com/users/login/?backUrl=/') # digkala login page
time.sleep(5)
driver.find_element(by=By.NAME, value='username').send_keys(digiUser) # enter username
driver.find_element(by=By.TAG_NAME, value='form').submit()
time.sleep(5)
driver.find_element(by=By.NAME, value='password').send_keys(digiPassword) # enter password
driver.find_element(by=By.TAG_NAME, value='form').submit()
time.sleep(5)
There are various strategies to locate elements in a page. You can use the most appropriate one for your case. Selenium provides the following method to locate elements in a page:
- find_element
To find multiple elements (these methods will return a list):
- find_elements
Example usage:
from selenium.webdriver.common.by import By
driver.find_element(By.XPATH, '//button[text()="Some text"]')
driver.find_elements(By.XPATH, '//button')
The attributes available for the By class are used to locate elements on a page. These are the attributes available for By class:
ID = "id"
NAME = "name"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"
The ‘By’ class is used to specify which attribute is used to locate elements on a page. These are the various ways the attributes are used to locate elements on a page:
find_element(By.ID, "id")
find_element(By.NAME, "name")
find_element(By.XPATH, "xpath")
find_element(By.LINK_TEXT, "link text")
find_element(By.PARTIAL_LINK_TEXT, "partial link text")
find_element(By.TAG_NAME, "tag name")
find_element(By.CLASS_NAME, "class name")
find_element(By.CSS_SELECTOR, "css selector")
If you want to locate several elements with the same attribute replace find_element with find_elements.
Locating by Id
Use this when you know the id attribute of an element. With this strategy, the first element with a matching id attribute will be returned. If no element has a matching id attribute, a NoSuchElementException
will be raised.
For instance, consider this page source:
<html>
<body>
<form id="loginForm">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="continue" type="submit" value="Login" />
</form>
</body>
</html>
The form element can be located like this:
login_form = driver.find_element(By.ID, 'loginForm')
Locating by Name
Use this when you know the name attribute of an element. With this strategy, the first element with a matching name attribute will be returned. If no element has a matching name attribute, a NoSuchElementException
will be raised.
For instance, consider this page source:
<html>
<body>
<form id="loginForm">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="continue" type="submit" value="Login" />
<input name="continue" type="button" value="Clear" />
</form>
</body>
</html>
The username & password elements can be located like this:
username = driver.find_element(By.NAME, 'username')
password = driver.find_element(By.NAME, 'password')
This will give the “Login” button as it occurs before the “Clear” button:
continue = driver.find_element(By.NAME, 'continue')
Locating by XPath
XPath is the language used for locating nodes in an XML document. As HTML can be an implementation of XML (XHTML), Selenium users can leverage this powerful language to target elements in their web applications. XPath supports the simple methods of locating by id or name attributes and extends them by opening up all sorts of new possibilities such as locating the third checkbox on the page.
One of the main reasons for using XPath is when you don’t have a suitable id or name attribute for the element you wish to locate. You can use XPath to either locate the element in absolute terms (not advised), or relative to an element that does have an id or name attribute. XPath locators can also be used to specify elements via attributes other than id and name.
Absolute XPaths contain the location of all elements from the root (html) and as a result are likely to fail with only the slightest adjustment to the application. By finding a nearby element with an id or name attribute (ideally a parent element) you can locate your target element based on the relationship. This is much less likely to change and can make your tests more robust.
For instance, consider this page source:
<html>
<body>
<form id="loginForm">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="continue" type="submit" value="Login" />
<input name="continue" type="button" value="Clear" />
</form>
</body>
</html>
The form elements can be located like this:
login_form = driver.find_element(By.XPATH, "/html/body/form[1]")
login_form = driver.find_element(By.XPATH, "//form[1]")
login_form = driver.find_element(By.XPATH, "//form[@id='loginForm']")
- Absolute path (would break if the HTML was changed only slightly)
- First form element in the HTML
- The form element with attribute id set to loginForm
The username element can be located like this:
username = driver.find_element(By.XPATH, "//form[input/@name='username']")
username = driver.find_element(By.XPATH, "//form[@id='loginForm']/input[1]")
username = driver.find_element(By.XPATH, "//input[@name='username']")
- First form element with an input child element with name set to username
- First input child element of the form element with attribute id set to loginForm
- First input element with attribute name set to username
The “Clear” button element can be located like this:
clear_button = driver.find_element(By.XPATH, "//input[@name='continue'][@type='button']")
clear_button = driver.find_element(By.XPATH, "//form[@id='loginForm']/input[4]")
- Input with attribute name set to continue and attribute type set to button
- Fourth input child element of the form element with attribute id set to loginForm
These examples cover some basics, but in order to learn more, the following references are recommended:
- W3Schools XPath Tutorial
- W3C XPath Recommendation
- XPath Tutorial — with interactive examples.
Here is a couple of very useful Add-ons that can assist in discovering the XPath of an element:
- xPath Finder — Plugin to get the elements xPath.
- XPath Helper — for Google Chrome
Locating Hyperlinks by Link Text
Use this when you know the link text used within an anchor tag. With this strategy, the first element with the link text matching the provided value will be returned. If no element has a matching link text attribute, a NoSuchElementException
will be raised.
For instance, consider this page source:
<html>
<body>
<p>Are you sure you want to do this?</p>
<a href="continue.html">Continue</a>
<a href="cancel.html">Cancel</a>
</body>
</html>
The continue.html link can be located like this:
continue_link = driver.find_element(By.LINK_TEXT, 'Continue')
continue_link = driver.find_element(By.PARTIAL_LINK_TEXT, 'Conti')
Locating Elements by Tag Name
Use this when you want to locate an element by tag name. With this strategy, the first element with the given tag name will be returned. If no element has a matching tag name, a NoSuchElementException
will be raised.
For instance, consider this page source:
<html>
<body>
<h1>Welcome</h1>
<p>Site content goes here.</p>
</body>
</html>
The heading (h1) element can be located like this:
heading1 = driver.find_element(By.TAG_NAME, 'h1')
4.6. Locating Elements by Class Name
Use this when you want to locate an element by class name. With this strategy, the first element with the matching class name attribute will be returned. If no element has a matching class name attribute, a NoSuchElementException
will be raised.
For instance, consider this page source:
<html>
<body>
<p class="content">Site content goes here.</p>
</body>
</html>
The “p” element can be located like this:
content = driver.find_element(By.CLASS_NAME, 'content')
4.7. Locating Elements by CSS Selectors
Use this when you want to locate an element using CSS selector syntax. With this strategy, the first element matching the given CSS selector will be returned. If no element matches the provided CSS selector, a NoSuchElementException
will be raised.
For instance, consider this page source:
<html>
<body>
<p class="content">Site content goes here.</p>
</body>
</html>
The “p” element can be located like this:
content = driver.find_element(By.CSS_SELECTOR, 'p.content')
Sauce Labs has good documentation on CSS selectors.