Friday, August 24, 2012

Programming a Selenium RC Test


Programming a Selenium RC Test
Now that you know how to run commands in interactive mode, let's code this test up! Here's examples of writing the test we just wrote in six different programming languages: 
 
use WWW::Selenium;
use Test::More;
 
plan tests => 1;
 
my $browser = WWW::Selenium->new( host => "localhost", 
                              port => 4444, 
                              browser => "*iexplore", 
                              browser_url => "http://www.google.com";,
                            );
$browser->start();
$browser->open("http://www.google.com?hl=en");
$browser->type("q", "hello world");
$browser->click("btnG");
$browser->wait_for_page_to_load(5000);
like($browser->get_title(), qr/Google Search/);
$browser->stop();



As you were running your tests, you may have noticed that your browser started at the following URL:
http://www.google.com/selenium-server/RemoteRunner.html?sessionId=260113
That's a rather unusual URL, because, of course, there is no such file available on www.google.com. If you open up your browser manually and browse to that URL, you'll get a 404 error. What's going on?
The Selenium Server is attempting to circumvent a very difficult problem in JavaScript automated testing: normally, JavaScript you write yourself can't be run on google.com, due to a policy known as the same origin policy. (That write-up is from the Mozilla website, but all modern JavaScript browsers enforce this policy.) The same origin policy states that JavaScript is only allowed to read/modify HTML from the same origin as its source.
That policy makes a lot of sense. Let's say you've got your browser window pointing at, for example, your bank's website, but you also have another webpage open pointing to someone's blog. JavaScript is allowed to read values from web pages, as well as change data appearing on webpages you've loaded. If not for the same origin policy, a malicious blogger could read your bank data, or worse, rewrite your bank page to make you think it was saying something else. The blogger could use JavaScript to trick you into giving him sensitive information.
Despite the soundness of the policy, it creates a problem for Selenium automated tests. If you write a .js file designed to test google.com, the same origin policy denies you the right to just run that .js file with google.com; instead, you'd have to somehow install that .js file on google.com in order to write automated tests against it. In the case of google.com we don't have the right to do this; but even if we did, it would be a hassle to do so.
That's where the Selenium Server comes in. The Selenium Server is acting as a client-configured proxy for the browser that you automatically started with "getNewBrowserSession". Specifically, it configures your browser to use the Selenium Server as a proxy in its browser preferences.
A proxy normally fetches HTML pages on your behalf; if a page can't be found, it honestly reports that the page wasn't there. But the Selenium Server is a very different kind of proxy; when the browser requests a page through the proxy that contains "/selenium-server/" in its URL, the Selenium Server doesn't simply fetch the page from the remote server, but instead automatically returns its own page instead. That makes the browser think that the remote server served up our JS, which allows us to "inject" arbitrary JavaScript into google.com without modifying google.com directly.
However, the solution isn't perfect. Try running your tests like this:
cmd=getNewBrowserSession&1=*iexplore&2=http://www.yahoo.com
cmd=open&1=http://www.google.com&sessionId=260113
cmd=type&1=q&2=hello world&sessionId=260113
In this case, the "start URL" was yahoo.com, so the browser opened to
http://www.yahoo.com/selenium-server/RemoteRunner.html?sessionId=260113
and then we tried to open up google.com (which did work...) and type "Hello World" into the search box. But yahoo.com doesn't have the right to modify google.com, so that operation fails.
All this means is that you have to choose your browser's start URL wisely: if you open up the browser to yahoo.com, you can't use it to test google.com, and vice versa.
However, in some cases, you may be required to test more than one domain at once. The most common case is when you need to test both http://blah.com and https://blah.com. "http:" and "https:" are considered different "origins" from JavaScript perspective, so tests running on one can't run on the other. In that case, for now, you'll have to use one of our experimental browser launchers which support running in multiple domains. (Also be sure to read the HTTPS section of this documentation for more details about HTTPS support.) 

Selenium Server can automatically launch/kill other browsers that we don't yet explicitly support. (Most of the browsers on the "Should Work" supported list need to be launched in this way.) When running your "getNewBrowserSession" command, use the "*custom" browser launcher instead of "*firefox" or "*iexplore", specifying the absolute path to your browser.
cmd=getNewBrowserSession&1=*custom c:\Program Files\Netscape\Netscape\Netscp.exe&2=http://www.google.com
Note that when we launch the browser in this way, you'll have to manually configure your browser to use the Selenium Server as a proxy. (Normally this just means opening your browser preferences and specifying "localhost:4444" as an HTTP proxy, but instructions for this can differ radically from browser to browser, so consult your browser's documentation for details.)
If you attempt to launch a *custom browser but don't configure the proxy correctly, you won't be able to get through even a simple Google test, because you'll get a 404 (File not found) error trying to access http://www.google.com/selenium-server/. Remember, that directory doesn't really exist on Google.com; it only appears to exist when the proxy is properly configured.
Also beware that Mozilla browsers can be a little fidgety about how they start and stop. Avoid launching your browser using a shell script; always prefer to use the binary executable directly. You may need to set the MOZ_NO_REMOTE environment variable to make Mozilla browsers behave a little more predictably.
If you want to use one of the explicitly supported browsers but have installed it in an unusual location, you can tell us that by using the special browser string followed by the absolute path to the executable.
cmd=getNewBrowserSession&1=*firefox c:\firefox\firefox.exe&2=http://www.google.com
That will automatically configure Firefox's proxy settings, but does not require you to add Firefox directly to the path. (You can use this to test multiple different versions of Firefox installed in separate directories.)
You can also use "*custom" to automatically launch a supported browser without configuring its proxy. For example, you could launch Firefox like this:
cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com
Again, note that you'll need to manually configure your proxy prior to launching Firefox in this way; otherwise you'll get a 404 error while following the steps in the tutorial.


By default, Selenium runs the application under test in a subframe. (Running the AUT in a subframe gives us a great deal of control over the AUT.) But some apps don't run properly in a subframe, preferring to be loaded into the top frame of the window. In that case, you need to make your application under test run in a seperate window rather than in the default frame. To do that, start selenium server with the -multiWindow parameter:
java -jar selenium-server.jar -multiWindow
Note that multiWindow mode is a little less stable than running in a frame, so you should probably avoid doing this if you can possibly help it.


Because of the unique proxy-based nature of Selenium RC, tests that require HTTPS can be a challenge. Our proxy attempts to examine and modify the HTTP requests being sent over the wire; HTTPS is explicitly designed to prevent anyone from doing that (even though, in our case, our intentions are benign).
Therefore, our proxy is configured to automatically generate dummy SSL certificates whenever you browse to an HTTPS site. Our dummy certificates are automatically signed by Selenium RC using a made-up certificate authority (CA) called "CyberVillains"; if your browser is configured to trust the CyberVillains CA, it will automatically trust our dummy certificates, allowing us to read/modify the content of your SSL requests.

No comments:

Post a Comment