This blog post documents the process I went through to get Selenium running on a headless Linux server in my lab environment. I find Selenium extremely useful when regression testing web site upgrades and major changes. At the end of this post, I have included the code I use for the automated testing of a base (vanilla) Joomla installation.
Using the Selenium IDE extension in Chrome
Then I added Python driver for Selenium, as pip was already installed:
pip install -U selenium
Then install pytest
sudo apt install python-logilab-common
sudo apt-get install pytest
Chrome: https://sites.google.com/a/chromium.org/chromedriver/downloads
sudo add-apt-repository ppa:ubuntu-mozilla-security/ppa
sudo apt-get update
sudo apt-get install firefox
cd /usr/local/bin
wget https://chromedriver.storage.googleapis.com/2.35/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
sudo nano /etc/apt/sources.list
deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main
sudo wget https://dl.google.com/linux/linux_signing_key.pub
sudo apt-key add linux_signing_key.pub
which gives OK
sudo apt install google-chrome-stable
#!/bin/bash
# Runs the Selenium Server so run in background mode
java -Xms40m -Xmx256m -jar /home/pgroom/selenium-server-standalone-3.141.59.jar &
Check they run ok via
pytest <name of test.py>
sudo apt-get install xvfb
pip install PyVirtual Display
The :40 is a display number so does not need to be 40 per se.
sudo nohup Xvfb :40 -ac &
export DISPLAY=:40
env | grep DISPLAY
Final script for the default Joomla installation
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
# chrome_options = webdriver.ChromeOptions()
# chrome_options.add_argument('--headless')
# chrome_options.add_argument('--no-sandbox') # required when running as root user. otherwise you would get no sandbox errors.
# driver = webdriver.Chrome(driver_path='/usr/local/bin/chromedriver', chrome_options=chrome_options, service_args=['--verbose', '--log-path=/tmp/chromedriver.log'])
from pyvirtualdisplay import Display
display = Display(visible=0, size=(1024, 768))
display.start()
# Full page web tests
print("DESKTOP WEB TESTS")
print("")
driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', service_args=['--verbose', '--log-path=/tmp/chromedriver.log'])
driver.get('<URL of test web site>')
print("Test 1 - UAT Chrome Desktop text exist")
driver.set_window_size(1294, 694)
assert ("Getting Started" in driver.page_source)
print("Passed - found Getting Started on the page")
print("")
print("Test 2 - UAT Chrome Desktop Home button exist")
menuhome = driver.find_element_by_css_selector("body.site > div#top > div.container > nav.navigation > div.nav-collapse > ul.nav > li.item-101 > a")
print(menuhome.text)
print("Passed - found Menu -> Home on the page")
print("")
print("Test 3 - UAT Chrome Desktop Joomla button exist")
joomlabtn = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > main#content > div.item-page > ul.tags > li.tag-2 > a.label")
print(joomlabtn.text)
print("Passed - found Joomla button on the page")
print("")
print("Test 4 - UAT Chrome Desktop Joomla under Popular Tags exist")
populartags = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > div#aside > div.well > div.tagspopular > ul > li > a")
print(populartags.text)
print("Passed - found Popular Tags -> Joomla on the page")
print("")
print("Test 5 - UAT Chrome Desktop Getting Started under Latest Articles exist")
gettingstarted = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > div#aside > div.well > ul.latestnews > li > a > span")
print(gettingstarted.text)
print("Passed - found Latest Articles -> Getting Started on the page")
print("")
print("Test 6 - UAT Chrome Desktop 0 results for CMS in Search Box exist")
searchentry = driver.find_element_by_css_selector("body.site > div#top > div.container > header.header > div.header-inner > div.header-search > div.search > form.form-inline > input#mod-search-searchword93.inputbox")
searchentry.send_keys('CMS')
searchentry.send_keys(Keys.ENTER)
assert ("results" in driver.page_source)
searchresults = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > main#content > div.search > form#searchForm > div.searchintro > p > strong > span.badge")
print(searchresults.text)
print("Passed - found 0 results for CMS in Search Box on the page")
print("")
# Then check get an User Menu with links to "Your Profile", "Submit an Article", "Site Administrator", "Template Setttings" and "Site Settings"
print("Test 7 - UAT Chrome Desktop Logged in and get an User Menu with links")
username = driver.find_element_by_id("modlgn-username")
password = driver.find_element_by_id("modlgn-passwd")
username.send_keys("username") # CHANGE THIS TO ACTUAL USERNAME
password.send_keys("password") # CHANGE THIS TO ACTUAL PASSWORD
driver.find_element_by_name("Submit").click()
assert ("Your Profile" in driver.page_source)
assert ("Submit an Article" in driver.page_source)
assert ("Site Administrator" in driver.page_source)
assert ("Template Settings" in driver.page_source)
assert ("Site Settings" in driver.page_source)
print("Passed - Logged in and found Your Profile etc on the page")
print("")
print("Test 8 - UAT Chrome Desktop Logged in -> User Menu -> Your Profile -> Name -> Super User")
yourprofile = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > div#aside > div.well > ul.nav > li.item-102 > a").click()
assert ("Super User" in driver.page_source)
print("Passed - Selected User Menu -> Your Profile -> Name results in Super User")
print("")
print("Test 9 - UAT Chrome Desktop Logged Out -> back to Login")
logout = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > div#aside > div.well > form#login-form > div.logout-button > input.btn").click()
assert ("Login Form" in driver.page_source)
print("Passed - Logged out back to Login prompt")
print("")
driver.quit()
print("MOBILE WEB TESTS")
print("")
driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', service_args=['--verbose', '--log-path=/tmp/chromedriver.log'])
driver.get('<URL of test web site>')
print("Test 11 - UAT Chrome Mobile text exist")
driver.set_window_size(514, 662)
assert ("Getting Started" in driver.page_source)
print("Passed - found Getting Started on the page")
print("")
print("Test 12 - UAT Chrome Mobile Home button exist")
menuhome = driver.find_element_by_css_selector("body.site > div#top > div.container > nav.navigation > div.nav-collapse > ul.nav > li.item-101 > a")
print(menuhome.text)
print("Passed - found Menu -> Home on the page")
print("")
print("Test 13 - UAT Chrome Mobile Joomla button exist")
joomlabtn = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > main#content > div.item-page > ul.tags > li.tag-2 > a.label")
print(joomlabtn.text)
print("Passed - found Joomla button on the page")
print("")
print("Test 14 - UAT Chrome Mobile Joomla under Popular Tags exist")
populartags = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > div#aside > div.well > div.tagspopular > ul > li > a")
print(populartags.text)
print("Passed - found Popular Tags -> Joomla on the page")
print("")
print("Test 15 - UAT Chrome Mobile Getting Started under Latest Articles exist")
gettingstarted = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > div#aside > div.well > ul.latestnews > li > a > span")
print(gettingstarted.text)
print("Passed - found Latest Articles -> Getting Started on the page")
print("")
print("Test 16 - UAT Chrome Mobile 0 results for CMS in Search Box exist")
searchentry = driver.find_element_by_css_selector("body.site > div#top > div.container > header.header > div.header-inner > div.header-search > div.search > form.form-inline > input#mod-search-searchword93.inputbox")
searchentry.send_keys('CMS')
searchentry.send_keys(Keys.ENTER)
assert ("results" in driver.page_source)
searchresults = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > main#content > div.search > form#searchForm > div.searchintro > p > strong > span.badge")
print(searchresults.text)
print("Passed - found 0 results for CMS in Search Box on the page")
print("")
# Then check get an User Menu with links to "Your Profile", "Submit an Article", "Site Administrator", "Template Setttings" and "Site Settings"
print("Test 17 - UAT Chrome Mobile Logged in and get an User Menu with links")
username = driver.find_element_by_id("modlgn-username")
password = driver.find_element_by_id("modlgn-passwd")
username.send_keys("username") # CHANGE THIS TO ACTUAL USERNAME
password.send_keys("password") # CHANGE THIS TO ACTUAL PASSWORD
driver.find_element_by_name("Submit").click()
assert ("Your Profile" in driver.page_source)
assert ("Submit an Article" in driver.page_source)
assert ("Site Administrator" in driver.page_source)
assert ("Template Settings" in driver.page_source)
assert ("Site Settings" in driver.page_source)
print("Passed - Logged in and found Your Profile etc on the page")
print("")
print("Test 18 - UAT Chrome Mobile Logged in -> User Menu -> Your Profile -> Name -> Super User")
yourprofile = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > div#aside > div.well > ul.nav > li.item-102 > a").click()
assert ("Super User" in driver.page_source)
print("Passed - Selected User Menu -> Your Profile -> Name results in Super User")
print("")
print("Test 19 - UAT Chrome Mobile Logged Out -> back to Login")
logout = driver.find_element_by_css_selector("body.site > div#top > div.container > div.row-fluid > div#aside > div.well > form#login-form > div.logout-button > input.btn").click()
assert ("Login Form" in driver.page_source)
print("Passed - Logged out back to Login prompt")
print("")
driver.quit()