/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.drone;
import java.util.concurrent.TimeUnit;
import org.jboss.arquillian.core.api.annotation.Observes;
import org.jboss.arquillian.drone.spi.DroneContext;
import org.jboss.arquillian.drone.spi.DronePoint;
import org.jboss.arquillian.drone.spi.event.AfterDroneEnhanced;
import org.jboss.arquillian.graphene.proxy.GrapheneProxyInstance;
import org.jboss.arquillian.graphene.proxy.Interceptor;
import org.jboss.arquillian.graphene.proxy.InvocationContext;
import org.jboss.logging.Logger;
import org.keycloak.testsuite.util.WaitUtils;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class KeycloakDronePostSetup {
protected static final Logger log = org.jboss.logging.Logger.getLogger(KeycloakDronePostSetup.class);
public void configureWebDriver(@Observes AfterDroneEnhanced event, DroneContext droneContext) {
DronePoint<?> dronePoint = event.getDronePoint();
Object drone = droneContext.get(dronePoint).getInstance();
if (drone instanceof WebDriver) {
WebDriver webDriver = (WebDriver) drone;
configureDriverSettings(webDriver);
} else {
log.warn("Drone is not instanceof WebDriver! Drone is " + drone);
}
if (drone instanceof GrapheneProxyInstance) {
GrapheneProxyInstance droneProxy = (GrapheneProxyInstance) drone;
if (drone instanceof HtmlUnitDriver) {
droneProxy.registerInterceptor(new HtmlUnitInterceptor());
}
} else {
log.warn("Drone is not instanceof GrapheneProxyInstance! Drone is " + drone);
}
}
private void configureDriverSettings(WebDriver driver) {
long implicitWaitMillis = WaitUtils.IMPLICIT_ELEMENT_WAIT_MILLIS;
long pageLoadTimeoutMillis = WaitUtils.PAGELOAD_TIMEOUT_MILLIS;
log.infof("Configuring driver settings. implicitWait=%d, pageLoadTimeout=%d", implicitWaitMillis, pageLoadTimeoutMillis);
driver.manage().timeouts().implicitlyWait(implicitWaitMillis, TimeUnit.MILLISECONDS);
driver.manage().timeouts().pageLoadTimeout(pageLoadTimeoutMillis, TimeUnit.MILLISECONDS);
driver.manage().window().maximize();
}
public static class HtmlUnitInterceptor implements Interceptor {
@Override
public Object intercept(InvocationContext context) throws Throwable {
if (context.getMethod().getName().equals("executeScript")) {
String currentUrl = ((WebDriver) context.getTarget()).getCurrentUrl();
int refreshCount = 0;
while (true) {
try {
// htmlUnit is not able to run javascript on about:blank page
if ("about:blank".equals(currentUrl)) {
log.debug("Ignored JS as we are on about:blank page now");
return null;
}
return context.invoke();
} catch (UnsupportedOperationException e) {
// htmlUnit may require to refresh the page after the action
if ("Cannot execute JS against a plain text page".equals(e.getMessage())) {
refreshCount += 1;
if (refreshCount < 2) {
log.debugf("Will try to refresh current page: %s", currentUrl);
((WebDriver) context.getProxy()).navigate().to(currentUrl);
} else {
log.debugf("Current page doesn't seem to support javascript. Current url: %s", currentUrl);
return null;
}
} else {
throw e;
}
}
}
} else {
return context.invoke();
}
}
@Override
public int getPrecedence() {
return -1;
}
}
}