View Javadoc
1   /*
2    * #%L
3    * wcm.io
4    * %%
5    * Copyright (C) 2020 wcm.io
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package io.wcm.qa.glnm.junit.seljup;
21  
22  import static io.wcm.qa.glnm.junit.seljup.SeleniumJupiterUtil.asBrowserList;
23  import static io.wcm.qa.glnm.junit.seljup.SeleniumJupiterUtil.getSeleniumExtension;
24  import static org.junit.jupiter.engine.execution.GaleniumDriverParameterContext.driverParamContext;
25  
26  import java.util.Optional;
27  
28  import org.junit.jupiter.api.extension.AfterAllCallback;
29  import org.junit.jupiter.api.extension.AfterEachCallback;
30  import org.junit.jupiter.api.extension.BeforeEachCallback;
31  import org.junit.jupiter.api.extension.ExtensionContext;
32  import org.openqa.selenium.TakesScreenshot;
33  import org.openqa.selenium.WebDriver;
34  import org.openqa.selenium.remote.RemoteWebDriver;
35  import org.slf4j.Logger;
36  import org.slf4j.LoggerFactory;
37  
38  import io.github.bonigarcia.seljup.Arguments;
39  import io.github.bonigarcia.seljup.BrowserType;
40  import io.wcm.qa.glnm.configuration.GaleniumConfiguration;
41  import io.wcm.qa.glnm.context.GaleniumContext;
42  import io.wcm.qa.glnm.reporting.GaleniumReportUtil;
43  import io.wcm.qa.glnm.webdriver.WebDriverManagement;
44  
45  class BrowserInjectionExtension implements
46      BeforeEachCallback,
47      AfterEachCallback,
48      AfterAllCallback {
49  
50    private static final Logger LOG = LoggerFactory.getLogger(BrowserInjectionExtension.class);
51    private final BrowserType browserType;
52  
53    BrowserInjectionExtension(BrowserType browser) {
54      browserType = browser;
55    }
56  
57    /** {@inheritDoc} */
58    @Override
59    public void afterAll(ExtensionContext context) throws Exception {
60      if (LOG.isTraceEnabled()) {
61        LOG.trace("after all: " + context.getUniqueId());
62      }
63      getSeleniumExtension().afterAll(context);
64    }
65  
66    /** {@inheritDoc} */
67    @Override
68    public void afterEach(ExtensionContext context) throws Exception {
69      if (LOG.isTraceEnabled()) {
70        LOG.trace("after each: " + context.getUniqueId());
71      }
72      screenshot(context);
73      getSeleniumExtension().afterEach(context);
74    }
75  
76    /** {@inheritDoc} */
77    @Override
78    public void beforeEach(ExtensionContext context) throws Exception {
79      if (LOG.isTraceEnabled()) {
80        LOG.trace("before each: " + context.getUniqueId());
81      }
82      String contextId = context.getUniqueId();
83      updateBrowserList(contextId);
84      Object webDriver = getDriverFromSelJup(context);
85      if (isDriver(contextId, webDriver)) {
86        setDriver(webDriver);
87      }
88    }
89  
90    private Object getDriverFromSelJup(ExtensionContext context) {
91      if (GaleniumConfiguration.isHeadless()) {
92        return SeleniumJupiterUtil.getDriverFromSelJup(driverParamContext(this, "setHeadlessDriver"), context);
93      }
94      return SeleniumJupiterUtil.getDriverFromSelJup(driverParamContext(this, "setVisibleDriver"), context);
95    }
96  
97    private boolean isDriver(String uniqueId, Object webDriver) {
98      if (webDriver == null) {
99        if (LOG.isInfoEnabled()) {
100         LOG.info("No webdriver resolved. ({0})", uniqueId);
101       }
102       // no webdriver
103       return false;
104     }
105 
106     if (!(webDriver instanceof WebDriver)) {
107       if (LOG.isInfoEnabled()) {
108         LOG.info("Not resolved to webdriver: {1} ({0})", uniqueId, webDriver);
109       }
110       // not a webdriver
111       return false;
112     }
113 
114     return true;
115   }
116 
117   private void screenshot(ExtensionContext context) {
118     Optional<Throwable> executionException = context.getExecutionException();
119     if (executionException.isPresent()) {
120       if (LOG.isTraceEnabled()) {
121         LOG.trace("screenshot after " + executionException.get());
122       }
123       screenshot();
124       return;
125     }
126     if (GaleniumConfiguration.isTakeScreenshotOnSuccessfulTest()) {
127       if (LOG.isDebugEnabled()) {
128         LOG.debug("screenshot after success");
129       }
130       screenshot();
131       return;
132     }
133     if (LOG.isTraceEnabled()) {
134       LOG.trace("no screenshot");
135     }
136   }
137 
138   private void setDriver(Object webDriver) {
139     setDriver((WebDriver)webDriver);
140   }
141 
142   private void updateBrowserList(String contextId) {
143     getSeleniumExtension().putBrowserList(contextId, asBrowserList(browserType));
144   }
145 
146   void setHeadlessDriver(
147       @Arguments({
148           "--headless",
149           "--enable-logging"
150       }) WebDriver driver) {
151     setDriver(driver);
152   }
153 
154   void setVisibleDriver(
155       @Arguments({
156           "--enable-logging"
157       }) WebDriver driver) {
158     setDriver(driver);
159   }
160 
161   private static void screenshot() {
162     WebDriver currentDriver = WebDriverManagement.getCurrentDriver();
163     if (currentDriver == null) {
164       if (LOG.isTraceEnabled()) {
165         LOG.trace("no screenshot as driver is null");
166       }
167       return;
168     }
169     if (currentDriver instanceof RemoteWebDriver && ((RemoteWebDriver)currentDriver).getSessionId() == null) {
170       if (LOG.isInfoEnabled()) {
171         LOG.info("no screenshot as session ID is null");
172       }
173       return;
174     }
175     if (!(currentDriver instanceof TakesScreenshot)) {
176       if (LOG.isInfoEnabled()) {
177         LOG.info("no screenshot as driver not able to take screenshot");
178       }
179       return;
180     }
181     GaleniumReportUtil.takeScreenshot((TakesScreenshot)currentDriver);
182   }
183 
184   private static void setDriver(WebDriver driver) {
185     GaleniumContext.getContext().setDriver(driver);
186   }
187 
188 }