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.comcmd=
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