View Javadoc

1   package com.atlassian.webdriver.testing.rule;
2   
3   import com.atlassian.pageobjects.browser.Browser;
4   import com.atlassian.pageobjects.browser.RequireBrowser;
5   import com.atlassian.pageobjects.util.BrowserUtil;
6   import com.atlassian.webdriver.WebDriverFactory;
7   import com.atlassian.webdriver.testing.annotation.IgnoreBrowser;
8   import com.atlassian.webdriver.testing.annotation.TestBrowser;
9   import com.google.common.base.Supplier;
10  import com.google.common.base.Suppliers;
11  import com.google.common.collect.ImmutableList;
12  import com.google.common.collect.Iterables;
13  import org.junit.rules.TestRule;
14  import org.junit.runner.Description;
15  import org.junit.runners.model.Statement;
16  import org.slf4j.Logger;
17  import org.slf4j.LoggerFactory;
18  
19  import javax.inject.Inject;
20  import java.util.Collections;
21  
22  import static com.google.common.base.Preconditions.checkNotNull;
23  import static org.hamcrest.Matchers.hasItem;
24  import static org.hamcrest.Matchers.not;
25  import static org.junit.Assume.assumeThat;
26  
27  /**
28   * <p/>
29   * A rule that allows annotating test methods with the {@link com.atlassian.pageobjects.browser.IgnoreBrowser}
30   * annotation and will skip the test if the current running driver
31   * is in the list of browsers to ignore.
32   *
33   * <p/>
34   * Also skips tests annotated with {@link com.atlassian.pageobjects.browser.RequireBrowser} if they require a
35   * particular browser that is not currently running.
36   *
37   * <p/>
38   * Currently still supports the deprecated annotations {@link IgnoreBrowser} and
39   * {@link com.atlassian.webdriver.testing.annotation.TestBrowser} but this will be dropped in the future. Please make
40   * sure to move to the equivalents from the pageobjects-api module.
41   *
42   * <p/>
43   * Requires surefire 2.7.2 or higher to show skipped tests in test results.
44   *
45   * @since 2.1
46   */
47  public class IgnoreBrowserRule implements TestRule
48  {
49      private static final Logger log = LoggerFactory.getLogger(IgnoreBrowserRule.class);
50  
51      private final Supplier<Browser> currentBrowserSupplier;
52  
53      @Inject
54      public IgnoreBrowserRule(Browser currentBrowser)
55      {
56          this(Suppliers.ofInstance(checkNotNull(currentBrowser, "currentBrowser")));
57      }
58  
59      public IgnoreBrowserRule(Supplier<Browser> currentBrowserSupplier)
60      {
61          this.currentBrowserSupplier = checkNotNull(currentBrowserSupplier, "currentBrowserSupplier");
62      }
63  
64      /**
65       *
66       * @deprecated use explicit browser/supplier, or get an instance of this rule using the page binder framework. Scheduled
67       * for removal in 3.0
68       * @see com.atlassian.webdriver.testing.runner.ProductContextRunner
69       */
70      @Deprecated
71      public IgnoreBrowserRule()
72      {
73          this(BrowserUtil.currentBrowserSupplier());
74      }
75  
76      public Statement apply(final Statement base, final Description description)
77      {
78          return new Statement()
79          {
80              @Override
81              public void evaluate() throws Throwable
82              {
83                  Class<?> clazz = description.getTestClass();
84                  Package pkg = clazz.getPackage();
85                  checkRequiredBrowsers(getRequired(description.getAnnotation(RequireBrowser.class)));
86                  checkRequiredBrowsers(getRequired(description.isSuite() ? null : clazz.getAnnotation(RequireBrowser.class)));
87                  checkRequiredBrowsers(getRequired(pkg.getAnnotation(RequireBrowser.class)));
88                  checkRequiredBrowsers(getRequired(description.getAnnotation(TestBrowser.class)));
89                  checkRequiredBrowsers(getRequired(description.isSuite() ? null : clazz.getAnnotation(TestBrowser.class)));
90                  checkRequiredBrowsers(getRequired(pkg.getAnnotation(TestBrowser.class)));
91  
92                  IgnoredBrowsers.fromLegacyAnnotation(description.getAnnotation(IgnoreBrowser.class))
93                          .checkBrowser(currentBrowser(), description);
94                  IgnoredBrowsers.fromLegacyAnnotation(description.isSuite() ? null : clazz.getAnnotation(IgnoreBrowser.class))
95                          .checkBrowser(currentBrowser(), description);
96                  IgnoredBrowsers.fromAnnotation(description.getAnnotation(com.atlassian.pageobjects.browser.IgnoreBrowser.class))
97                          .checkBrowser(currentBrowser(), description);
98                  IgnoredBrowsers.fromAnnotation(description.isSuite() ? null : clazz.getAnnotation(com.atlassian.pageobjects.browser.IgnoreBrowser.class))
99                          .checkBrowser(currentBrowser(), description);
100                 base.evaluate();
101             }
102 
103             // support for legacy annotation that will be removed: https://studio.atlassian.com/browse/SELENIUM-187
104             private Iterable<Browser> getRequired(TestBrowser testBrowser)
105             {
106                 if (testBrowser != null)
107                 {
108                     return Collections.singleton(WebDriverFactory.getBrowser(testBrowser.value()));
109                 }
110                 else
111                 {
112                     return Collections.emptyList();
113                 }
114             }
115 
116             private Iterable<Browser> getRequired(RequireBrowser requireBrowser)
117             {
118                 if (requireBrowser != null)
119                 {
120                     return ImmutableList.copyOf(requireBrowser.value());
121                 }
122                 else
123                 {
124                     return Collections.emptyList();
125                 }
126             }
127 
128             private void checkRequiredBrowsers(Iterable<Browser> required)
129             {
130                 if (Iterables.isEmpty(required) || Iterables.contains(required, Browser.ALL))
131                 {
132                     return;
133                 }
134                 Browser latestBrowser = currentBrowser();
135                 if (!Iterables.contains(required, latestBrowser))
136                 {
137                     log.info(description.getDisplayName() + " ignored, since it requires one of " + required);
138                     assumeThat(required, hasItem(latestBrowser));
139                 }
140             }
141 
142             private Browser currentBrowser()
143             {
144                 return currentBrowserSupplier.get();
145             }
146         };
147     }
148 
149     private static final class IgnoredBrowsers
150     {
151         public static IgnoredBrowsers fromLegacyAnnotation(IgnoreBrowser legacy)
152         {
153             if (legacy == null)
154             {
155                 return empty();
156             }
157             else
158             {
159                 return new IgnoredBrowsers(ImmutableList.copyOf(legacy.value()), legacy.reason());
160             }
161         }
162 
163         public static IgnoredBrowsers fromAnnotation(com.atlassian.pageobjects.browser.IgnoreBrowser ignoreBrowser)
164         {
165             if (ignoreBrowser == null)
166             {
167                 return empty();
168             }
169             else
170             {
171                 return new IgnoredBrowsers(ImmutableList.copyOf(ignoreBrowser.value()), ignoreBrowser.reason());
172             }
173         }
174 
175         public static IgnoredBrowsers empty()
176         {
177             return new IgnoredBrowsers(Collections.<Browser>emptyList(), "");
178         }
179 
180         private final Iterable<Browser> ignored;
181         private final String reason;
182 
183         private IgnoredBrowsers(Iterable<Browser> ignored, String reason)
184         {
185             this.ignored = ignored;
186             this.reason = reason;
187         }
188 
189         boolean isEmpty()
190         {
191             return Iterables.isEmpty(ignored);
192         }
193 
194         void checkBrowser(Browser currentBrowser, Description description)
195         {
196             if (isEmpty())
197             {
198                 return;
199             }
200             for (Browser browser : ignored)
201             {
202 
203                 if (browser == currentBrowser || browser == Browser.ALL)
204                 {
205                     log.info(description.getDisplayName() + " ignored, reason: " + reason);
206                     assumeThat(browser, not(currentBrowser));
207                     assumeThat(browser, not(Browser.ALL));
208                 }
209             }
210         }
211     }
212 }