Robot Framework Tutorial 2016
Part 1: Installation
Part 2: Keywords
Part 3: Implementing Keywords in Java
Part 4: Selenium2Library as a drop-in replacement for SeleniumLibrary
Part 5: Integration with TeamCity CI-Server
Part 6: Integration with Jenkins
Part 7: File Processing
A brief history of Selenium
Selenium is still one of the first tools to name when testing Web Applications. It is sticking around since 2004 and has gone through quite some improvements during that time. The biggest improvement for sure was the step from Selenium 1 (Selenium-RC) to Selenium 2 (Selenium Web-Driver). Now this is not really hot news as Selenium 2 is out for years already. But still lots of projects – and we are looking at those projects utilizing the Robot Framework – are for sure using Selenium-RC. This blog post is intended to help in switching to Selenium 2 and showing that this is probably often less effort than expected in return for a big gain in test stability. Not talking about the fact that support for the Selenium-RC library of the Robot Framework has stopped already some time ago.
Selenium-RC vs. Selenium 2 – Comparison
So of course new projects will always start using the Selenium2Library. But what about upgrading existing projects? The following table shows a comparison of the available keywords for both Selenium libraries. And believe me it was really some effort to create that table.
|–||Add Cookie||Add Location Strategy||Add Location Strategy||Alert Should Be Present||Alert Should Be Present|
|Assign Id To Element||Assign Id To Element||Call Selenium Api||–||–||Assign Id To Element|
|Capture Page Screenshot||Capture Page Screenshot||Capture Screenshot||–||Checkbox Should Be Selected||Checkbox Should Be Selected|
|Checkbox Should Not Be Selected||Checkbox Should Not Be Selected||Choose Cancel On Next Confirmation||Choose Cancel On Next Confirmation||Choose File||Choose File|
|–||Choose Ok On Next Confirmation||–||Clear Element Text||Click Button||Click Button|
|Click Element||Click Element||Click Flex Element||–||–||Click Element At Coordinates|
|Click Image||Click Image||Click Link||Click Link||Close All Browsers||Close All Browsers|
|Close Browser||Close Browser||Close Window||Close Window||Confirm Action||Confirm Action|
|–||Create Webdriver||Current Frame Contains||Current Frame Contains||Current Frame Should Contain||–|
|–||Current Frame Should Not Contain||Delete All Cookies||Delete All Cookies||Delete Cookie||Delete Cookie|
|–||Dismiss Alert||Double Click Element||Double Click Element||Double Click Flex Element||–|
|Drag And Drop||Drag And Drop||–||Drag And Drop By Offset||Element Should Be Disabled||Element Should Be Disabled|
|Element Should Be Enabled||Element Should Be Enabled||Element Should Be Visible||Element Should Be Visible||Element Should Contain||Element Should Contain|
|Element Should Not Be Visible||Element Should Not Be Visible||–||Element Should Not Contain||Element Text Should Be||Element Text Should Be|
|Flex Element Should Exist||–||Flex Element Should Not Exist||–||Flex Element Text Should Be||–|
|Focus||Focus||Frame Should Contain||Frame Should Contain||Frame Should Contain Text||–|
|Get Alert Message||Get Alert Message||Get All Links||Get All Links||Get Cookie Value||Get Cookie Value|
|Get Cookies||Get Cookies||Get Element Attribute||Get Element Attribute||Get Horizontal Position||Get Horizontal Position|
|Get Inner Html||–||Get List Items||Get List Items||Get Location||Get Location|
|Get Matching Xpath Count||Get Matching Xpath Count||Get Selected List Label||Get Selected List Label||Get Selected List Labels||Get Selected List Labels|
|Get Selected List Value||Get Selected List Value||Get Selected List Values||Get Selected List Values||–||Get Selenium Implicit Wait|
|–||Get Selenium Speed||–||Get Selenium Speed||–||Get Selenium Timeout|
|Get Source||Get Source||Get Table Cell||Get Table Cell||Get Text||Get Text|
|Get Title||Get Title||Get Value||Get Value||Get Vertical Position||Get Vertical Position|
|–||Get Webelement||–||Get Webelements||Get Window Identifiers||Get Window Identifiers|
|Get Window Names||Get Window Names||–||Get Window Position||–||Get Window Size|
|Get Window Titles||Get Window Titles||Go Back||Go Back||Go To||Go To|
|Highlight Element||–||Input Password||Input Password||Input Text||Input Text|
|Input Text Into Flex Element||–||–||Input Text Into Prompt||List Selection Should Be||List Selection Should Be|
|List Should Have No Selections||List Should Have No Selections||–||List Windows||Location Should Be||Location Should Be|
|Location Should Contain||Location Should Contain||–||Locator Should Match X Times||–||Log Location|
|Log Source||Log Source||–||Log Title||Maximize Browser Window||Maximize Browser Window|
|Mouse Down||Mouse Down||Mouse Down On Image||Mouse Down On Image||Mouse Down On Link||Mouse Down On Link|
|Mouse Out||Mouse Out||Mouse Over||Mouse Over||Mouse Up||Mouse Up|
|Open Browser||Open Browser||Open Context Menu||Open Context Menu||Page Should Contain||Page Should Contain|
|Page Should Contain Button||Page Should Contain Button||Page Should Contain Checkbox||Page Should Contain Checkbox||Page Should Contain Element||Page Should Contain Element|
|Page Should Contain Image||Page Should Contain Image||Page Should Contain Link||Page Should Contain Link||Page Should Contain List||Page Should Contain List|
|Page Should Contain Radio Button||Page Should Contain Radio Button||Page Should Contain Textfield||Page Should Contain Textfield||Page Should Not Contain||Page Should Not Contain|
|Page Should Not Contain Button||Page Should Not Contain Button||Page Should Not Contain Checkbox||Page Should Not Contain Checkbox||Page Should Not Contain Element||Page Should Not Contain Element|
|Page Should Not Contain Image||Page Should Not Contain Image||Page Should Not Contain Link||Page Should Not Contain Link||Page Should Not Contain List||Page Should Not Contain List|
|Page Should Not Contain Radio Button||Page Should Not Contain Radio Button||Page Should Not Contain Textfield||Page Should Not Contain Textfield||Press Key||Press Key|
|Press Key Native||–||Radio Button Should Be Set To||Radio Button Should Be Set To||Radio Button Should Not Be Selected||Radio Button Should Not Be Selected|
|Register Keyword To Run On Failure||Register Keyword To Run On Failure||Reload Page||Reload Page||–||Remove Location Strategy|
|Select All From List||Select All From List||Select Checkbox||Select Checkbox||Select Flex Application||–|
|Select Frame||Select Frame||Select From Flex Element||–||Select From List||Select From List|
|–||Select From List By Index||–||Select From List By Label||–||Select From List By Value|
|Select Radio Button||Select Radio Button||Select Window||Select Window||–||Set Browser Implicit Wait|
|–||Set Screenshot Directory||–||Set Selenium Implicit Wait||Set Selenium Speed||Set Selenium Speed|
|Set Selenium Timeout||Set Selenium Timeout||–||Set Window Position||–||Set Window Size|
|Simulate||Simulate||Start Selenium Server||–||Stop Selenium Server||–|
|Submit Form||Submit Form||Switch Browser||Switch Browser||Table Cell Should Contain||Table Cell Should Contain|
|Table Column Should Contain||Table Column Should Contain||Table Footer Should Contain||Table Footer Should Contain||Table Header Should Contain||Table Header Should Contain|
|Table Row Should Contain||Table Row Should Contain||Table Should Contain||Table Should Contain||–||Textarea Should Contain|
|–||Textarea Value Should Be||Textfield Should Contain||Textfield Should Contain||Textfield Value Should Be||Textfield Value Should Be|
|Title Should Be||Title Should Be||Unselect Checkbox||Unselect Checkbox||Unselect Frame||Unselect Frame|
|Unselect From List||Unselect From List||–||Unselect From List By Index||–||Unselect From List By Label|
|–||Unselect From List By Value||Wait For Condition||Wait For Condition||–||Wait For Flex Element|
|–||Wait Until Element Contains||–||Wait Until Element Does Not Contain||–||Wait Until Element Is Enabled|
|–||Wait Until Element Is Not Visible||–||Wait Until Element Is Visible||Wait Until Page Contains||Wait Until Page Contains|
|Wait Until Page Contains Element||Wait Until Page Contains Element||Wait Until Page Loaded||–||–||Wait Until Page Does Not Contain|
|–||Wait Until Page Does Not Contain Element||Xpath Should Match X Times||Xpath Should Match X Times|
First thought was to do this with a screenshot, but it would have been rather hard to see the differences at a glance then. The keywords are taken from the final release (2.9.2) of the Selenium-RC keyword library and the release 1.7.4 of the Selenium 2 keyword library. Following keywords are “missing” from the Selenium 2 library in the comparison:
- Call Selenium Api
- Capture Screenshot
- Click Flex Element
- Current Frame Should Contain
- Double Click Flex Element
- Flex Element Property Should Be
- Flex Element Should Exist
- Flex Element Should Not Exist
- Flex Element Text Should Be
- Frame Should Contain Text
- Get Inner Html
- Highlight Element
- Input Text Into Flex Element
- Press Key Native
- Select Flex Application
- Select From Flex Element
- Start Selenium Server
- Stop Selenium Server
- Wait Until Page Loaded
Analysis of the Differences
Back to the title of this blog post that is stating something like “drop-in replacement”. But the list of “missing” keywords seems to be rather long. Let’s have a closer look.
This page explains how to use SeleniumLibrary to run tests against Adobe Flex applications. Although it has not been explicitly tested, it should be possible to test also Flash applications the same way. (https://github.com/robotframework/SeleniumLibrary/wiki/FlexTesting)
The missing “Flex-Keywords” are probably only relevant for a minority of projects (no offense intended :-)). Obviously starting and stopping the Selenium Server is no longer required, because, well, there is no Selenium Server anymore. “Highlight Element” (Highlights element found with locator briefly. This is mainly useful for debugging purposes.) does not have any real purpose unless this kind of debugging is happening on a daily basis ;-). “Get Inner HTML” can be easily worked around and “Capture Screenshot” can be replaced by “Capture Page Screenshot”.
“Current Frame Should Contain” and “Frame Should Contain Text” can be replaced using the “Select Frame” and “Current Frame Contains” keywords. The solution to work around the missing keyword “Wait Until Page Loaded” is probably the fact that many of the keywords that cause a page load take an optional argument “dont_wait” that can be also used to wait/not wait for the page load.
This is leaving us with very few potential hard cases, well, at least harder than the previous ones:
- Call Selenium Api and
- Press Key Native.
“Call Selenium Api” might have been used to call Selenium functionality that has not been exposed as a keyword. As there are additional keywords available in the Selenium 2 library there is a chance the needed keywords are available already. Otherwise a change in the implementation of the test will be required. The “Press Key Native” has been called last resort in one of my previous blog posts. Well, today I think if this is required then there is really something wrong in the system under test. Again it should have been only used in very rare cases and thus in a very small amount of projects.
The next Move
Hopefully the list and analysis in this blog post makes it easier to predict the effort needed to switch from Selenium-RC to Selenium 2. Just in case here comes a brief list of the main advantages of Selenium 2:
- The used Webdriver API is supporting real browsers, no need anymore for running a Selenium Server.
- Possibility to execute tests in headless mode.
- Better support to test applications using AJAX.
Now making the move from Selenium-RC to Selenium 2 might be a good candidate to be analysed using time-boxing. Depending on the size and complexity of the project one to two days should be enough for this. In a best case scenario after this time the switch is already finished to a good degree. In worst case one has at least a concrete idea on the effort needed to finally move from Selenium-RC to Selenium 2 and if that makes sense at all.
Of course the change can – and should – be made in a rather noninvasive way. Once it has been verified that the affected tests are still running fine the switch can be made final. This means:
- In case of a smaller project just duplicate the whole testsuite and make the changes in the copy. Keep both testsuites running in parallel for a certain amount of time.
- In bigger problems the same approach is possible, but just starting with a rather isolated part, e.g. one testsuite from the overall amount of testsuites.
- In product development there might be often libraries wrapping the Selenium (and other) libraries already. Again a copy can be created and some testsuites can be changed to use that copy. The testsuites can run in parallel to prove it is working with the changed library.
A similar approach should be possible in most projects/products.
Well, it is worth a try :-).