Selenium WebDriver with Jenkins on Ubuntu

Hi,


Note: Update on July 23, 2019 to use Chrome headless browser and docker.

Use Case:

I have a task to do a quick verification on the web application that can launch and login, so I want to do a quick UI check with screenshot, then I think about the Selenium webdriver.


Solution:

As I'm working with Python and Ubuntu environment so I picked up using Python for a quick solution. Based on my previous knowledge, I use Chrome browser, download Chrome driver  for Linux then unzip and copy the chromdriver into any directory in your $PATH, for ex: /usr/bin. From Chrome browser 59, it supports headless browsing so we will use this feature instead of using pyvirtualdisplay and xvfb.

Based on this guide, instead of using virtualenv, create a docker container based on this Dockerfile (create a jenkins service user in this container to turn this container as a Jenkins slave and mount the Jenkins workspace into this container for processing and make sure the downloaded chromedriver is executed by this jenkins user). You can refer to this guide to have some idea to build is docker image, but the article is to build the selenium standalone grid server where I build the client selenium environment.

FROM ubuntu:16.04

RUN apt-get -y update && apt-get install -y \
  sudo \
  curl \
  software-properties-common \
  apt-transport-https \
  openjdk-8-jre \
  ca-certificates \
  git \
  unzip \
  python3-setuptools \
  python3-dev

RUN curl -sSL https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py \
  && python3 /tmp/get-pip.py \
  && rm /tmp/get-pip.py

RUN curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add \
  && echo "deb [arch=amd64]  http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list \
  && apt-get -y update \
  && apt-get install -y google-chrome-stable

RUN cd /tmp \
  && export VERSION=$(curl http://chromedriver.storage.googleapis.com/LATEST_RELEASE) \
  && curl -sSLO https://chromedriver.storage.googleapis.com/$VERSION/chromedriver_linux64.zip \
  && unzip chromedriver_linux64.zip -d /usr/bin \
  && chmod 777 /usr/bin/chromedriver

RUN python3 -m pip install selenium

RUN adduser --disabled-password --gecos "" --uid <jenkins_uid> jenkins && adduser jenkins sudo \
  && mkdir /home/jenkins/slave \
  && echo "jenkins ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers 

RUN curl -L https://repo.jenkins-ci.org/releases/org/jenkins-ci/plugins/swarm-client/3.9/swarm-client-3.9.jar \
  -o /home/jenkins/slave/swarm-client-3.9.jar


USER jenkins


With my latest test, you don't need to have xvfb apt  in order to have pyvirtualdisplay to run selenium UI with Jenkins. But you have to provide the Chrome headless options when initiate the chromedriver

A sample script as below

import argparse

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
#from pyvirtualdisplay import Display

parser = argparse.ArgumentParser(description='Run a simple GUI test')
parser.add_argument("-t", "--test", type=str, default='x.x.x.x', help='Test machine IP')
parser.add_argument("-o", "--output", type=str, help='Screenshot output path')
parsed_args = parser.parse_args()

#display = Display(visible=0, size=(800, 600))
#display.start()

url = "http://" + parsed_args.test + ':8080'
filename = parsed_args.output + '/screen1.png'

options = webdriver.ChromeOptions()
options.binary_location = '/usr/bin/google-chrome-stable'
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--window-size=1024,768')


driver = webdriver.Chrome(chrome_options=options)
#driver = webdriver.Chrome()
driver.get(url)
driver.save_screenshot(filename)
print("Saved screenshot: " + filename)

userNameEl = driver.find_element_by_id("id1")
userNameEl.send_keys("user")
passwordEl = driver.find_element_by_id("id2")
passwordEl.send_keys("password")
driver.find_element_by_xpath("//button[@type='submit']").click()
try:
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[contains(text(), 'MainPage')]")))
    filename = parsed_args.output + '/screen2.png'
    driver.save_screenshot(filename)
    print("Saved screenshot: " + filename)
finally:

    driver.quit()



Comments