Usage of DC automated testing with Python: A Step-by-Step Selenium Tutorial for 'Hello World'
Selenium is a powerful tool for web automation, and when combined with Python, it becomes an easy-to-use yet efficient framework for automating tasks on web applications. In this tutorial, we will walk you through automating a simple ‘Hello World’ task on Jira Data Center (DC) using Selenium in Python. We will cover how to detect web elements, execute JavaScript code, and even debug your automation script. Let’s dive in!
Prerequisites:
Python 3.x installed.
Selenium WebDriver for Python.
A WebDriver (like ChromeDriver) for the browser you want to automate.
Access to a Jira DC instance (either a local or cloud setup).
Step 1: Check if Python 3.x is Installed
To verify if Python 3.x is installed, open a terminal or command prompt and type:
python --version
If Python is installed, you should see a version number starting with 3 (e.g.,
Python 3.9.1
).If it’s not installed, download and install it from the Python website.
Step 2: Check if Selenium is Installed
To verify if the Selenium WebDriver package for Python is installed, run:
pip show selenium
This command will display details about Selenium if it’s installed. You’ll see the version and location if it’s available.
If Selenium is not installed, you can install it with:
pip install selenium
Step 3: Check if a WebDriver (like ChromeDriver) is Installed and in PATH
The WebDriver (e.g., ChromeDriver, GeckoDriver) should be installed and accessible in your system’s PATH. Here’s how you can check:
For ChromeDriver:
Open a terminal and run:
chromedriver --version
If ChromeDriver is properly installed and in the PATH, this command will display its version (e.g.,
ChromeDriver 91.0.4472.19
).If it’s not installed, download the appropriate version from the ChromeDriver website.
For Other Browsers:
Follow the same process but with the command specific to your browser (e.g., geckodriver --version
for Firefox).
Tip: If the WebDriver is downloaded but not in your PATH, you can specify the path directly in your script like this:
from selenium import webdriver
driver = webdriver.Chrome(executable_path='/path/to/chromedriver')
Step 4: Verify Access to Jira DC Instance
To confirm access to your Jira DC instance:
Open a browser and navigate to your Jira instance URL.
Log in manually to ensure credentials are correct.
If all checks are successful, you’re ready to start automating with Selenium.
Step 5: Setting Up the Basic Selenium Script
In this section, we will create a basic Selenium script that logs into Jira and performs a "Hello World" operation (for instance, navigating to the Jira dashboard).
Step 6: Create a Python Script
Open a Text Editor: Open your preferred text editor or IDE (like Visual Studio Code, PyCharm, or even Notepad).
Write Your Selenium Script: Here’s an example script that opens a webpage and runs some JavaScript:
from selenium import webdriver
from util.conf import JIRA_SETTINGS
from selenium_ui.jira.pages.pages import Login
from selenium_ui.conftest import print_timing
import random
import time
# Constants
JIRA_URL = f"{JIRA_SETTINGS.server_url}"
@print_timing("selenium_app_custom_action")
def app_specific_action(jira_webdriver, jira_datasets):
admin_login = JIRA_SETTINGS.admin_login
admin_password = JIRA_SETTINGS.admin_password
# To run action as specific user uncomment code bellow.
# NOTE: If app_specific_action is running as specific user, make sure that app_specific_action is running
# just before test_2_selenium_z_log_out action
@print_timing("selenium_app_specific_user_login")
def measure():
@print_timing("login")
def app_specific_user_login(username=admin_login, password=admin_password):
login_page = Login(jira_webdriver)
login_page.delete_all_cookies()
login_page.go_to()
login_page.set_credentials(username=username, password=password)
if login_page.is_first_login():
login_page.first_login_setup()
if login_page.is_first_login_second_page():
login_page.first_login_second_page_setup()
login_page.wait_for_page_loaded()
app_specific_user_login(username=admin_login, password=admin_password) # Call the function to perform the login
time.sleep(3)
# At this point, you're logged into Jira and can automate further interactions
print("Hello World! You are now logged into Jira DC.")
@print_timing("selenium_view_issue_page")
def view_issue():
issue_key = random.choice(jira_datasets['issues'])[0]
print(f"Opening issue: {issue_key}")
jira_webdriver.get(f"{JIRA_URL}/browse/{issue_key}")
print("Waiting for page to load...")
time.sleep(3)
view_issue()
measure()
You can find the complete script for this tutorial in the Bitbucket repository: Jira Selenium Automation Code
Let's break down the Python script, line by line, to explain what each part does.
Code Explanation :-
from selenium import webdriver
Imports the
webdriver
module from theselenium
package: This module allows you to control a web browser (such as Chrome, Firefox, etc.) through Python code.
from util.conf import JIRA_SETTINGS
Imports the
JIRA_SETTINGS
configuration from theutil.conf
module: This provides access to settings such as the Jira server URL, admin login credentials, and other configuration parameters needed for the automation.
from selenium_ui.jira.pages.pages import Login
Imports the
Login
class from thepages
module: This class handles interactions with the Jira login page. It contains methods for actions like deleting cookies, navigating to the login page, and entering login credentials.
from selenium_ui.conftest import print_timing
Imports the
print_timing
decorator fromconftest
: This decorator is used to measure the time taken by a function to execute and prints the result. It helps in performance monitoring and profiling the code.
import random
Imports the
random
module: This module is used to generate random numbers or choose random elements, like randomly selecting a Jira issue from a list.
import time
Imports the
time
module: This module provides various time-related functions, includingsleep()
which is used to pause the execution of the code for a specified number of seconds.
Constants
JIRA_URL = f"{JIRA_SETTINGS.server_url}"
Sets the Jira base URL: This formats the Jira server URL stored in the
JIRA_SETTINGS
configuration into a usable string that will be used to build URLs for accessing specific pages on the Jira platform.
Main Functionality
@print_timing("selenium_app_custom_action")
Decorates the
app_specific_action
function: This decorator measures the time it takes for theapp_specific_action
function to run and logs that time with the label"selenium_app_custom_action"
.
def app_specific_action(jira_webdriver, jira_datasets):
Defines the
app_specific_action
function: This function performs specific actions in the Jira application using the providedjira_webdriver
(the Selenium WebDriver instance) andjira_datasets
(which likely contains issue data for use in tests).
admin_login = JIRA_SETTINGS.admin_login
admin_password = JIRA_SETTINGS.admin_password
Retrieves admin credentials from
JIRA_SETTINGS
: These variables store the username and password for the Jira admin account, used for login purposes during the automation.
Nested Functions
User Login
@print_timing("selenium_app_specific_user_login")
Decorates the
measure
function: This decorator measures and logs the execution time of themeasure
function with the label"selenium_app_specific_user_login"
.
def measure():
Defines the
measure
function: This function encapsulates the user login process and other actions (like opening an issue page), measuring the time it takes to perform these tasks.
@print_timing("login")
Decorates the
app_specific_user_login
function: This decorator tracks the time it takes to execute the login process and logs that time with the label"login"
.
def app_specific_user_login(username=admin_login, password=admin_password):
Defines the
app_specific_user_login
function: This function handles logging in to Jira by accepting a username and password (with default values set to the admin credentials).
login_page = Login(jira_webdriver)
Creates an instance of the
Login
page: TheLogin
class is instantiated, which enables interaction with the login page through the providedjira_webdriver
.
login_page.delete_all_cookies()
Deletes all browser cookies: This ensures that the login process starts fresh, avoiding any potential interference from existing cookies (e.g., previous sessions).
login_page.go_to()
Navigates to the Jira login page: This method directs the browser to the URL for Jira's login page.
login_page.set_credentials(username=username, password=password)
Enters the login credentials: This method sets the username and password on the login form, preparing it for submission.
if login_page.is_first_login():
login_page.first_login_setup()
if login_page.is_first_login_second_page():
login_page.first_login_second_page_setup()
Handles first-time login setup: If it’s the first time the user logs in, additional setup steps (like configuring preferences or accepting terms) are performed using methods like
first_login_setup()
andfirst_login_second_page_setup()
.
login_page.wait_for_page_loaded()
Waits for the login page to fully load: This ensures that the page is fully ready before proceeding with further actions.
app_specific_user_login(username=admin_login, password=admin_password)
Calls the
app_specific_user_login
function: This executes the login function with the admin credentials to log into Jira.
time.sleep(3)
Pauses for 3 seconds: This gives the page a moment to load after login before proceeding with the next action.
print("Hello World! You are now logged into Jira DC.")
Prints a confirmation message: A message indicating that the user has successfully logged in to Jira.
View Issue
@print_timing("selenium_view_issue_page")
Decorates the
view_issue
function: This decorator measures and logs the time taken to open a Jira issue page.
def view_issue():
Defines the
view_issue
function: This function is responsible for selecting a random issue and viewing it in Jira.
issue_key = random.choice(jira_datasets['issues'])[0]
Selects a random issue key: Randomly picks an issue key from the
jira_datasets['issues']
list for further interaction.
print(f"Opening issue: {issue_key}")
Logs the issue being opened: Prints the issue key of the randomly selected Jira issue.
jira_webdriver.get(f"{JIRA_URL}/browse/{issue_key}")
Navigates to the issue page: Uses the Selenium WebDriver to navigate to the issue's page using the constructed URL (
JIRA_URL + /browse/{issue_key}
).
print("Waiting for page to load...")
Logs a message indicating that the issue page is loading: This lets the user know that the script is waiting for the page to load.
time.sleep(3)
Pauses for 3 seconds: Gives the page time to load before continuing.
view_issue()
Calls the
view_issue
function: This performs the task of viewing the randomly selected issue.
Execution Order
measure()
Calls the
measure
function: This starts the execution of the login process and viewing the issue.
Step 7: Detecting Web Elements in Selenium
Selenium provides various ways to detect and interact with web elements. These methods are crucial for automating any web-based tasks. Here’s a breakdown of the commonly used element detection strategies:
By ID:
driver.find_element_by_id("element_id")
By Name:
driver.find_element_by_name("element_name")
By XPath:
driver.find_element_by_xpath("//input[@name='q']")
By Class Name:
driver.find_element_by_class_name("class_name")
By CSS Selector:
driver.find_element_by_css_selector("div.classname > input")
For example, if you need to click on the Jira dashboard menu item, you might use something like:
dashboard_menu = driver.find_element_by_id("home_link")
dashboard_menu.click()
Step 8: Running JavaScript in Selenium
Sometimes, Selenium doesn’t directly support certain actions, and this is where executing JavaScript can be useful. You can run JavaScript code using the execute_script
method.
For example, scrolling the page to a certain element:
element = driver.find_element_by_id("some_element_id")
driver.execute_script("arguments[0].scrollIntoView(true);", element)
Or executing a custom JavaScript function:
driver.execute_script("alert('Hello from Selenium!');")
Step 9: Handling Delays and Waits
Automation can fail if the script interacts with elements before they fully load. There are two main ways to handle these delays:
Explicit Waits: Wait until a specific condition is met before proceeding.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "element_id"))
)
Implicit Waits: Define a default wait time for all elements.
driver.implicitly_wait(10)
Step 10: Debugging Selenium Scripts
Debugging Selenium scripts can be tricky, but there are a few strategies you can use to make the process easier:
Use
print()
Statements: Print intermediate results to track where the script is failing.
print("Attempting to find login button...")
Pause the Script: You can manually pause the script at any point to inspect the web page or element status.
input("Press Enter to continue...")
Screenshot on Failure: Capture a screenshot if an exception occurs.
driver.save_screenshot('error.png')
Logging: Use Python’s logging library to track events with more granularity.
import logging logging.basicConfig(level=logging.DEBUG)
Step 11: Closing the WebDriver
Once your script has completed its task, you should always ensure that the browser closes properly:
driver.quit()
This releases the WebDriver resources and closes the browser.
Step 12: Output
Conclusion
You’ve just created a simple Selenium automation script using Python to log in to Jira DC, run a "Hello World" action, and handle various other operations like detecting elements, running JavaScript, and debugging. With this foundational knowledge, you can automate a wide range of tasks in Jira or any other web-based system.