Not every Python programmer have to know HTML to use Selenium. Although tests format uses only <table>'s, <tr>'s and <td>'s it still consumes too much place and is hard to modify and maintain. With this script you'll be able to write Selenium commands in Python language. Before running Selenium, execute this script on your .py tests and it will generate appropriate .html files.

    python source_directory destination_directory

Files in source_directory that doesn't start with '_' will be parsed and HTML files will be generated from them. They will be saved to destination_directory along with index.html file which lists all tests so that Selenium Test Runner could find them.

You can also run with a file as a argument:

python source_file [ destination_file ]

Source file will be parsed and saved to destination file. If second argument is not present, name of original file will be used, with extension changed to .html. Not index.html will be created.

Test source files format is minimalistic. Use docstring at the beginning of test as its description. Selenium commands are defined with S() function which requires 1-3 arguments. They correspond to the standard "command", "target" and "value" arguments of Selenium command. If you want to open an script, simply write:

S('open', '')

Compare it to the standard Selenium code:


Commands can also be written in more Pythonic fashion, changing first argument string to method call:'')

List of commands is not closed or binded to specific Selenium version, so you can use any arbitrary string and you won't be warned. This is needed for future compatibility.

make_selenium understands both CamelCase and underscore_names notation. So you can either write S.clickAndWait or S.click_and_wait.

As an addition, lines that contain nothing but a comment will be listed line by line in a test files, put into an unordered list ( <ul> ).

Of course that's not the end of features. Because now you can use Python to write tests, why not to use its power? See how easy it is to check different e-mail addresses in your web application form. No more copy-and-paste!

bogus_addresses = [

for address in bogus_addresses:
    S.type('mail', address)
    S.assertTextPresent('Bogus address!')

Now you have five automated tests of your e-mail checker. Adding another is a matter of adding another element to bogus_addresses list.

Some tests require to fill in a lot of input fields, as well as checking long lists of field's values. This script doesn't support you with a function that generates more that one command. But remember you have Python in your hands. Define function F() that wraps 'type' command and function A() that wraps 'assertValue':

def F(mapping):
    for key, value in mapping.iteritems():
        S.type(key, value)

def A(mapping):
    for key, value in mapping.iteritems():
        S.assertValue(key, value)

Both of them take a dictionary of field name -> value pairs. So, when you need to check if certain fields don't loose their values after a submit, just write:

data = {
    'forename': 'John',
    'surname': 'Smith',
    'age': '25',


Wasn't that nice?

Knowing how easily this system can be extended you would probably end up creating your own little library of handy functions. To include definitions from other file use I() function. It takes one argument which is path to a file you want to include (relative to the source_directory given on the command line). It works more like C preprocessor #include directive than Python import, as all symbols defined go to common namespace.

But that's not all. With you can combine two powerful tools: Selenium IDE and Python. Selenium IDE can record tests directly from your browser, so it's easy to create new tests. Its main disadvantage is HTML output, native format for the Selenium, but hard to maintain and modify. But that's not a problem for make_selenium. You can convert your old tests from HTML to Python, using -p option:

python -p source_file [ destination_file ]

You can also convert whole bunch of tests:

python -p source_directory destination_directory

As you see, migrating to is very easy and straightforward.

Author: MichaƂ Kwiatkowski
Last modified: 14 April 2006

Technorati tags: