By now, I’ve already created a new solution for testing my Selenium Unit Tests. I named my solution ‘SeleniumTesting.sln’. I created a new Unit Test Class, and copied the C# code generated by Selenium IDE into my new Unit Test Class. I renamed the NUnit test attributes to Microsoft Unit Test Attributes (see previous post). I was to the point of testing, and then I discovered that I hadn’t started Selenium Server. I ran the server on the same machine on which I had both the Unit Test Solution, my Web Application, and Selenium Server running. I was just at the point where I needed to run Selenium Server on a separate machine, and test how it worked that way.
Fortunately, I just happen to have a desktop nearby that nobody else is using. It’s got Windows XP Professional, but I don’t remember seeing any hard and fast limitations to running Selenium server, so I copied the folder from my laptop to the desktop. I terminal service into the desktop (which I guess you could call a server the way I use it), and go the ‘c:\Selenium\selenium-server-1.0.3′ folder (where I copied Selenium Server to). I navigated to the folder, and double-clicked on selenium-server.jar. It’s now up and running. You can’t really tell, it’s running as a javaw process. I started the test, and the first thing I noticed was that in my remote desktop, a console popped up along with a web browser.
As each command executed, the Command History would display the command. At the same time, the browser would show the command output. As I let it run through, everything worked fine until the:
Test method SeleniumTesting.InitialSeleniumTest.TestMethod threw exception: Selenium.SeleniumException: Timed out after 5000ms.
I tried adding a Click-And-Wait command. Since Selenium is a JavaScript-based tool, I checked my IE version. The desktop was running IE6. I rashly concluded that this was the problem, and proceeded to test again on my laptop, just to be sure. Imagine my surprise when I got the same error, but at a different place in code!!
With some pretty fancy research (if I say so myself – inasmuch as research can be fancy), I discovered the following:
- Selenium 1.0.3 does not seem to like IE6. It’s as if the ‘WaitForPageLoad’ gives up the ghost. I never got it to load successfully.
- Depending on network connectivity, Selenium RC varies how quickly it access a page. This means that about half of the time, the client attempts to access the page before the elements are rendered. WaitForPageLoad is wonky, too, and doesn’t really work with my .NET web application.
- selenium.SetSpeed(string) is your friend. This is the way to make sure that the page is loaded before attempting to access an element. Mine seems to work all right set at “1000″.
- selenium.SelectWindow(null) is your friend, too. Believe it or not, every once in a while, the client will lose focus on the browser. I haven’t yet figured out what it’s focusing on (as I don’t have infinite time), but it seems like, in those cases, SelectWindow(null) is sufficient.
- Beware selenium.Select/selenium.Click combinations. ‘Select’ selects an option in drop-down. ‘Click’ will click an Element. When recording, if the tester clicks an option, it may record both the act of selection and act of clicking. In playback, the selection will trigger the click event (in .NET), and the clicking will attempt to click an element which no longer exists because the page is being refreshed if the drop-down has AutoPostback.
- For Developers: Beware Dynamically-Named Controls. Selenium uses a number of things to determine which control you are trying to click. It seems to check the control ‘id’ attribute first. If, like we had in some legacy code, someone thinks it’s a good idea to use a GUID.NewGuid().Replace(“-”, “_”) as a control id, smack them on the head. Offhand, I can’t think of any reason, ever, to do this. If you have so many controls on your page that you need GUIDs to identify them, your application will most likely not run. Dynamically-created controls should be named in a predictable, consistent manner, so that Selenium can correctly identify them.
- Selenium.SeleniumException: ERROR: Element ctlName not found. This is a common error. The error happens in response to the selenium.Select/selenium.Click problem I’ve mentioned (5 above), as well as if a page doesn’t load quickly enough. You can use the
selenium.WaitForPageToLoad("5000");
to give yourself more time. In my situation, I initially got the error so frequently that I almost threw out Selenium as a tool, until I met
selenium.SetSped("1000");
. The command sets the delay between actions in milliseconds. Sweet!
So, Selenium, at this point, still seemed promising to me. Unfortunately, the version of the test that testers would record is going to have to be significantly changed before the test can actually be used as a unit test. The changes, though, are pretty consistent, and to me, worth the pain in order to have good regression testing. Selenium is not the be-all-end-all, by any means. If I had ten-thousand dollars, I would buy something different, possibly. In the perfect case, I would go ahead and invest in extending our TFS/Visual Studio infrastructure to include Microsoft’s testing package (out w/VS 2010).
For part 6, I’m going to start setting up the infrastructure. I got our infrastructure guy to set up a virtual server for me, and a virtual workstation. I’ll keep you posted on how that works out.

