View Javadoc

1   /*
2       Jiffie Plugin for Jameleon - An Internet Explorer plug-in for Jameleon
3       Copyright (C) 2004-2006 Christian W. Hargraves (engrean@hotmail.com) and
4                          Matthias Marschall (matthias@marschalls.de)
5   
6       This program is free software; you can redistribute it and/or modify
7       it under the terms of the GNU General Public License as published by
8       the Free Software Foundation; either version 2 of the License, or
9       (at your option) any later version.
10  
11      This program is distributed in the hope that it will be useful,
12      but WITHOUT ANY WARRANTY; without even the implied warranty of
13      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14      GNU General Public License for more details.
15  
16      You should have received a copy of the GNU General Public License
17      along with this program; if not, write to the Free Software
18      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20  package net.sf.jameleon.plugin.jiffie;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.Iterator;
25  import java.util.Vector;
26  
27  import net.sf.jameleon.SessionTag;
28  import net.sf.jameleon.Storable;
29  import net.sf.jameleon.plugin.jiffie.util.BrowserCache;
30  import net.sf.jameleon.plugin.jiffie.util.DialogListener;
31  import net.sf.jameleon.plugin.jiffie.util.IEEventListener;
32  import net.sf.jameleon.plugin.jiffie.util.JiffieEventHandlerFactory;
33  import net.sf.jameleon.util.Configurator;
34  import net.sf.jameleon.util.JameleonUtility;
35  import net.sf.jameleon.util.StateStorer;
36  
37  import net.sf.jiffie.ElementFactory;
38  import net.sf.jiffie.IHTMLBodyElement;
39  import net.sf.jiffie.IHTMLDocument2;
40  import net.sf.jiffie.InternetExplorer;
41  import net.sf.jiffie.JiffieException;
42  import net.sf.jiffie.JiffieUtility;
43  import net.sf.jiffie.TrackingElementFactory;
44  
45  /***
46   * This is a Jiffie implementation of the @see SessionTag. It basically starts the application
47   * in the state provided by the baseUrl and beginAt variables and creates a new session for
48   * the function points to share.
49   * 
50   * An example of its use might:
51   * 
52   * <pre><source>
53   * &lt;testcase xmlns="jelly:jameleon"&gt;
54   *     &lt;ie-session baseUrl="http://www.google.com" beginSession="true"&gt;
55   *       &lt;ie-validate
56   *           functionId="Check that title is Google."
57   *           title="Google"/&gt;
58   *     &lt;/ie-session&gt;
59   * &lt;/testcase&gt;
60   * </source></pre>
61   *
62   * @jameleon.function name="ie-session"
63   */
64  public class IESessionTag extends SessionTag implements BrowserCache, Storable {
65  
66      private static final boolean WAIT = true;
67  
68      /***
69       * If set to true, then Internet Explorer will be visible.
70       * @jameleon.attribute
71       */
72      protected boolean visible;
73      /***
74       * Used when the beginSession is set to true. This is the url, including protocol http://
75       *
76       * @jameleon.attribute contextName="baseUrl"
77       */
78      protected String baseUrl;
79      /***
80       * Used when the beginSession attribute is set to true. This the path to navigate to.
81       * It is recommended to only use baseUrl, including the entire path and not use this.
82       * @jameleon.attribute contextName="beginAt"
83       */
84      protected String beginAt;
85      /***
86       * If set to true, then any browsers opened by the session will be closed.
87       * Set this attribute to false to keep the browsers open.
88       * @jameleon.attribute default="true"
89       */
90      protected boolean closeIEOnExit;
91      /***
92       * The maximum time to wait before timing out. The default is one hundred twenty seconds.
93       */
94      protected int maxWaitTimeInSeconds = 120;
95      /***
96       * Click yes on the Security Alert dialog box if one appears after the session is started.
97       * @jameleon.attribute default="false"
98       */
99      protected boolean clickYesOnSecurityAlert;
100     protected boolean selectedYes;
101     /***
102      * Click no on the Security Alert dialog box if one appears after the session is started.
103      * @jameleon.attribute default="false"
104      */
105     protected boolean clickNoOnSecurityAlert;
106 
107     /***
108      * Turn on com.jacob.autogc
109      * @jameleon.attribute default="true"
110      */
111     protected boolean enableJacobAutoGc = true;
112     protected boolean selectedNo;
113 
114     /***
115      * The list of all open browser windows
116      */
117     protected Vector browsers = new Vector();
118 
119     private ElementFactory originalFactory;
120 
121     public void setUpSession() {
122         if (tc.isExecuteTestCase()) {
123             JiffieUtility.setMaxPollCount((maxWaitTimeInSeconds * 2));
124             setVariablesFromEnvironment();
125             System.setProperty("com.jacob.autogc", ""+enableJacobAutoGc);
126             TrackingElementFactory factory = new TrackingElementFactory();
127             originalFactory = JiffieUtility.setElementFactory(factory);
128             JiffieUtility.setEventHandlerFactory(new JiffieEventHandlerFactory());
129             InternetExplorer ie = new InternetExplorer();
130             new IEEventListener(ie, this);
131             ie.setVisible(visible);
132         }
133     }
134 
135     protected void setVariablesFromEnvironment(){
136         Configurator config = Configurator.getInstance();
137         visible = new Boolean(config.getValue("jiffie-plugin.visible", visible+"")).booleanValue();
138       
139         clickYesOnSecurityAlert = new Boolean(config.getValue("jiffie-plugin.clickYesOnSecurityAlert",clickYesOnSecurityAlert+"")).booleanValue();
140         clickNoOnSecurityAlert = new Boolean(config.getValue("jiffie-plugin.clickNoOnSecurityAlert",clickNoOnSecurityAlert+"")).booleanValue();
141         enableJacobAutoGc = new Boolean(config.getValue("jiffie-plugin.enableJacobAutoGc",enableJacobAutoGc+"")).booleanValue();
142     }
143 
144     /***
145      * todo integrate DialogListener with IEEventListener.
146      */
147     public void startApplication() {
148         String url = null;
149         if (beginAt != null && beginAt.length() > 0) {
150             beginAt = beginAt.startsWith("/") ? beginAt.substring(1) : beginAt;
151         } else {
152             beginAt = "";
153         }
154         url = baseUrl + beginAt;
155         String errMsg = null;
156         DialogListener dl = new DialogListener(clickYesOnSecurityAlert, clickNoOnSecurityAlert, "Security Alert");
157         try{
158             getFirstBrowser().addNavigationListener(dl);
159         }catch(JiffieException je){
160             traceMsg("couldn't add dialog listener");
161             traceMsg(JameleonUtility.getStack(je));
162         }
163         try {
164             StateStorer.getInstance().addStorable(this);
165             getFirstBrowser().navigate(url, WAIT);
166         } catch (JiffieException e) {
167             errMsg = "Internet Explorer could not navigate to " + url;
168             throw new RuntimeException(errMsg, e);
169         } finally {
170             try{
171                 getFirstBrowser().removeNavigationListener(dl);
172             }catch(JiffieException je){
173                 traceMsg("couldn't remove dialog listener");
174                 traceMsg(JameleonUtility.getStack(je));
175             }
176             StateStorer.getInstance().removeStorable(this);
177         }
178     }
179 
180     //Storable Methods
181 
182     public void store(String fName, int event) throws IOException{
183         try {
184             String html = null;
185             String filename = fName+".html";
186             IHTMLDocument2 document = null;
187 
188             try{
189                 document = getFirstBrowser().getDocument(WAIT);
190                 document.waitWhileIncomplete();
191                 html = document.getBody().getParentElement().getOuterHtml();
192             }catch(JiffieException je){
193             }finally{
194                 document.release();
195             }
196             if ( html != null && html.length() > 0 ) {
197                 File lastFileWritten = new File(filename);
198                 JameleonUtility.recordResultsToFile(lastFileWritten, html);
199             } else {
200                 log.debug("Not writing results to file because there is no html to be written.");
201             }
202         } catch ( IOException ioe ) {
203             throw new IOException(JameleonUtility.createErrMsg("Unable to get response to store to file in session tag:\n\r "+JameleonUtility.getStack(ioe)));
204         } catch ( RuntimeException re ) {
205             throw new IOException(JameleonUtility.createErrMsg("Unable to get response to store to file in session tag:\n\r "+JameleonUtility.getStack(re)));
206         }
207     }
208 
209     //End Storable Methods.
210 
211     protected void tearDownSession() {
212         ElementFactory elementFactory = JiffieUtility.getElementFactory();
213         TrackingElementFactory factory;
214         if (elementFactory instanceof TrackingElementFactory) {
215             factory = (TrackingElementFactory)elementFactory;
216             JiffieUtility.setElementFactory(originalFactory);
217             factory.flushReleasedAndCount();
218             factory.release();
219         }
220         if (closeIEOnExit) {
221             int size = browsers.size();
222             for (int i = size; i > 0; i--) {
223                 InternetExplorer internetExplorer = (InternetExplorer) browsers.elementAt(i - 1);
224                 browsers.remove(internetExplorer);
225                 if (internetExplorer != null && !internetExplorer.isReleased()) {
226                     try {
227                         // try to correctly unload the document
228                         IHTMLDocument2 doc = internetExplorer.getDocument(WAIT);
229                         if (doc != null){
230                             IHTMLBodyElement body = doc.getBody();
231                             body.fireEvent("onunload", WAIT);
232                             doc.release();
233                         }
234                     } catch (Exception e) {
235                         // ignore
236                     }
237                     if (!internetExplorer.isReleased()) {
238                         internetExplorer.quit();
239                         internetExplorer.release();
240                     }
241                     internetExplorer = null;
242                 }
243             }
244         }
245         factory = null;
246     }
247 
248     /***
249      * Returns the last element of the list of all open browser windows.
250      *
251      * @return The last opened browser window.
252      */
253     public InternetExplorer getCurrentIE() {
254         return (InternetExplorer) browsers.lastElement();
255     }
256 
257     public boolean getVisible() {
258         return visible;
259     }
260 
261 //--------------- Implenetation of interface BrowserCache -----------------
262 
263     public Vector getBrowserCache() {
264         return browsers;
265     }
266 
267     /***
268      * Add a browser instance to the cache. Usually newly opened browser windows should be added to the cache.
269      * @param ie The browser window that should be added to the cache.
270      */
271     public void addBrowser(InternetExplorer ie) {
272         browsers.addElement(ie);
273     }
274 
275     /***
276      * Remove a browser instance from the cache. This should usually happen on quit of the browser window.
277      * @param ie The browser window that should be removed from the cache.
278      */
279     public void removeBrowser(InternetExplorer ie) {
280         // a test's tearDown method might have set browsers to null already before the onQuit event of the browser comes
281         // here and tries to remove the browser (again)
282         //if (browsers != null) {
283         browsers.remove(ie);
284         //}
285     }
286 
287     /***
288      * Get the first browser window from the cache. The first instance is usually the "root" of all subsequently opened
289      * browser windows.
290      * @return The first browse window that is in the cache.
291      */
292     public InternetExplorer getFirstBrowser() {
293         InternetExplorer ie = (InternetExplorer) browsers.firstElement();
294         return ie;
295     }
296 
297     /***
298      * Get the i-th browser window from the cache. If all opened browser windows are added to the cache, it returns the
299      * i-th browser window that has been opened.
300      * @param i The index of the browser window in the cache. This is usually the i-th browser window opened.
301      * @return The i-th browser window.
302      */
303     public InternetExplorer getBrowserAt(int i) {
304         return (InternetExplorer) browsers.elementAt(i);
305     }
306 
307     /***
308      * Get the browser window from the cache with the matching title. 
309      * @param title The title of the browser window in the cache.
310      * @return The matching browser window.
311      */
312     public InternetExplorer getBrowserWithTitle(String title){
313         InternetExplorer windowFound = null;
314         Iterator it = browsers.iterator();
315         InternetExplorer tmpWindow;
316         String tmpTitle;
317         while (it.hasNext() && windowFound == null) {
318             tmpWindow = (InternetExplorer)it.next();
319             try{
320                 tmpTitle = tmpWindow.getDocument(WAIT).getTitle();
321                 if (title != null && title.equals(tmpTitle)) {
322                     windowFound = tmpWindow;
323                 }
324             }catch(JiffieException je){
325                 traceMsg("Trouble getting browser with the provided title '"+title+"'!");
326                 traceMsg(JameleonUtility.getStack(je));
327             }
328         }
329         return windowFound;
330     }
331 }