Overview

Robot Framework Web-Template – Selenium2, PhantomJS, Basic Authentification

No Comments

This article and the corresponding template-project has been updated on 10th of March 2017 to include support for Geckodriver.

This article is an up-to-date version of “Robot Framework – A complete example” from 2012. Even though a lot of things from that article are still valid, time was not standing still since then. This is especially true for the used web technologies. Therefore this article is based on an updated technology stack consisting of Selenium2Library, PhantomJS, Chromedriver, Geckodriver and of course the latest Robot Framework release, which is 3.0.2 at the time writing this post.

Test Scenario

The scenario considered in this article is probably quite common: Testing a web application through its web – and thus user – interface. But typically it is not that simple as there are some additional constraints/requirements. It must be possible to run the tests locally on the developer machines. In this case we assume that the application under test is also running locally. Then test execution must be possible on some CI-server, e.g. Jenkins. The development team is using different operating systems, which must be considered for the local setup. Furthermore it would be nice to be able to watch the test execution locally, e.g. for debugging purposes. The execution on the CI-environment on the other hand must be executed headless as no window manger nor browser is installed there.

Project Setup

Providing a template for the above test scenario – along with some explanations – is the purpose of this blog post. Even though it is a quite common scenario projects are often starting from scratch in setting up the acceptance testing chain for this.

The Robot Framework Web Template is provided on GitHub. Checking the project out and running the tests right away was a major goal of this project. Therefore some binaries and JARs are already part of the project. For sure you want to update those as your project is progressing.

After checking out the template-project from GitHub (see box above) there are the following directories:

  • ./bin/ : Contains needed Robot Framework JARs and Chromedriver/Geckodriver executables together with run-scripts to execute the tests locally on different operating systems and a run-script for the CI-environment. Test execution must be started from within this directory.
  • ./configuration/ : Provides configurations for running the tests on different operating systems and the CI-environment. Those configurations are used in the above mentioned run-scripts by passing them in as variable files. Of course those variables are then used in the test implementation.
  • ./testsuites/ : Contains a sample testsuite that is performing a search using Google advanced search page. Hopefully that stays stable for some time for this example to work properly.
  • ./testsuites/resources/ : The technical part to perform the search is implemented in own keywords. Those are grouped in own resource files. Storing the resource files in a sub-directory of the testsuite-directory or on the same level in a different directory is probably a matter of taste. Nowadays I prefer the approach of using a subdirectory.

Test Execution

After checking out the project-template the corresponding run-script should work out of the box. The reason for this is that the Robot Framework JAR and the Selenium2Library JAR are part of the project template. The same if true for the Chromedriver- and Geckodriver-executables for the different operating systems. During the test execution it is ensured that the proper executable is accessible and used. Thus no additional local installation is required.


Note: As it has turned out that using the Python-installation is typically more reliable (as it is more up-to-date) this is now the default in the run-scripts. For a quick trial simply comment out the line starting with “robot” and comment in the line starting with “java” to run the scripts without any further installation. Otherwise if Python 2.7 is already installed it is easy as this to setup the Robot Framework with Selenium2 library locally:

pip install robotframework
pip install robotframework-selenium2library

The project setup is tested on all three operating systems and should work out-of-the-box. If there are problems please let me know so I can fix those in the template-project.

Now what about running the CI-environment run-script? The required steps are the same to be able to execute it on some CI-server or locally. This way it can be nicely tested locally as well. But it requires a bit of additional installation and some words of explanation. Executing the tests headless works by routing any requests to PhantomJS. For this first of all PhantomJS must be started as a webdriver on the specific environment. Furthermore when opening the Browser using the “Open Browser” keyword from the Selenium2Library the corresponding URL must be given as a remote URL.

 .../phantomjs-2.1.1-macosx/bin$ ./phantomjs --webdriver=4444
 
Open Browser   http:www.google.de   phantomjs   MainBrowser   http://localhost:4444

To execute PhantomJS just download it from here for the target operating system, unpack it and start it as shown above Then start the run-ci-env.sh run-script. Well, that will fail unless there is a local Robot Framework installation available. The reason why this is needed is explained right away. More information on installing the Python-flavor of the Robot Framework can be found here. In very short:

Install Python 2.7.x (if not available already)
pip install robotframework
pip install robotframework-selenium2library

After these installation steps the run-script for the CI-environment will work as well.

