summaryrefslogtreecommitdiff
path: root/tests/FunctionalTests/selenium/doc/driven.html
blob: a5f33dff3985d5120372b7f51058381273dd87df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="generator"
 content="Docutils 0.3.6: http://docutils.sourceforge.net/">
  <title>Driven Selenium Reference</title>
  <link rel="stylesheet" href="default.css" type="text/css">
</head>
<body>
<div class="document" id="selenium-reference">
<div class="section" id="test-tables">
<h2><a name="test-tables"></a>Overview</h2>
Driven Selenium is where the browser is under the the control of an
adjacent process. That process is either a Java, .Net, Ruby or Python
application and it is typically run in conjunction with a unit testing
framework like JUnit or NUnit. Also possible, is a console application
driving a browser interactively.<br>
<h2>Selenium &amp; Selenese</h2>
The key to this mode of operation is manner in which the browset-bot
takes instruction from the driver.&nbsp; If it were possible, the
browser-bot's javascript would open a server socket and await requests
from the driver. It is against the rules for browser embedded
javascript, to open ports for incoking requests as it would be a
general breach of security for the client-OS that the browser is
running on.&nbsp; What a browser can do is open addition requests to
the same server that its source came from. See <a
 href="http://www.mozilla.org/projects/security/components/same-origin.html">http://www.mozilla.org/projects/security/components/same-origin.html</a>
for more info.<br>
<br>
To overcome the limitations of Javascript in a browser page is the page
continuously requests pages from the driver (which has conveniently
opened a web server). The pages which are retrieved from the server are
in fact plain text and each is an individual instruction from the
driver for what the browser-bot is to do next.&nbsp; E.g. - <br>
<br>
&nbsp;&nbsp;&nbsp; | open | /foo/bar.html | |<br>
<br>
We refer to this architecture are reply/request rather than the more
ususal request/reply.<br>
<h2><a name="test-tables">Sample test method<br>
</a></h2>
The test script is one that would be recognisable to people adept with
unit test frameworks :<br>
<br>
For Java -<br>
<br>
&nbsp; public void testOKClick() {<br>
&nbsp;&nbsp;&nbsp; selenium.verifyTitle("First Page");<br>
&nbsp;&nbsp;&nbsp; selenium.open("/TestPage.html");<br>
&nbsp;&nbsp;&nbsp; selenium.click("OKButton");<br>
&nbsp;&nbsp;&nbsp; selenium.verifyTitle("Another Page");<br>
&nbsp; }<br>
<br>
The difference from normal unit testing is that as part of the startup,
three major things have to happen:<br>
<ol>
  <li>The test framework needs to publish a fresh copy of the
Application Under Test (AUT).
Selenium prefers to mount its own web server temporarily for the
purposes of testing.</li>
  <li>The test framework needs to publish the static Selenium pages
(refer selenium dir in TestRunner mode above) in an apparent directory
on the same web server as (1).</li>
  <li>The test framework needs to open a browser instance and point it
