Page tree
Skip to end of metadata
Go to start of metadata

Selenium allows you to automate UI browser testing. You can write your tests in Java, Javascript, C#, etc. In this example, I use Java. 

More information here: http://www.seleniumhq.org/.

Why Selenium Grid

There isn’t any easy and reliable way to run Internet Explorer in Linux, so I had to find a Windows machine to host the browser. I also could not install Chrome and Firefox successfully in the linux box (maybe I could have if I spent more time).

Therefore I run the tests remotely in aus-test-worker2 (Linux), but I have to tell the Windows machine to open the browsers. This is where Selenium Grid comes in.

A grid consists of a hub and a single or multiple nodes. The hub is where you tell the tests to connect to, and it will redirect the appropriate node for the browser. Each node hosts the browser(s) to execute the tests on.

More info: https://github.com/SeleniumHQ/selenium/wiki/Grid2

Selenium Hub

Our hub lives in aus-test-worker2. The web drivers I’m using is only compatible with java 8.

You need to download Selenium Standalone Server here: http://www.seleniumhq.org/download/.

To start the hub, specify "-role hub":

java -jar <selenium-server-standalone-3.0.1.jar path> -role hub

To shut down the hub:

http://<hub address>/lifecycle-manager?action=shutdown

 

Selenium Node

The Windows node lives in xsrv.arrc.csiro.au.

You need to download and install selenium-standalone via npm: https://www.npmjs.com/package/selenium-standalone (includes all the latest web drivers for firefox, chrome and ie).

Ideally, you would set up a windows slave on Jenkins, but I had troubles with firewall and I could not get the windows slave to handshake back to aus-test-worker2.

I ended up installing Cygwin so I could execute selenium via SSH from Jenkins.

Browsers installed in this node:

  • Internet Explorer 11
  • Chrome 54
  • Firefox 47.

 

To start selenium as a node, you must specify "-role node" and the "-hub" parameter with the hub address. 

selenium-standalone start -- -role node -hub http://<hub-ip-address>:<hub-port>/grid/register -port 4444

To shut down the node:

http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer

Internet Explorer Notes

Unfortunately, when downloading, it detects the machine is running on 64 bit and automatically downloads IE driver 64 bit which is very slow and problematic.

So I had to download a separate 32 bit IE driver and pointed selenium to use it in the start parameter.

-Dwebdriver.ie.driver="C://jenkins/IeDriverServer.exe"


There are also a couple of things to do in IE:

Firefox Notes

As of Selenium 3.0.1, the built-in Firefox driver only works for Firefox 47 and below. You can either download a separate Firefox driver (called Gecko or Marionette) – I had no success with this, or downgrade your Firefox to version 47.

After downgrading Firefox, ensure you check “no update” in the settings so it doesn't automatically update itself.

Chrome Notes

Chrome just works in Windows.

I was unable to install Chrome in Linux though.

  • Chrome 32 bit in linux is no longer supported (unless we stick to an older version) - that means we can't run the tests on aus-test-worker2 (32 bit).

Safari Notes

I thought it would be nice to test Safari so we know they will work on Iphone and Ipad. However, Safari support for Windows also ended.

There is no Safari for Linux, but it can be run via wine although I have not tried it. 

Writing Selenium Test

Here is the full API: https://seleniumhq.github.io/selenium/docs/api/java/.

In AuScope Portal, I created 2 packages in tests:

  • org.auscope.portal.ui -> for Auscope portal tests
  • org.auscope.portal.ui.mobile -> for Auscope portal mobile tests

I use testng.xml to set up the browser and other parameters for the tests:

<suite name="Selenium TestNG Suite" parallel="tests" thread-count="10">

<!-- Main dev portal tests -->

    <test name="Firefox main portal test">
        <parameter name="browser" value="firefox" />
        <parameter name="version" value="" />
        <parameter name="port" value="4444" />
        <parameter name="portal_url"
            value="http://auscope-portal-dev.arrc.csiro.au/portal/gmap.html" />
        <classes>
            <class name="org.auscope.portal.ui.SearchLayerTest" />
        </classes>
    </test>
    
    <test name="Chrome main portal test">
        <parameter name="browser" value="chrome" />
        <parameter name="version" value="" />
        <parameter name="port" value="4444" />
        <parameter name="portal_url"
            value="http://auscope-portal-dev.arrc.csiro.au/portal/gmap.html" />
        <classes>
            <class name="org.auscope.portal.ui.SearchLayerTest" />
        </classes>
    </test>

    <test name="IE main portal test">
        <parameter name="browser" value="internet explorer" />
        <parameter name="version" value="" />
        <parameter name="port" value="4444" />
        <parameter name="portal_url"
            value="http://auscope-portal-dev.arrc.csiro.au/portal/gmap.html" />
        <classes>
            <class name="org.auscope.portal.ui.SearchLayerTest" />
        </classes>
    </test>

    <!-- Mobile tests -->
    <test name="Firefox mobile test">
        <parameter name="browser" value="firefox" />
        <parameter name="version" value="" />
        <parameter name="port" value="4444" />
        <parameter name="portal_url"
            value="http://auscope-portal-dev.arrc.csiro.au/portal/mobile/index.htm" />
        <classes>
            <class name="org.auscope.portal.ui.mobile.SearchLayerMobileTest" />
        </classes>
    </test> 

    <test name="Chrome mobile test">
        <parameter name="browser" value="chrome" />
        <parameter name="version" value="" />
        <parameter name="port" value="4444" />
        <parameter name="portal_url"
            value="http://auscope-portal-dev.arrc.csiro.au/portal/mobile/index.htm" />
        <classes>
            <class name="org.auscope.portal.ui.mobile.SearchLayerMobileTest" />
        </classes>
    </test>

    <test name="IE mobile test">
        <parameter name="browser" value="internet explorer" />
        <parameter name="version" value="" />
        <parameter name="port" value="4444" />
        <parameter name="portal_url"
            value="http://auscope-portal-dev.arrc.csiro.au/portal/mobile/index.htm" />
        <classes>
            <class name="org.auscope.portal.ui.mobile.SearchLayerMobileTest" />
        </classes>
    </test>

