Start a Chrome Browser
- Selenium webdriver does not invoke browser directly
- There is chrome driver service work as an agent between the webdriver and the browser. This service invoke the chrome browser.
- For every version of Chrome browser, there exist a corresponding Chrome driver.
- Selenium version 4 onwards, it support downloading the corresponding Chrome driver on invoking webdriver.Chrome(). Not require to download manually.
- It first check the Chrome version in your machine and download the corresponding Chrome driver from internet.
- But in following instances there could be issue with the above approach –
- Your org has strict VPN rule which restrict downloading from internet.
- Browser version in your machine is outdate. or for any reason it could not find the corresponding driver version.
- So for safer side you download the driver yourself.
# Selenium download the corresponding Chrome driver
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("headless")
driver = webdriver.Chrome(options=option)
driver.get(“url”)
driver.maximize_window()
assert driver.title == “ABC”
assert driver.current_url = “url”
#manually downloaded corresponding Chrome driver
from selenium import webdriver
from senenium.webdriver.chrome.service import Service
service = Service(“path of the chrome driver”)
driver = webdriver.Chrome(service=service, options=options)
driver.get(“url”)
# Firefox - Get gecko driver
driver = webdriber.Firefox()
# Microsoft Edge - Get Edge driver
driver = webdriber.Edge()
Locators
Ask: Enter your name in the name field and click submit. Check the success message after the submit.
CSS Selector Syntax
- tagname[attribute=‘value’]
- #id-name
- .class-name
- If multiple elements are matching locate the element using CSS index e.g(tagname[attribute=‘value’]):nth-element(3)
- If attribute is not defined for a tag you can traverse from parent to child e.g parent-tagname div[2] input
- CSS is same like XPATH just replace // or / with space
- Say the attribute of a tag is very large, we can use regualar expression instead of writing the entire attribute value
XPATH Selector Syntax
- //tagname[@attribute=‘value’]
- If multiple elements are matching locate the element using XPATH index e.g (//tagname[@type=’text’])[3] # Select the 3rd index match
- If attribute is not defined for a tag you can traverse from parent to child e.g //parent-tagname/div[2]/input
One of the helpful Chrome extension is SelectorHub. The extension can be used to check if the CSS selector or XPATH is pointing to the right element
Click Me
Success “The form submitted”
#Name selector
from selenium.webdriver.common.by import By
driver.find_element(By.NAME, “my_name”).send_keys(“”)
# Clear what you have written in the field
driver.find_element(By.NAME, “my_name”).clear()
#ID locator
from selenium.webdriver.common.by import By
driver.find_element(By.ID, “name_id”).send_keys(“”)
#CSS Selector
driver.find_element(By.CSS_SELECTOR,”input[type=‘submit’]”).click()
#CSS_SELECTOR Move from parent to child element
driver.find_element(By.CSS_SELECTOR,”form div:nth-child(2) input']”).send_keys(“”)
# CSS_SELECTOR with our without regualr expression
river.find_element(By.CSS_SELECTOR,”a[href='https://playground.for.shool.kids.com']").click()
river.find_element(By.CSS_SELECTOR,”a[href*='kids']").click()
# XPATH with our without regualr expression
river.find_element(By.XPATH,”//a[@href='https://playground.for.shool.kids.com']").click()
river.find_element(By.XPATH,”//a[contains(@href,'kids')]").click()
#XPATH Selector
driver.find_element(By.XPATH,”//input[@type=‘submit’]”).click()
#XPATH Move from parent to child element
driver.find_element(By.XPATH,”//form/div[1]/input']”).send_keys(“”)
#Class locator
# “.text” it will capture the text
message = driver.find_element(By.CLASS_NAME, “alert-success”).text
assert “Success” in message
#Capture by Link text. Condition the text has to be link i.e
message = driver.find_element(By.LINK_TEXT, "Click ME").click()
#Capture by Partial Link text
message = driver.find_element(By.PARTIAL_LINK_TEXT, "Click").click()
# Select element with text. When the text is not a Link
driver.find_element(By.XPATH,”//button[text()='Submit']").click()
Static and Dynamica Drop Down
HTML has two types of drop down:
Static Dropdown – Here the drop down is under the select tags. Which has static set of options user need to select from it. Selenium has a class called select() inside this provide the locator of the dropdown block.
Dynamic or Auto suggestive Dropdown – Here user need to type some characters in the field. Depending on the characters types corresponding values will appear in the drop down.
- goto the field and enter first three letters
- all corresponding words will appear in the drop down within 2 secs. So wait for 2secs
- Either we can locate one of the option using it’s attributes (id/class/type) and click
- But the problem with the above approach is, as it is dynamic it’s location might change when more options get added.
- So the best way is to check each and every options and select the match. For this we will use find_elements() instead of find_element()
import selenium.webdrive.support.select.Select
# Find options in a static dropdown
dropdown = Select(driver.find_element(By.ID, “gender_id"))
#dropdown is the object of the Select class
dropdown.select_by_index(0)
dropdown.select_by_visible_text("Female")
dropdown.select_by_value("male")
# Auto suggestive dropdown :
driver.find_element(By.ID, “input_field_id").send_keys("man")
time.sleep(2)
all_options = find_elements(By.CSS_SELECTOR, "li[class='class_name'] a")
for opt in all_options:
if opt.text == "mango"
opt.click()
break
# verify mango appears in the input field
# The following will fail. As "text" can only capture attributes which are loaded during the page load. But in this case mango came to the field after selecting the option i.e dynamically
driver.find_element(By.ID, “input_field_id").text == "mango"
#so instead of "text" use "get_attribute"
assert driver.find_element(By.ID, “input_field_id").get_attribute('value') == "mango"
Handling Checkbox and Radio Button
all_checkboxes = find_elements(By.XPATH, "//input[@type='checkbox']")
for box in all_checkboxes:
if box.get_attribute('value') == "option2"
box.click
assert box.is_selected()
break
all_radios = find_elements(By.XPATH, "//input[@type='radio']")
for rad in all_radios:
if rad.get_attribute('value') == "roption2"
rad.click
assert rad.is_selected()
break
# Similar to is_selected() one more method is there called is_displayed()
Handling Alerts
- Alert is JS popup does not have any html code. But Selenium can only locate html tags.
- It needs to switch to alert mode.
# Switch to the alert mode
alert = drive.switch_to.alert
# Capture the text in the pop up
print(alert.text)
# CLick OK button
alert.accept()
# CLick Cancel button
alert.dismiss()
Handling Mouse Hover
- Not click just hover the mouse on an element
- Use ActionChains Class
- At the end of the Action we need to use perform() method. Then all actions chains will be executed
from selenium.webdriver import ActionChains
from selenium import webdriver
driver = webdriver.Chrome()
action = ActionChains(driver)
#right click
action.context_click(driver.find_element(By.NAME, "name"))
#mouse hover
action.move_to_element(driver.find_element(By.ID, "mousehover")).perform()
Move Control to New Tab or Window
- Open an url and click on a link
- A new tab or window open
- The scope of the selenium is still with the parent window
- Need to transfer the scope to new window or tab (i.e lets called it child tab)
- After performing the operation transfer the scope back to parent window.
- First window’s index is 0 and the window open upon click have index 1
driver.get(“url name”)
# The click operation will open a link in new window
driver.find_element(By.LINK_TEXT, “Click Here”).click()
# Return all open windows in the current session in the list format
windowsOpened = driver.window_handles()
# Switch to the child window.
drive.switch_to.window(windowsOpened[1])
# Perform operation in the child window
driver.find_element(Buy.NAME, “some_name”).click()
# Once operation is completed, close the child window
driver.close()
# Switch back to parent window and continue other operation
drive.switch_to.window(windowsOpened[0])
Chaining of Web element, Implicit and Explicit Wait
- When we have multiple web elements with the same locators
- To perform operation on each of the child element we can first find the parent element
- Then do the further search for each child element under that parent
Implicit wait is global time out. e.g driver.implicit_wait(5)
- driver will wait max 5 secs for each object to be available.
- If the object is available before 5 secs, say 2 sec driver will continue.
- Better then time.sleep(5). Because even if the object available before 5 secs it will still wait for 5 secs.
Why we don’t increase the implicit wait according to the object which takes maximum time to be available?
- It impact the performance testing. Say all objects are suppose to be available with in 2 secs. else we need to report to developer to check the performance.
- So for one specific object which required 5 secs to load (expected behaviour) we use explicit wait.
- Explicit wait is used for a specific object which takes more time than default implicit wait.
# Switch to the alert mode
driver.implicit_wait(5)
elements = driver.find_elements(By.XPATH,"//form/div")
for element in elements:
# the find_element here will search only within the element not the entire html page.
element.find_element(By.CSS_SELECTOR,".form_class").send_keys("same text")
#explicit wait
#Define a class called WebDriverWait. Pass driver object and time to wait
wait = WebDriverWait(driver,15)
wait.until(expected_conditions.presence_of_element_located(By.CSS_SELECTOR,".some_class"))
Run JavaScript on Browser using Python
- All browser design on JS
- e.g Scroll down: Selenium doesn’t provide method for scroll down. But using JS you can
- driver.execute_script(“enter your javascript here”)
# Scroll to the bottom of the window
driver.execute_script("window.scrollBy(0,document.body.scrollHeight);")
#This the JS. Also try to run it in the browser console directly
#window.scrollBy(0,document.body.scrollHeight);
# Scroll the window only 500px
#depends when the element is visible after scrolling.
#try in browser window directly then use in Selenium
driver.execute_script("window.scrollBy(0,500);")
Screenshot
driver.get_screenshot_as_file("screen.png")
Certificate Error
Some site gives certificate error, saying the certificate is not recognised. Add the certificate as trustable. Selenium can handle these errors.
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--ignore-certificate-errors")
driver = webdriver.Chrome(options=option)