Skip to content

Commit

Permalink
Rewriting ConfigureTimeout to support W3C compliant payload that cont…
Browse files Browse the repository at this point in the history
…ains multiple timeouts at once
  • Loading branch information
barancev committed Jul 31, 2017
1 parent 5592739 commit ce06f68
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,60 +21,83 @@
import org.openqa.selenium.remote.server.JsonParametersAware;
import org.openqa.selenium.remote.server.Session;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class ConfigureTimeout extends WebDriverHandler<Void> implements JsonParametersAware {

private static final String IMPLICIT = "implicit";
private static final String PAGE_LOAD = "page load";
private static final String SCRIPT = "script";
private volatile String type;
private volatile long millis;
private static final List<String> knownTypes = Arrays.asList(IMPLICIT, PAGE_LOAD, SCRIPT);

private Map<String, Object> timeouts = new HashMap<>();

public ConfigureTimeout(Session session) {
super(session);
}

public void setJsonParameters(Map<String, Object> allParameters) throws Exception {
String key = "ms";
type = (String) allParameters.get("type");
if (null == type || type.trim().isEmpty()) {
//We got the parameters as per the w3c spec
if (allParameters.containsKey(IMPLICIT)) {
type = IMPLICIT;
} else if (allParameters.containsKey(PAGE_LOAD)) {
type = PAGE_LOAD;
} else if (allParameters.containsKey(SCRIPT)) {
type = SCRIPT;
} else {
throw new WebDriverException("Unknown wait type");
String type = (String) allParameters.get("type");

if (type != null) {
// OSS
if (! knownTypes.contains(type)) {
throw new WebDriverException("Unknown wait type: " + type);
}
key = type;
}
try {
millis = ((Number) allParameters.get(key)).longValue();
} catch (ClassCastException ex) {
throw new WebDriverException("Illegal (non-numeric) timeout value passed: " + allParameters.get(key), ex);
timeouts.put(type, allParameters.get("ms"));

} else {
// W3C
for (String key : allParameters.keySet()) {
if (! knownTypes.contains(key)) {
throw new WebDriverException("Unknown wait type: " + key);
}
}
timeouts.putAll(allParameters);
}
}

@Override
public Void call() throws Exception {
if (IMPLICIT.equals(type)) {
getDriver().manage().timeouts().implicitlyWait(millis, TimeUnit.MILLISECONDS);
} else if (PAGE_LOAD.equals(type)) {
getDriver().manage().timeouts().pageLoadTimeout(millis, TimeUnit.MILLISECONDS);
} else if (SCRIPT.equals(type)) {
getDriver().manage().timeouts().setScriptTimeout(millis, TimeUnit.MILLISECONDS);
} else {
throw new WebDriverException("Unknown wait type: " + type);
if (timeouts.containsKey(IMPLICIT)) {
try {
getDriver().manage().timeouts().implicitlyWait(
((Number) timeouts.get(IMPLICIT)).longValue(), TimeUnit.MILLISECONDS);
} catch (ClassCastException ex) {
throw new WebDriverException(
"Illegal (non-numeric) timeout value passed: " + timeouts.get(IMPLICIT), ex);
}
}
if (timeouts.containsKey(PAGE_LOAD)) {
try {
getDriver().manage().timeouts().pageLoadTimeout(
((Number) timeouts.get(PAGE_LOAD)).longValue(), TimeUnit.MILLISECONDS);
} catch (ClassCastException ex) {
throw new WebDriverException(
"Illegal (non-numeric) timeout value passed: " + timeouts.get(PAGE_LOAD), ex);
}
}
if (timeouts.containsKey(SCRIPT)) {
try {
getDriver().manage().timeouts().setScriptTimeout(
((Number) timeouts.get(SCRIPT)).longValue(), TimeUnit.MILLISECONDS);
} catch (ClassCastException ex) {
throw new WebDriverException(
"Illegal (non-numeric) timeout value passed: " + timeouts.get(SCRIPT), ex);
}
}
return null;
}

@Override
public String toString() {
return String.format("[%s wait: %s]", type, millis);
return "[" + timeouts.entrySet().stream()
.map((entry) -> String.format("%s: %s", entry.getKey(), entry.getValue()))
.collect(Collectors.joining(",")) + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
Expand All @@ -43,31 +44,34 @@

import java.io.File;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.concurrent.TimeUnit;

@RunWith(JUnit4.class)
public class ConfigureTimeoutTest {

@Rule
public ExpectedException expectedEx = ExpectedException.none();

private DriverFactory driverFactory;
private WebDriver.Timeouts timeouts;
private TemporaryFilesystem tempFs;
private File tempDir;
private DesiredCapabilities caps;
private Session session;

private String[] timeoutTypes = new String[]{"implicit", "page load", "script"};

@Before
public void setUp() {
driverFactory = mock(DriverFactory.class);
WebDriver.Timeouts timeouts = mock(WebDriver.Timeouts.class);
public void setUp() throws Exception {
DriverFactory driverFactory = mock(DriverFactory.class);
timeouts = mock(WebDriver.Timeouts.class);
WebDriver.Options options = mock(WebDriver.Options.class);
WebDriver driver = mock(WebDriver.class);
when(driverFactory.newInstance(any(Capabilities.class))).thenReturn(driver);
when(driver.manage()).thenReturn(options);
when(driver.manage().timeouts()).thenReturn(timeouts);
tempDir = Files.createTempDir();
tempFs = TemporaryFilesystem.getTmpFsBasedOn(tempDir);
caps = DesiredCapabilities.firefox();
DesiredCapabilities caps = DesiredCapabilities.firefox();
session = DefaultSession.createSession(driverFactory, tempFs, caps);
}

@After
Expand All @@ -77,65 +81,73 @@ public void cleanUp() {
}

@Test
public void shouldAcceptW3cCompliantPayLoadForTimeouts() throws Exception {
runAssertions(ImmutableMap::of, 100);
public void shouldAcceptW3CCompliantPayLoadForTimeouts() throws Exception {
for (String timeoutType : timeoutTypes) {
runW3CAssertion(ImmutableMap.of(timeoutType, 100));
}
verify(timeouts).implicitlyWait(100, TimeUnit.MILLISECONDS);
verify(timeouts).pageLoadTimeout(100, TimeUnit.MILLISECONDS);
verify(timeouts).setScriptTimeout(100, TimeUnit.MILLISECONDS);
verifyNoMoreInteractions(timeouts);
}

@Test
public void shouldAcceptW3CCompliantPayLoadWithMultipleTimeouts() throws Exception {
runW3CAssertion(ImmutableMap.of("implicit", 100, "page load", 100, "script", 100));
verify(timeouts).implicitlyWait(100, TimeUnit.MILLISECONDS);
verify(timeouts).pageLoadTimeout(100, TimeUnit.MILLISECONDS);
verify(timeouts).setScriptTimeout(100, TimeUnit.MILLISECONDS);
verifyNoMoreInteractions(timeouts);
}

@Test
public void shouldAcceptJsonWireProtocolCompliantPayLoadForTimeouts() throws Exception {
runAssertions((type, timeout) -> ImmutableMap.of("type", type, "ms", timeout), 200);
for (String timeoutType : timeoutTypes) {
runOSSAssertion(timeoutType, 100);
}
verify(timeouts).implicitlyWait(100, TimeUnit.MILLISECONDS);
verify(timeouts).pageLoadTimeout(100, TimeUnit.MILLISECONDS);
verify(timeouts).setScriptTimeout(100, TimeUnit.MILLISECONDS);
verifyNoMoreInteractions(timeouts);
}

@Test
public void shouldThrowExceptionWhenIncorrectTimeoutTypeSpecifiedForJsonSpec() throws Exception {
expectedEx.expect(WebDriverException.class);
expectedEx.expectMessage("Unknown wait type: unknown");
runAssertion((type, timeout) -> ImmutableMap.of("type", type, "ms", timeout), "unknown");
runOSSAssertion("unknown", 100);
}

@Test
public void shouldThrowExceptionWhenIncorrectTimeoutTypeSpecifiedForW3CSpec() throws Exception {
expectedEx.expect(WebDriverException.class);
expectedEx.expectMessage("Unknown wait type");
runAssertion(ImmutableMap::of, "unknown");
runW3CAssertion(ImmutableMap.of("unknown", 100));
}

@Test
public void shouldThrowExceptionWhenInvalidTimeoutValueSpecifiedForJsonSpec() throws Exception {
expectedEx.expect(WebDriverException.class);
expectedEx.expectMessage("Illegal (non-numeric) timeout value passed: timeout");
runAssertion((type, timeout) -> ImmutableMap.of("type", type, "ms", "timeout"), "implicit");
runOSSAssertion("implicit", "timeout");
}

@Test
public void shouldThrowExceptionWhenInvalidTimeoutValueSpecifiedForW3CSpec() throws Exception {
expectedEx.expect(WebDriverException.class);
expectedEx.expectMessage("Illegal (non-numeric) timeout value passed: timeout");
runAssertion((type, timeout)-> ImmutableMap.of(type, "timeout"), "implicit");
runW3CAssertion(ImmutableMap.of("implicit", "timeout"));
}

private void runAssertions(BiFunction<String, Integer, Map<String, Object>> map, int timeout)
throws Exception {
String[] timeoutTypes = new String[]{"implicit", "page load", "script"};
Session session = DefaultSession.createSession(driverFactory, tempFs, caps);
for (String timeoutType : timeoutTypes) {
runAssertion(session, map, timeoutType, timeout);
}
}

private void runAssertion(BiFunction<String, Integer, Map<String, Object>> map,
String timeoutType) throws Exception {
Session session = DefaultSession.createSession(driverFactory, tempFs, caps);
runAssertion(session, map, timeoutType, 100);
private void runW3CAssertion(Map<String, Object> args) throws Exception {
ConfigureTimeout configureTimeout = new ConfigureTimeout(session);
configureTimeout.setJsonParameters(args);
configureTimeout.call();
}

private void runAssertion(Session session, BiFunction<String, Integer, Map<String, Object>> map,
String timeoutType, int timeout) throws Exception {
private void runOSSAssertion(String type, Object timeout) throws Exception {
ConfigureTimeout configureTimeout = new ConfigureTimeout(session);
Map<String, Object> args = map.apply(timeoutType, timeout);
configureTimeout.setJsonParameters(args);
configureTimeout.setJsonParameters(ImmutableMap.of("type", type, "ms", timeout));
configureTimeout.call();
String expected = String.format("[%s wait: %d]", timeoutType, timeout);
Assert.assertEquals(expected, configureTimeout.toString());
}
}

0 comments on commit ce06f68

Please sign in to comment.