Recording Robot Framework Keywords with Selenium IDE - codecentric AG Blog

:

In nearly all projects at codecentric we are using the Robot Framework for Acceptance Testing. The Robot Framework is a keyword-driven test-automation framework. An introduction is available here.

The Selenium IDE is a Firefox-Addon which supports the developer to record test cases with Selenium. One interesting feature is the possibility to choose one of the different clipboard formats which translates the script into your favorite programming language syntax, for example HTML (default), JUnit, Python or Ruby.

During the startup phase of my actual project I came up with the idea to implement a Robot Framework Clipboad Format for the Selenium IDE. After only a few search requests on google I quickly realized, that it is not very complicated to extend the IDE with custom extensions :-). So the plan is that it is possible to record the test cases with this Firefox Addon and directly copy and paste the script into the Robot Framework Keyword Format.

The goal

A Selenium command consists of three attributes: selenium-command, target and value. The default format is always HTML and looks like this:

<tr>
	<td>select</td>
	<td>id=feldId</td>
	<td>Test</td>
</tr>

<tr> <td>select</td> <td>id=feldId</td> <td>Test</td> </tr>

The format in Java:

selenium.select("id=feldId", "Test");

selenium.select("id=feldId", "Test");

But we want to get something like this:

Select From List  id=feldId  test

Select From List id=feldId test

The API

For implementing a custom clipboard format you have to implement only a few methods. The formatCommands-Method converts the test case respectively the single command into the target format.

function formatCommands(commands) {
  var result = '';
  for (var i = 0; i < commands.length; i++) {
    var command = commands[i];
    if (command.type == 'command') {
      var keyword = KEYWORDS[command.command];
      if(keyword == null){
      	keyword = "Call Selenium Api  " + command.command;
      }
      var target = command.target.replace(/id=/, '');
      result += keyword + SEPARATOR + target + SEPARATOR + command.value + "\n";
      keyword = null;
    }
  }
  return result;
}

function formatCommands(commands) { var result = ''; for (var i = 0; i < commands.length; i++) { var command = commands[i]; if (command.type == 'command') { var keyword = KEYWORDS[command.command]; if(keyword == null){ keyword = "Call Selenium Api " + command.command; } var target = command.target.replace(/id=/, ''); result += keyword + SEPARATOR + target + SEPARATOR + command.value + "\n"; keyword = null; } } return result; }

The parse-Method takes the source of the recorded test case and updates it, when something has changed. Additionally it is possible to define variable options and some other methods, but we don’t need them here.

function parse(testCase, source) {
  var doc = source;
  var commands = [];
  while (doc.length > 0) {
    var line = /(.*)(\r\n|[\r\n])?/.exec(doc);
    var array = line[1].split(SEPARATOR);
    if (array.length >= 3) {
      var command = new Command();
      command.command = array[0];
      command.target = array[1];
      command.value = array[2];
      commands.push(command);
    }
    doc = doc.substr(line[0].length);
  }
  testCase.setCommands(commands);
}

function parse(testCase, source) { var doc = source; var commands = []; while (doc.length > 0) { var line = /(.*)(\r\n|[\r\n])?/.exec(doc); var array = line[1].split(SEPARATOR); if (array.length >= 3) { var command = new Command(); command.command = array[0]; command.target = array[1]; command.value = array[2]; commands.push(command); } doc = doc.substr(line[0].length); } testCase.setCommands(commands); }

More interesting is the following definition:

//Mapping: Selenium Commands on to Selenium Robot Keywords
var KEYWORDS = {
  type: "Input Text",
  select: "Select From List",
  verifyValue: "Textfield Should Contain"
  //[...]
};
 
//Separator for splitting commands(2 blanks)
var SEPARATOR = "  ";

//Mapping: Selenium Commands on to Selenium Robot Keywords var KEYWORDS = { type: "Input Text", select: "Select From List", verifyValue: "Textfield Should Contain" //[...] };//Separator for splitting commands(2 blanks) var SEPARATOR = " ";

Per default the generic “Call Selenium Api”-Keyword will be generated with the corresponding selenium method. But I think it’s more convenient, when we get the dedicated Robot Keywords directly. So we have to define a mapping here. It is also possible to substitute some keywords, when you have your own ones. I would suggest that you only create a mapping for a keyword, when you have already tested it with your application. So you can recognize it directly, when there is a “new” keyword, because you get “Call Selenium Api” in your testcase.

Installation

  1. Open the Selenium IDE
  2. Go to Options → Options… → Formats
  3. Add a new format definition with the name “robotframework-rc”
  4. Copy and paste the contents of the file “robotframework-rc.js” here

Usage

Now it is very easy to record the test case and get the Robot Keywords directly. Just select under Options->Clipboard Format the entry “robotframework-rc”. In general, I would not suggest to record complete test runs with the Selenium IDE and copy it 1:1 to a Robot Test, because one of the main goals of keyword-driven-testing is reusability 😉 But the initial recording of some basic workflows is now very easy.

Selenium IDE

Robot Framework Keywords

Select From List  feldId  Test
Input Text  feldId2  AnotherValue
Textfield Should Contain  feldId  Test

Select From List feldId Test Input Text feldId2 AnotherValue Textfield Should Contain feldId Test

The complete code is available at https://github.com/denschu/selenium-ide-format-robotframework. Feedback is very welcome 🙂 In my next blog post I will show you the implementation of your own locators in selenium.