to Selenium.html served in (2) above.</li>
</ol>
As each of these isa fairly time consuming operation, it is best that
all three of those happen in a one time setup mode.&nbsp; As such, and
even though these leverage a unit testing framework, this is definately
for acceptance or functional testing.<br>
<h2>Example Setup<br>
</h2>
</div>
<div class="section" id="continuous-integration">For Java -<br>
<br>
&nbsp;&nbsp; selenium = new DefaultSelenium("c:\foo\bar-web-app\");<br>
<br>
The above will instantiate a web server using <a
 href="http://jetty.mortbay.com/jetty/index.html">Jetty</a>, and
publish it at http://localhost:8080. The Selenium pages will appear to
be run from http://localhost:8080/selenium-driver. The default browser
for Windows, Linux or Mac will be instantiated and directed to accept
test instructions from the driver.<br>
<br>
The above would ususally be done in a setup method if under unit test
control.&nbsp; See <a
 href="http://junit.sourceforge.net/doc/faq/faq.htm#organize_3">http://junit.sourceforge.net/doc/faq/faq.htm#organize_3</a>
for advice on one time setup for Java.<br>
&nbsp;<br>
A more complex case could be -<br>
<br>
&nbsp; selenium = new DefaultSelenium(new
TomcatCommandProcessor("c:\foo\bar-web-app"), new
MyOperaBrowserLauncher()), <br>
<h2>Command Reference</h2>
&nbsp;&nbsp;&nbsp; void chooseCancelOnNextConfirmation();<br>
&nbsp;&nbsp;&nbsp; void click(String field);<br>
&nbsp;&nbsp;&nbsp; void clickAndWait(String field);<br>
&nbsp;&nbsp;&nbsp; void open(String path);<br>
&nbsp;&nbsp;&nbsp; void pause(int duration);<br>
&nbsp;&nbsp;&nbsp; void selectAndWait(String field, String value);<br>
&nbsp;&nbsp;&nbsp; void selectWindow(String window);<br>
&nbsp;&nbsp;&nbsp; void setTextField(String field, String value);<br>
&nbsp;&nbsp;&nbsp; void storeText(String element, String value);<br>
&nbsp;&nbsp;&nbsp; void storeValue(String field, String value);<br>
&nbsp;&nbsp;&nbsp; void testComplete();<br>
&nbsp;&nbsp;&nbsp; void type(String field, String value);<br>
&nbsp;&nbsp;&nbsp; void typeAndWait(String field, String value);<br>
&nbsp;&nbsp;&nbsp; void verifyAlert(String alert);<br>
&nbsp;&nbsp;&nbsp; void verifyAttribute(String element, String value);<br>
&nbsp;&nbsp;&nbsp; void verifyConfirmation(String confirmation);<br>
&nbsp;&nbsp;&nbsp; void verifyElementNotPresent(String type);<br>
&nbsp;&nbsp;&nbsp; void verifyElementPresent(String type);<br>
&nbsp;&nbsp;&nbsp; void verifyLocation(String location);<br>
&nbsp;&nbsp;&nbsp; void verifySelectOptions(String field, String[]
values);<br>
&nbsp;&nbsp;&nbsp; void verifySelected(String field, String value);<br>
&nbsp;&nbsp;&nbsp; void verifyTable(String table, String value);<br>
&nbsp;&nbsp;&nbsp; void verifyText(String type, String text);<br>
&nbsp;&nbsp;&nbsp; void verifyTextPresent(String type, String text);<br>
&nbsp;&nbsp;&nbsp; void verifyTitle(String title);<br>
&nbsp;&nbsp;&nbsp; void verifyValue(String field, String value);<br>
<h2>Deployment Choices</h2>
<h3>Embedded Web Server</h3>
<p>
<img alt="Picture of Browser and Driving process" src="images/Embedded.png"
 style="width: 518px; height: 302px;" align="top"><br>
The best way to deply the driven form of Selenium is where an embedded
web server is used. With the Java version, this could be <a
 href="http://jetty.mortbay.com/jetty/index.html">Jetty</a> or <a
 href="http://jakarta.apache.org/tomcat/">Tomcat</a>. <br>
<br>
In advance of a series of selenese instructions being issued to the
browser, a web server containing the AUT and some static pages for
Selenium itself will be programmatically started and used to
communicate selenese instructions to the browser.&nbsp; When the driver
process is complete the web server will be programmatically stopped. <br>
</p>
<p style="color: rgb(255, 0, 0);">[ For release 0.2 - this is the only
mode that really works. Those below will be fine for 0.3 and above ]<br>
</p>
<h3>Adjacent Web Server</h3>
<img alt="diagram of adjacent config" src="images/Adjacent.png"
 style="width: 534px; height: 572px;"><br>
By adjacent we mean a process on the same machine as the driver. As
such it would appear as localhost to browsers. <br>
<br>
For the .Net driver embedded is very unlikely as Internet Information
Server is running in its own process. For the Java driver, this could
simple be a necessary choice - i.e. the deployment target is WebLogic
or
WebSphere which are not too embeddable.&nbsp; <br>
<br>
In this scenario we suggest you deploy a small web-app alongside the
AUT that will liase between the driver process and the browser. Of
course, there is less fine grained control over the starting and
stopping of the server and indeed the version of the AUT. If the web
server supports it, it is best to copy a fresh version of the AUT to
the underlying directory that the web-app is mapped to. We call the
small web-app the selenese proxy. It does of course slow things down a
fraction.<br>
<span style="font-weight: bold;"><br>
Selenese-proxy</span><br style="font-weight: bold;">
<br>
If you can deploy a copy of the selenese proxy to remote web server,
and configure it to forward requests to your machine, then you can
essentially script that remote web app. The downside of this is that
that remote machine can essentially only be driven from the machine
that is configured to drive it. i.e. it would need to be reconfigured
to be driven from elsewhere. The upside is that you can to a great
extent mix and match your technologies to achieve this proxying (a Java
driver could use a Python selenese-proxy script a web-app).<br>
<h3>Nearby Web Server <br>
</h3>
This is where the AUT is running on a nearby testing stack or dedicated
development box (not the developer's own workstation).<br>
<br>
To achieve this the selenese proxy needs to be deployed again, this
time to that nearby machine. It will need to be reconfigured to
indicate that selenese traffic is either forwarded to a particular
machine.<span style="font-weight: bold;"><br>
</span>
<h3>Remote Web Server <br>
</h3>
This is where the AUT is running on a remote machine, which you have no
control over.&nbsp; A good example would be www.google.com.&nbsp; It is
worth pointing out that this is of more interest to hackers or data
harvesters than testing professionals, as what self respecting
development group would prevent you from deploying at least the
Selenese Proxy webapp to a testing stack.<br>
<span style="font-weight: bold;"><br>
Funnel</span><br style="font-weight: bold;">
<br>
We are writing an application called the funnel that can help us
overcome the <a
 href="http://www.mozilla.org/projects/security/components/same-origin.html">same
origin</a> issue that is key to Selenium. It essentially makes a
selenium-driver/ directory appear on a remote web site for the purposes
of the browser.<br>
<br>
<br>
</div>
</div>
</body>
</html>