View Javadoc

1   /*
2       Jameleon Selenium plug-in - A plug-in that uses Selenium (http://www.openqa.org/selenium/) to drive web sites
3       Copyright (C) 2006 Christian W. Hargraves (engrean@hotmail.com)
4       
5       This library is free software; you can redistribute it and/or
6       modify it under the terms of the GNU Lesser General Public
7       License as published by the Free Software Foundation; either
8       version 2.1 of the License, or (at your option) any later version.
9   
10      This library is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13      Lesser General Public License for more details.
14  
15      You should have received a copy of the GNU Lesser General Public
16      License along with this library; if not, write to the Free Software
17      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19  package net.sf.jameleon.plugin.selenium;
20  
21  import net.sf.jameleon.SessionTag;
22  import net.sf.jameleon.exception.JameleonException;
23  import net.sf.jameleon.function.ContextHelper;
24  import net.sf.jameleon.plugin.selenium.util.SeleniumProxyServer;
25  import net.sf.jameleon.util.StateStorer;
26  
27  import org.openqa.selenium.server.SeleniumServer;
28  import org.openqa.selenium.server.SingleEntryAsyncQueue;
29  
30  import com.thoughtworks.selenium.DefaultSelenium;
31  import com.thoughtworks.selenium.Selenium;
32  
33  /***
34   * A Session tag for the Selenium plug-in.
35   * 
36   * An example of its use might:
37   * 
38   * <pre><source>
39   * &lt;testcase xmlns="jelly:jameleon"&gt;
40   *     &lt;selenium-session baseUrl="http://www.google.com" beginSession="true"&gt;
41   *       &lt;selenium-assert-title-equals
42   *           functionId="Check that title is Google."
43   *           title="Google"/&gt;
44   *     &lt;/session-session&gt;
45   * &lt;/testcase&gt;
46   * </source></pre>
47   *
48   * @jameleon.function name="selenium-session"
49   */
50  public class SeleniumSessionTag extends SessionTag {
51  
52      /***
53       * @jameleon.attribute contextName="baseUrl"
54       */
55      protected String baseUrl;
56      /***
57       * @jameleon.attribute contextName="beginAt"
58       */
59      protected String beginAt;
60      /***
61       * @jameleon.attribute contextName="seleniumBrowser" default="*firefox"
62       */
63      protected String browser;
64      /***
65       * @jameleon.attribute default="false" contextName="seleniumMultiWindowMode"
66       */
67      protected boolean multiWindowMode;
68      /***
69       * @jameleon.attribute default="false" contextName="seleniumStopProxyServerOnSessionClose"
70       */
71      protected boolean stopProxyServerOnSessionClose;
72      /***
73       * @jameleon.attribute contextName="startSeleniumProxy" default="false"
74       */
75      protected boolean startSeleniumProxy;
76      /***
77       * @jameleon.attribute contextName="seleniumProxyHost" default="localhost"
78       */
79      protected String seleniumProxyHost;
80      /***
81       * @jameleon.attribute contextName="seleniumProxyPort" default="4444"
82       */
83      protected int seleniumProxyPort;
84      /***
85       * @jameleon.attribute contextName="seleniumTimeoutSeconds" default="1800"
86       */
87      protected int timeoutSeconds;
88  
89      /***
90       * A handle on the Selenium server session
91       */
92      protected Selenium session;
93      /***
94       * @jameleon.attribute default="false" contextName="seleniumSlowResourcesMode"
95       */
96      protected boolean slowResourcesMode;
97  
98      /***
99       * Deregister this tag as a storable
100      */
101     protected void deregisterStorable(){
102         StateStorer.getInstance().removeStorable(this);
103     }
104 
105     /***
106      * Gets the url to request
107      * 
108      * @return The URL to use in startApplication.
109      */
110     protected String getRequestUrl(){
111         String url = getBaseUrl();
112         if (getBeginAt() != null) {
113             url += getBeginAt();
114         }
115         return url;
116     }
117 
118     /***
119      * Gets the base URL, including the protocol (http://), the domain name and any path informtion.
120      * 
121      * @return the base URL.
122      */
123     public String getBaseUrl(){
124         return baseUrl;
125     }
126 
127     /***
128      * Gets the trailing path of the URL to begin the browser at if set.
129      * 
130      * @return the trailing path of the URL to begin the browser at if set.
131      */
132     public String getBeginAt(){
133         return beginAt;
134     }
135 
136     /***
137      * Gets the browser to run the selinium tests under.
138      * @return The broswer to use.
139      */
140     public String getBrowser(){
141         return ContextHelper.getValueAsStringWithConfig(context, "seleniumBrowser", "seleniumBrowser", browser);
142     }
143 
144     /***
145      * Gets the Selenium multi window mode. If set to true, then selenium will run the tests under a different window
146      * as opposed to in the same frame
147      * @return The Selenium multi window mode.
148      */
149     public boolean getSeleniumStopProxyServerOnSessionClose(){
150         return ContextHelper.getValueAsBooleanWithConfig(context, "seleniumStopProxyServerOnSessionClose", "seleniumStopProxyServerOnSessionClose", stopProxyServerOnSessionClose);
151     }
152 
153     /***
154      * Gets the Selenium proxy host to connect to.
155      * @return The Selenium proxy host to connect to
156      */
157     public String getSeleniumProxyHost(){
158         return ContextHelper.getValueAsStringWithConfig(context, "seleniumProxyHost", "seleniumProxyHost", seleniumProxyHost);
159     }
160 
161     /***
162      * Gets the Selenium multi window mode. If set to true, then selenium will run the tests under a different window
163      * as opposed to in the same frame
164      * @return The Selenium multi window mode.
165      */
166     public boolean getMultiWindowMode(){
167         return ContextHelper.getValueAsBooleanWithConfig(context, "seleniumMultiWindowMode", "seleniumMultiWindowMode", multiWindowMode);
168     }
169 
170     /***
171      * Gets the Selenium proxy port to connect to.
172      * @return The Selenium proxy port to connect to
173      */
174     public int getSeleniumProxyPort(){
175         return ContextHelper.getValueAsIntWithConfig(context, "seleniumProxyPort", "seleniumProxyPort", seleniumProxyPort);
176     }
177 
178     /***
179      * Gets the Selenium slow resources mode. If set to <code>true</code>, the test will run more slowly to help with debugging.
180      * @return The Selenium proxy host to connect to
181      */
182     public boolean getSlowResourcesMode(){
183         return ContextHelper.getValueAsBooleanWithConfig(context, "seleniumSlowResourcesMode", "seleniumSlowResourcesMode", slowResourcesMode);
184     }
185 
186     /***
187      * Gets the Selenium timeout in seconds.
188      * @return The Selenium timeoutSeconds
189      */
190     public int getTimeoutSeconds(){
191         return ContextHelper.getValueAsIntWithConfig(context, "seleniumTimeoutSeconds", "seleniumTimeoutSeconds", timeoutSeconds);
192     }
193 
194     /***
195      * Set the Selenium proxy server to start when the session
196      * starts. If this is set to false (the default), then the proxy
197      * server will need to be started manually.
198      */
199     public boolean isStartSeleniumProxy(){
200         return ContextHelper.getValueAsBooleanWithConfig(context, "startSeleniumProxy", "startSeleniumProxy", startSeleniumProxy);
201     }
202 
203     /***
204      * Gets the Selenium session used to communicate with the web application
205      * 
206      * @return Selenium
207      */
208     public Selenium getSession(){
209         return session;
210     }
211 
212     /***
213      * Register this tag as a storable
214      */
215     protected void registerStorable(){
216         StateStorer.getInstance().addStorable(this);
217     }
218 
219     protected void createSession(){
220         if (getBaseUrl() != null) {
221             session = new DefaultSelenium(getSeleniumProxyHost(), getSeleniumProxyPort(), getBrowser(), getBaseUrl());
222         } else {
223             throw new JameleonException("'baseUrl' is a required field if beginSession is set to 'true'!");
224         }
225     }
226 
227     public void setUpSession(){
228         if (isStartSeleniumProxy()) {
229             startSeleniumProxyServer();
230         }
231         createSession();
232         startSession();
233     }
234 
235     public void tearDownSession(){
236         if (session != null) {
237             try {
238                 session.stop();
239             } catch (Throwable t) {
240                 //This just means the session wasn't started.
241             }
242             session = null;
243         }
244         if (isStartSeleniumProxy()) {
245             stopSeleniumProxyServer();
246         }
247     }
248 
249     /***
250      * Start a selenium proxy server
251      */
252     protected void startSeleniumProxyServer(){
253         SeleniumProxyServer spServer = SeleniumProxyServer.getInstance();
254         if (spServer.getSeleniumServer() == null) {
255             SingleEntryAsyncQueue.setDefaultTimeout(getTimeoutSeconds());
256             try {
257                 System.setProperty("selenium.log", "selenium-proxy.log");
258                 SeleniumServer seleniumProxyServer = new SeleniumServer(seleniumProxyPort, getSlowResourcesMode(), getMultiWindowMode());
259                 spServer.setSeleniumServer(seleniumProxyServer);
260                 spServer.setTimeoutSeconds(getTimeoutSeconds());
261                 spServer.startUp();
262                 synchronized (this){ 
263                     try {
264                         this.wait(50); 
265                     } catch (InterruptedException e) {
266                         e.printStackTrace(); 
267                     }
268                 }
269             } catch (Exception e) {
270                 throw new JameleonException("Could not start SeleniumServer!", e);
271             }
272         }
273     }
274 
275     protected void startSession(){
276         try {
277             if (session != null) {
278                 session.start();
279             }
280         } catch (Exception e) {
281             String errMsg = "Could not start Selenium!";
282             if (e.getMessage() != null) {
283                 errMsg = e.getMessage();
284             }
285             throw new JameleonException(errMsg, e);
286         }
287     }
288 
289     /***
290      * Start a selenium proxy server
291      */
292     protected void stopSeleniumProxyServer(){
293         if (getSeleniumStopProxyServerOnSessionClose()) {
294             SeleniumProxyServer sps = SeleniumProxyServer.getInstance();
295             if (sps.getSeleniumServer() != null) {
296                 sps.shutDown();
297             }
298         }
299     }
300 
301     /***
302      * Loads the URL given by <b>beginAt</b> and <b>baseUrl</b>.
303      */
304     public void startApplication(){
305         session.open(getRequestUrl());
306     }
307 
308 }