</suite>

1. RemoteWebDriver vs WebDriver

If you are running the selenium server locally, you can use WebDriver, as opposed to RemoteWebDriver. 

You would need to download the WebDriver for your browser(s) and tell the tests the driver's location via Java parameter or System property.

e.g. webdriver.chrome.driver for Chrome

System.setProperty("webdriver.chrome.driver", "C:\\chromedriver.exe");

ChromeDriver driver = new ChromeDriver(profile);

If you are running the browsers remotely (as done with AuScope Jenkins job), you need to use RemoteWebDriver and pass on the hub address.

You will need to start the hub/server before running the test if using RemoteWebDriver. If testing locally on your machine, start the server:

selenium-standalone start

If you want to use the remote hub, then make sure the hub is running

For Auscope portal tests, I made it use localhost as hub by default, but you can specify your hub address with -Dhub parameter, e.g.  -Dhub=130.116.24.73.

RemoteWebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);

 

2. Open the test URL

driver.get("http://auscope-portal-dev.arrc.csiro.au/portal/mobile/index.htm");

3. Find the web element

You can search an element by id, class name, CSS style, etc. Please refer to the API: https://seleniumhq.github.io/selenium/docs/api/java/.

WebElement searchBox = driver.findElement(By.id("hh-searchfield-Featured-inputEl"));

If you need to wait for an element to meet a condition, you can do it using WebDriverWait. E.g. the example below waits for 30 seconds for an element to become visible:

WebElement searchIcon = new WebDriverWait(driver, 30).until(ExpectedConditions.visibilityOf(
    driver.findElement(By.id("hh-searchfield-Featured-trigger-search"))));

4. Perform actions

You can send keys, click, etc.

searchBox.sendKeys("tenement");

toggle.click();

5. Test results via assertions

List<WebElement> rows = driver.findElements(By.className("layer-row"));
assertEquals(1, rows.size());

6. Release the driver

This will release memory and close all browsers associated.

driver.quit();

Running tests from maven

For Auscope portal tests, I made a custom parameter -Dhub to pass on the remote hub address. I also made a profile called "selenium" so the tests are only activated with this profile.

You will need to start your local selenium server, or remote hub and nodes, if running remotely prior to executing:

mvn -Pselenium test -Dhub=xx.xx.xx

You can omit -Dhub parameter if running the tests locally.

Running tests from Eclipse

Again, you'll need to start selenium server/hub and node first because the portal tests use RemoteWebDriver.

You can right click on testng.xml and run as testng suite, or you can run the tests individually and pass on the required parameters as vm args.

As per above, you can run the tests using localhost or via custom -Dhub parameter.

Jenkins Setup

https://cgsrv8.arrc.csiro.au/jenkins/job/Auscope%20portal%20selenium%20tests/

Selenium seems to use a lot of memory and aus-test-worker2 seems to be pretty full.. so I made the tests run manually (and when they grow, we'll have to move it somewhere else).

Pre Steps:

1. Start the hub using java 8:

/usr/lib/jvm/java-8-oracle/jre/bin/java -jar /home/jenkins-slave/selenium/selenium-server-standalone-3.0.1.jar -role hub &

2. SSH into the windows node and start the node (to enable this, I installed Cygwin on the windows machine). Register the node to the hub ip address. I also pointed it to a 32bit IE driver.

bash selenium-standalone start -- -role node -hub http://130.116.24.73:4444/grid/register -port 4444 -Dwebdriver.ie.driver="C://jenkins/IeDriverServer.exe" &

Maven build parameters:

test -Pselenium -Dmaven.test.failure.ignore=false -Dhub=130.116.24.73

Post Steps:

Shut down the node:

cygstart "http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer"

Shut down the hub:

 wget "http://130.116.24.73:4444/lifecycle-manager?action=shutdown"

Notes:

-          I had to set Build_ID=dontkillme to get around this intermittent problem: http://wiki.jenkins-ci.org/display/JENKINS/Spawning+processes+from+build, but I am not sure if it works..