1 /* BrowserTestRunner.java
2 Copyright (C) 2012 Red Hat, Inc.
3 
4 This file is part of IcedTea.
5 
6 IcedTea is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, version 2.
9 
10 IcedTea 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 General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with IcedTea; see the file COPYING.  If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301 USA.
19 
20 Linking this library statically or dynamically with other modules is
21 making a combined work based on this library.  Thus, the terms and
22 conditions of the GNU General Public License cover the whole
23 combination.
24 
25 As a special exception, the copyright holders of this library give you
26 permission to link this library with independent modules to produce an
27 executable, regardless of the license terms of these independent
28 modules, and to copy and distribute the resulting executable under
29 terms of your choice, provided that you also meet, for each linked
30 independent module, the terms and conditions of the license of that
31 module.  An independent module is a module which is not derived from
32 or based on this library.  If you modify this library, you may extend
33 this exception to your version of the library, but you are not
34 obligated to do so.  If you do not wish to do so, delete this
35 exception statement from your version.
36  */
37 
38 package net.sourceforge.jnlp.browsertesting;
39 
40 import java.lang.annotation.Annotation;
41 import java.lang.reflect.InvocationTargetException;
42 import net.sourceforge.jnlp.annotations.TestInBrowsers;
43 import java.lang.reflect.Method;
44 import java.util.Arrays;
45 import java.util.List;
46 import java.util.Random;
47 import net.sourceforge.jnlp.ServerAccess;
48 import org.junit.Ignore;
49 import org.junit.internal.AssumptionViolatedException;
50 import org.junit.internal.runners.model.EachTestNotifier;
51 import org.junit.runner.Description;
52 import org.junit.runner.notification.RunNotifier;
53 import org.junit.runners.BlockJUnit4ClassRunner;
54 import org.junit.runners.model.FrameworkMethod;
55 import org.junit.runners.model.InitializationError;
56 import org.junit.runners.model.Statement;
57 
58 public class BrowserTestRunner extends BlockJUnit4ClassRunner {
59 
BrowserTestRunner(java.lang.Class<?> testClass)60     public BrowserTestRunner(java.lang.Class<?> testClass) throws InitializationError {
61         super(testClass);
62     }
63 
64     @Override
runChild(FrameworkMethod method, RunNotifier notifier)65     protected void runChild(FrameworkMethod method, RunNotifier notifier) {
66         Method mm = method.getMethod();
67         TestInBrowsers tib = mm.getAnnotation(TestInBrowsers.class);
68         injectBrowserCatched(method, Browsers.none);
69         boolean browserIgnoration = false;
70         if (tib != null) {
71             try {
72                 List<Browsers> testableBrowsers = BrowserFactory.getFactory().getBrowsers(tib);
73                 String mbr = System.getProperty("modified.browsers.run");
74                 if (mbr != null) {
75                     if (mbr.equalsIgnoreCase("all")) {
76                         if (!isBrowsersNoneSet(tib)) {
77                             testableBrowsers = BrowserFactory.getFactory().getBrowsers(new Browsers[]{Browsers.all});
78                         }
79                     } else if (mbr.equalsIgnoreCase("one")) {
80                         //this complication here is for case like
81                         // namely enumerated concrete browsers, so we want to pick up
82                         // random one from those already enumerated
83                         if (isBrowsersNoneSet(tib)) {
84                             testableBrowsers = Arrays.asList(new Browsers[]{testableBrowsers.get(new Random().nextInt(testableBrowsers.size()))});
85                         }
86                     } else if (mbr.equalsIgnoreCase("ignore")) {
87                         testableBrowsers = BrowserFactory.getFactory().getBrowsers(new Browsers[]{Browsers.none});
88                         browserIgnoration = true;
89                     } else {
90                         ServerAccess.logErrorReprint("unrecognized value of modified.browsers.run - " + mbr);
91                     }
92                 }
93                 for (Browsers browser : testableBrowsers) {
94                     try {
95                         injcetBrowser(method, browser);
96                         runChildX(method, notifier, browser, browserIgnoration);
97                     } catch (Exception ex) {
98                         //throw new RuntimeException("unabled to inject browser", ex);
99                         ServerAccess.logException(ex, true);
100                     }
101                 }
102             } finally {
103                 injectBrowserCatched(method, Browsers.none);
104             }
105         } else {
106             runChildX(method, notifier, null, false);
107         }
108     }
109 
isBrowsersNoneSet(TestInBrowsers tib)110     private boolean isBrowsersNoneSet(TestInBrowsers tib) {
111         if (tib.testIn().length == 1 && tib.testIn()[0] == Browsers.none) {
112             return true;
113         }
114         return false;
115     }
116 
injectBrowserCatched(FrameworkMethod method, Browsers browser)117     private void injectBrowserCatched(FrameworkMethod method, Browsers browser) {
118         try {
119             injcetBrowser(method, browser);
120         } catch (Exception ex) {
121             //throw new RuntimeException("unabled to inject browser", ex);
122             ServerAccess.logException(ex, true);
123         }
124     }
125 
injcetBrowser(FrameworkMethod method, Browsers browser)126     private void injcetBrowser(FrameworkMethod method, Browsers browser) throws IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
127         Method ff = method.getMethod().getDeclaringClass().getMethod("setBrowser", Browsers.class);
128         ff.invoke(null, browser);
129     }
130 
runChildX(final FrameworkMethod method, RunNotifier notifier, Browsers browser, boolean browserIgnoration)131     protected void runChildX(final FrameworkMethod method, RunNotifier notifier, Browsers browser, boolean browserIgnoration) {
132         Description description = describeChild(method, browser);
133         if (method.getAnnotation(Ignore.class) != null) {
134             notifier.fireTestIgnored(description);
135         } else {
136             try {
137                 runLeaf(methodBlock(method), description, notifier, browserIgnoration);
138 //                ServerAccess.logOutputReprint("trying leaf");
139 //                Method m = this.getClass().getMethod("runLeaf", Statement.class, Description.class, RunNotifier.class);
140 //                m.setAccessible(true);
141 //                m.invoke(this, methodBlock(method), description, notifier);
142 //                ServerAccess.logOutputReprint("leaf invoked");
143             } catch (Exception ex) {
144                 //throw new RuntimeException("unabled to lunch test on leaf", ex);
145                 ServerAccess.logException(ex, true);
146             }
147         }
148     }
149 
150     /**
151      * Runs a {@link Statement} that represents a leaf (aka atomic) test.
152      */
runLeaf(Statement statement, Description description, RunNotifier notifier, boolean ignore)153     protected final void runLeaf(Statement statement, Description description,
154             RunNotifier notifier, boolean ignore) {
155         EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
156         eachNotifier.fireTestStarted();
157           if (ignore) {
158                 eachNotifier.fireTestIgnored();
159                 return;
160             }
161         try {
162           statement.evaluate();
163         } catch (AssumptionViolatedException e) {
164             eachNotifier.addFailedAssumption(e);
165         } catch (Throwable e) {
166             eachNotifier.addFailure(e);
167         } finally {
168             eachNotifier.fireTestFinished();
169         }
170     }
171 
describeChild(FrameworkMethod method, Browsers browser)172     protected Description describeChild(FrameworkMethod method, Browsers browser) {
173         if (browser == null) {
174             return super.describeChild(method);
175         } else {
176             try {
177                 return Description.createTestDescription(getTestClass().getJavaClass(),
178                         testName(method) + " - " + browser.toString(), method.getAnnotations());
179             } catch (Exception ex) {
180                 ServerAccess.logException(ex, true);
181                 return super.describeChild(method);
182             }
183         }
184     }
185 }
186