Considering how easy it is to install the Python-flavor of the Robot Framework using pip it is absolutely an option to completely switch to this type of installation. The main reason for using the Java-flavor in the template is the possibility to execute the tests locally right away after checking them out without any further installation steps.

So why the Python-flavor installation for running in headless mode? The trivial answer: I was not getting the desired_capabilities feature to work properly with the Java port of the Selenium2Library. It just did not work and I wanted to add that to the template-project as it might be a common problem when using PhantomJS that the user-agent must be set explicitly. How to do this can be seen from the basic_keywords.txt.

Basic Authentification

Dealing with Basic Authentification can easily feel like a boss fight. The Robot Framework Selenium2Library simply does not provide any real solution for this. Or I was simply unable to find that solution. Anyway there is a quite simple workaround, well, potentionally ;-). It is possible to simply add the username and password used for Basic Authentification directly to the URL. Assuming the Google page would be protected by user “kirk” and password “captain!1” the URL to open would be: “https://kirk:captain!1@www.google.de”. Interesting enough the provided username and password are ignored if not needed and the page will still open.

Well, this approach has some implications still. While this works in the current PhantomJS driver (2.1.1) this feature has bee removed from the Chromedriver due to security issues. In Chromdriver 2.27 this still worked though and as luck would have it that is the version bundled in the template-project ;-). Luckily this also works with the current Geckodriver 0.14 that is also included in the template project.

If PhantomJS is dropping support for this and one needs to advance to more recent version of Chromedriver I would be a bit clueless how to do this using the Robot Framework and Selenium2Library. Any additional ideas are of course welcome in the comments section.

Robot Implementation Details

Let’s take a closer look at some of the Robot Framework implementation details that might be interesting. I tried something a bit new – at least for me – here by prefixing keyword names with a technical term. This might make the tests more readable and easier to maintain.

Copying the Webdriver Executable
If we are using Chromedriver it is one solution to copy the executable to the bin-directory during test execution. Thus it can be found during test execution. Afterwards it is deleted again. If we are using PhanomJS there is no need to copy anything. This is recognized by defining the WEBDRIVER_PATH as “none” in that case.

Basic -> Prepare
    Run Keyword Unless   '${WEBDRIVER_PATH}' == 'none'    Copy File         ${WEBDRIVER_PATH}   .
 
Basic -> Cleanup
    Run Keyword Unless   '${WEBDRIVER_COPY}' == 'none'    Remove File       ${WEBDRIVER_COPY}

Open page using PhantomJS or Chromedriver
In this keyword it is distinguished whether Chromedriver or PhantomJS is used for running the tests. All variables are defined in the variable-files in the configuration directory. This also allows to define different BASE_URLs for different run-scripts.

Basic -> Open Application
    &{CAPS}=   Create Dictionary   phantomjs.page.settings.userAgent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/601.2.7 (KHTML, like Gecko) Version/9.0.1 Safari/601.2.7
    Run Keyword If       '${WEBDRIVER_COPY}' == 'none'   Open Browser    ${BASE_URL}   ${WEBDRIVER_TYPE}   MainBrowser   http://localhost:${PHANTOMJS_PORT}    ${CAPS}
    Run Keyword Unless   '${WEBDRIVER_COPY}' == 'none'   Open Browser    ${BASE_URL}   ${WEBDRIVER_TYPE}   MainBrowser
    Wait Until Element Is Visible   _dKg
    Capture Page Screenshot

A search testcase

Finally let’s take a quick look at how a testcase is written using those keywords. This is hopefully pretty straightforward now.

*** Test Cases ***
Search for Robot Framework
    Basic -> Open Application
    Search -> Search for Phrase   Robot Framwewok
    Search -> Found in Results    robotframework.org
    Basic -> Close Application

Conclusion

The web-template provided in this blog post can hopefully be a good starting point to start testing web applications using Selenium 2. Being able to run the tests in headless mode using PhantomJS is probably often required. Being able to easily support different operating systems in the development team is nice to have I guess. This might not happen that often ;-). Anyway it is a good showcase on how to configure the tests using variable files. Any feedback or ideas for improvements are of cause highly welcome.

Thomas Jaspers

Long-term experience in agile software projects using
Java enterprise technologies. Interested in test automation tools and concepts.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

More content about Agile Testing

Comment

Your email address will not be published. Required fields are marked *