Testing with Selenium TestRunner

I know, I know its been two weeks since I posted. . . but I hope this makes it worth the wait!

I've looked at Selenium a few times but just couldn't fathom how it could possibly work -- and with all javascript?? I went to a Ruby "HackFest" here in my beautiful city of Chicago and met one of the developers of Selenium , Jason. He gave a demonstration of Selenium testing itself and I saw how it worked, but how do I get it to work? As it turned out, in my traditional fashion, I was making it harder than it really was.

First thing, get a copy of Selenium. There are two approaches to testing with Selenium: TestRunner and Driven. I'm using TestRunner. I got the subversion development branch (you won't see the checkbox and X graphics in that version, I added that myself to my copy). There is a default directory "javascript/tests" containing the tests for Selenium itself. You can create another directory and specify it on the url, but I renamed the existing one to "test_sel" and used "test" for my own devices.

I needed a project to test. So I took DotProject a wonderful project management tool created in PHP (no, has nothing to do with .NET). It should be a good project to give Selenium a test run (no pun intended!) since it has a lot of interaction including login, add/edit/delete things, javascript events, javascript popup windows etc.

You can follow along with this by this going to my test site at:
http://test.devasap.com/sel/TestRunner.html

And you might also open the Selenium documentation to refer to as well.

To run the tests, Click on the name of the test in the list in the top left pane. Then in the top right pane, click the Walk (just goes a bit slower so you can see what’s happening) radio option and then click Selected. If you click All, of course it will run all of them. But for following along use the Selected mode. I haven’t figured out the Step / Continue mode yet.

First I made a test suite file, which is a simple single column HTML table with the first row as a title (ignored by Selenium) and each row with the name of a test as a simple link.

(table properties don't matter, I just picked ones I liked)

Nola's Test
Login and Logout Test
Project Test

For these two tests: "Login and Logout Test" and "Project Test" they are a page with a html table with 3 columns. The top cell should be merged into one and have a title. Too simple, eh?

Now for the tests themselves:

Login / Logout Test
open /dotproject/index.php  
type name=username admin
type name=password passwd
clickAndWait name=login  
pause 2000  
assertTextPresent Welcome Admin Person  
clickAndWait link=Logout  

1. Open the url, which in this case is "/dotproject/index.php"
2. Then you instruct Selenium to "type" your username and password. "name" refers to the name attribute in the form tag.
3. Issue a clickAndWait, that will click the submit button name="login" and wait for the page to load.
4. Pause for 2000 milliseconds. Sometimes depending on the load of the server, it will still timeout after a clickAndWait.
5. Assert that text "Welcome Admin Person" is on the page. If it you did not see that then you would not be successfully logged in.
6. Click on the link=Logout to end the test. Link is the actual text in the logout href. If your logout was Exit this funky program then you would put link=Exit this funky program. If you ordered the tests correctly you could make the first test in the suite login and the last test logout. However I'd rather keep each test isolated isolated from the others. The documentation has some clues on how to make a setup and teardown script that you could use.

And for my next test, I do a little planning:

  1. Login
  2. Go to Projects section
  3. Click on New Project to create new project
  4. Fill in some project data
  5. Save Project
  6. View Project
  7. Delete Project
  8. Logout
Login / Logout Test
open /dotproject/index.php  
type name=username admin
type name=password passwd
clickAndWait name=login  
clickAndWait link=Projects  
assertTextPresent All Projects  
fireEvent dom=document.forms[2] submit
pause 2000  
type name=project_name Test Project by Selenium
fireEvent name=project_name onblur
select name=project_company value=4
type name=project_color_identifier 990099
select name=project_priority label=high
pause 2000  
type name=project_description This is a description for my test project
clickAndWait name=btnFuseAction onClick
pause 1500  
assertTextPresent Project inserted  
select name=department value=company_4
pause 1500  
clickAndWait link=Test Project by Selenium  
pause 1500  
clickAndWait link=delete project  
verifyConfirmation Are you sure you want to delete this Project?  
assertTextPresent Project deleted  
clickAndWait link=Logout  

Explanation:
1. Login, type username, wait, (yeah, yeah forgot the pause in this one, if you have problems let me know) as in previous test.
2. Click on Projects link and wait
3. Assert that "All Projects" text visible on page
4. Click on "add projects" sometimes its difficult to get at the element you need. I had to use the dom to locate the submit button in this case. fireEvent will make any event fire (submit, click, blur, focus). Nifty.
5. Pause. Sometimes if you have a problem getting at an element, put a pause in there. I had a hard time with this, because sometimes it would work and sometimes not. $%!*# Just depended on server load. So use a Pause when you load something, just in case.
6. Enter a name in the Project Name field
7. Fire the onBlur event so it will call fill the short name automatically
8. Set the Project Color (I like purple)
9. Set the Project Priority to the select element who's label is "high"
10. Don't know why I threw a Pause in there. Maybe for a coffee break.
11. Type project description
12. Click on submit button who's name is "btnFuseAction"
13. Pause for good measure.
14. Assert that the action was successful by checking the page says "Project inserted"
15. Change the dropdown to display companies with value=4 (couldn’t get the label to work for some reason)
16. Now you can see the project in the list, so click the link who's text is "Test Project by Selenium" and wait.
17. Pause for good measure.
18. Click link for "delete project"
19. This action pops up a javascript alert box. Selenium will ALWAYS click ok unless you specify the command to cancel, but it will click it and give you an error if you haven't done a verifyConfirmation.
20. Assert that "Project deleted" is visible
21. Click the Logout link

And there you have a test. Any time you make changes to the code you can go back to this test, run it again and make sure you didn't break anything. The documentation talks about how you can even automate this process and have the output sent to a file.

There’s a Firefox extension that will help you make tests, but I haven’t tried it yet:

Cool huh? I had some problems finding elements on the page whether using dom, id, name, xpath but if you code your page right with "id" on elements (that’s what I would do) I think it would be much easier to write tests in Selenium.

I will have this available for testing for at least a few days at: http://test.devasap.com/sel/TestRunner.html

Resources: