Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.openqa.selenium.htmlunit.remote.HtmlUnitDriverServer Maven / Gradle / Ivy
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you 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.openqa.selenium.htmlunit.remote;
import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
import static java.util.stream.Collectors.toList;
import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.fromJson;
import static org.openqa.selenium.remote.http.Route.delete;
import static org.openqa.selenium.remote.http.Route.get;
import static org.openqa.selenium.remote.http.Route.post;
import java.io.UncheckedIOException;
import java.lang.reflect.Type;
import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.InvalidSelectorException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.NoSuchFrameException;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.Point;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.UnsupportedCommandException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriver.Timeouts;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.grid.TemplateGridServerCommand.Handlers;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.htmlunit.options.HtmlUnitDriverOptions;
import org.openqa.selenium.htmlunit.remote.ActionsCoercer.ActionsWrapper;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.json.TypeToken;
import org.openqa.selenium.netty.server.NettyServer;
import org.openqa.selenium.remote.ErrorCodec;
import org.openqa.selenium.remote.NewSessionPayload;
import org.openqa.selenium.remote.http.HttpHandler;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.http.Route;
/**
* This class implements a server that supports remote execution of {@link HtmlUnitDriver}.
*/
public class HtmlUnitDriverServer extends NettyServer {
/**
* Constructor for {@link HtmlUnitDriver} server.
*
* @param options {@link BaseServerOptions} object
*/
public HtmlUnitDriverServer(BaseServerOptions options) {
super(options, createHandlers().httpHandler);
}
private static final Type MAP_OF_LONGS = new TypeToken>() {}.getType();
private static final Type MAP_OF_OBJECTS = new TypeToken>() {}.getType();
private static final Type MAP_OF_STRINGS = new TypeToken>() {}.getType();
private static final Type MAP_OF_INTEGERS = new TypeToken>() {}.getType();
private static final Type MAP_OF_ACTIONS = new TypeToken>() {}.getType();
private static final Type MAP_OF_COOKIES = new TypeToken>() {}.getType();
private static final Logger LOG = Logger.getLogger(HtmlUnitDriverServer.class.getName());
private static Map driverMap = new ConcurrentHashMap<>();
/**
* Define the handlers for the routes supported by this server.
*
* @return {@link Handlers} object
*/
protected static Handlers createHandlers() {
return new Handlers(Route.combine(
post("/session").to(() -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return newSession(req);
}
}),
delete("/session/{sessionId}").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return deleteSession(sessionIdFrom(params));
}
}),
get("/session/{sessionId}/timeouts").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getTimeouts(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/timeouts").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return setTimeouts(req, sessionIdFrom(params));
}
}),
post("/session/{sessionId}/url").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return navigateTo(req, sessionIdFrom(params));
}
}),
get("/session/{sessionId}/url").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getCurrentUrl(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/back").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return navigateBack(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/forward").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return navigateForward(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/refresh").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return refreshSession(sessionIdFrom(params));
}
}),
get("/session/{sessionId}/title").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getTitle(sessionIdFrom(params));
}
}),
get("/session/{sessionId}/window").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getWindowHandle(sessionIdFrom(params));
}
}),
delete("/session/{sessionId}/window").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return closeWindow(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/window").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return switchToWindow(req, sessionIdFrom(params));
}
}),
post("/session/{sessionId}/window/new").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return switchToNewWindow(req, sessionIdFrom(params));
}
}),
get("/session/{sessionId}/window/handles").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getWindowHandles(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/frame").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return switchToFrame(req, sessionIdFrom(params));
}
}),
post("/session/{sessionId}/frame/parent").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return switchToParentFrame(sessionIdFrom(params));
}
}),
get("/session/{sessionId}/window/rect").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getWindowRect(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/window/rect").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return setWindowRect(req, sessionIdFrom(params));
}
}),
post("/session/{sessionId}/window/maximize").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return maximizeWindow(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/window/minimize")
.to(() -> req -> errorForException(new UnsupportedCommandException("Cannot minimize window"))),
post("/session/{sessionId}/window/fullscreen").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return fullscreenWindow(sessionIdFrom(params));
}
}),
get("/session/{sessionId}/element/active").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getActiveElement(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/element").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return findElement(req, sessionIdFrom(params));
}
}),
post("/session/{sessionId}/elements").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return findElements(req, sessionIdFrom(params));
}
}),
post("/session/{sessionId}/element/{elementId}/element").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return findElementFromElement(req, sessionIdFrom(params), elementIdFrom(params));
}
}),
post("/session/{sessionId}/element/{elementId}/elements").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return findElementsFromElement(req, sessionIdFrom(params), elementIdFrom(params));
}
}),
get("/session/{sessionId}/element/{elementId}/selected").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return isElementSelected(sessionIdFrom(params), elementIdFrom(params));
}
}),
get("/session/{sessionId}/element/{elementId}/attribute/{name}").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getElementDomAttribute(sessionIdFrom(params), elementIdFrom(params), nameFrom(params));
}
}),
get("/session/{sessionId}/element/{elementId}/property/{name}").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getElementDomProperty(sessionIdFrom(params), elementIdFrom(params), nameFrom(params));
}
}),
get("/session/{sessionId}/element/{elementId}/css/{name}").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getElementCssValue(sessionIdFrom(params), elementIdFrom(params), nameFrom(params));
}
}),
get("/session/{sessionId}/element/{elementId}/text").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getElementText(sessionIdFrom(params), elementIdFrom(params));
}
}),
get("/session/{sessionId}/element/{elementId}/name").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getElementTagName(sessionIdFrom(params), elementIdFrom(params));
}
}),
get("/session/{sessionId}/element/{elementId}/rect").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getElementRect(sessionIdFrom(params), elementIdFrom(params));
}
}),
get("/session/{sessionId}/element/{elementId}/enabled").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return isElementEnabled(sessionIdFrom(params), elementIdFrom(params));
}
}),
post("/session/{sessionId}/element/{elementId}/click").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return elementClick(sessionIdFrom(params), elementIdFrom(params));
}
}),
post("/session/{sessionId}/element/{elementId}/clear").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return elementClear(sessionIdFrom(params), elementIdFrom(params));
}
}),
post("/session/{sessionId}/element/{elementId}/value").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return elementSendKeys(req, sessionIdFrom(params), elementIdFrom(params));
}
}),
get("/session/{sessionId}/source").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getPageSource(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/execute/sync").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return executeScript(req, sessionIdFrom(params), false);
}
}),
post("/session/{sessionId}/execute/async").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return executeScript(req, sessionIdFrom(params), true);
}
}),
get("/session/{sessionId}/cookie").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getAllCookies(sessionIdFrom(params));
}
}),
get("/session/{sessionId}/cookie/{name}").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getNamedCookie(sessionIdFrom(params), nameFrom(params));
}
}),
post("/session/{sessionId}/cookie").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return addCookie(req, sessionIdFrom(params));
}
}),
delete("/session/{sessionId}/cookie/{name}").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return deleteNamedCookie(sessionIdFrom(params), nameFrom(params));
}
}),
delete("/session/{sessionId)/cookie").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return deleteAllCookies(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/actions").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return performActions(req, sessionIdFrom(params));
}
}),
delete("/session/{sessionId}/actions").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return releaseActions(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/alert/dismiss").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return dismissAlert(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/alert/accept").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return acceptAlert(sessionIdFrom(params));
}
}),
get("/session/{sessionId}/alert/text").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return getAlertText(sessionIdFrom(params));
}
}),
post("/session/{sessionId}/alert/text").to(params -> new HttpHandler() {
@Override
public HttpResponse execute(final HttpRequest req) throws UncheckedIOException {
return sendAlertText(req, sessionIdFrom(params));
}
}),
get("/session/{sessionId}/screenshot")
.to(() -> req -> errorForException(new UnsupportedCommandException("Cannot take screenshot"))),
get("/session/{sessionId}/element/{elementId}/screenshot")
.to(() -> req -> errorForException(new UnsupportedCommandException("Cannot take element screenshot"))),
get("/status").to(() -> req -> successWithData(Map.of("ready", true, "message", "HtmlUnitDriverServer is ready."))),
get("/readyz").to(() -> req -> new HttpResponse().setStatus(HTTP_NO_CONTENT))),
null
);
}
/**
* Handle remote 'New Session' request :: POST '/session'
*
* @param req request with {@link NewSessionPayload}
* @return response:
* 200 - success with data:
* sessionId : session ID
* capabilities : session capabilities
* 404 - session not created
* @see New Session
*/
public static HttpResponse newSession(final HttpRequest req) {
List capsList;
Map content = fromJson(req, MAP_OF_OBJECTS);
try(NewSessionPayload payload = NewSessionPayload.create(content)) {
capsList = payload.stream().collect(toList());
}
HtmlUnitDriverOptions options = new HtmlUnitDriverOptions(capsList.get(0));
String sessionId = UUID.randomUUID().toString();
HtmlUnitDriver driver = new HtmlUnitDriver(options);
driverMap.put(sessionId, driver);
Map data = Map.of(
"sessionId", sessionId,
"capabilities", driver.getCapabilities());
return successWithData(data);
}
/**
* Handle remote 'Delete Session' request :: DELETE '/session/{sessionId}'
*
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* @see Delete Session
*/
public static HttpResponse deleteSession(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.quit();
driverMap.remove(sessionId);
return successWithData(null);
}
/**
* Handle remote 'Get Timeouts' request :: GET '/session/{sessionId}/timeouts'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* script : script timeout (mS)
* pageLoad : page load timeout (mS)
* implicit : implicit timeout (mS)
* 404 - invalid session ID
* @see Get Timeouts
*/
public static HttpResponse getTimeouts(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithTimeouts(driver);
}
/**
* Handle remote 'Set Timeouts' request :: POST '/session/{sessionId}/timeouts'
*
* @param req request with payload:
* script : script timeout (mS)
* pageLoad : page load timeout (mS)
* implicit : implicit timeout (mS)
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* script : script timeout (mS)
* pageLoad : page load timeout (mS)
* implicit : implicit timeout (mS)
* 404 - invalid session ID
* @see Set Timeouts
*/
public static HttpResponse setTimeouts(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Timeouts timeouts = driver.manage().timeouts();
Map content = fromJson(req, MAP_OF_LONGS);
for (Entry entry : content.entrySet()) {
try {
switch(entry.getKey()) {
case "script":
timeouts.scriptTimeout(Duration.ofMillis(entry.getValue()));
break;
case "pageLoad":
timeouts.pageLoadTimeout(Duration.ofMillis(entry.getValue()));
break;
case "implicit":
timeouts.implicitlyWait(Duration.ofMillis(entry.getValue()));
break;
}
} catch (InvalidArgumentException e) {
return errorForException(e);
}
}
return successWithTimeouts(driver);
}
/**
* Handle remote 'Navigate To' request :: POST '/session/{sessionId}/url'
*
* @param req request with payload:
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* @see Navigate To
*/
public static HttpResponse navigateTo(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Map content = fromJson(req, MAP_OF_STRINGS);
driver.get(content.get("url"));
return successWithData(null);
}
/**
* Handle remote 'Get Current URL' request :: GET '/session/{sessionId}/url'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* 404 - invalid session ID
* @see Get Current URL
*/
public static HttpResponse getCurrentUrl(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.getCurrentUrl());
}
/**
* Handle remote 'Back' request :: POST '/session/{sessionId}/back'
*
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* @see Back
*/
public static HttpResponse navigateBack(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.navigate().back();
return successWithData(null);
}
/**
* Handle remote 'Forward' command :: POST '/session/{sessionId}/forward'
*
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* @see Forward
*/
public static HttpResponse navigateForward(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.navigate().forward();
return successWithData(null);
}
/**
* Handle remote 'Refresh' request :: POST '/session/{sessionId}/refresh'
*
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* @see Refresh
*/
public static HttpResponse refreshSession(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.navigate().refresh();;
return successWithData(null);
}
/**
* Handle remote 'Get Title' request :: GET '/session/{sessionId}/title'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* value : current page title
* 404 - invalid session ID
* @see Refresh
*/
public static HttpResponse getTitle(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.getTitle());
}
/**
* Handle remote 'Get Window Handle' request :: GET '/session/{sessionId}/window'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* value : current window handle
* 404 - invalid session ID
* @see Get Window Handle
*/
public static HttpResponse getWindowHandle(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.getWindowHandle());
}
/**
* Handle remote 'Close Window' request :: DELETE '/session/{sessionId}/window'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* value : list of window handles
* 404 - invalid session ID
* @see Close Window
*/
public static HttpResponse closeWindow(final String sessionId) {
Set data;
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.close();
try {
driver.getWebClient();
data = driver.getWindowHandles();
} catch (NoSuchSessionException eaten) {
driverMap.remove(sessionId);
data = Collections.emptySet();
}
return successWithData(data);
}
/**
* Handle remote 'Switch To Window' request :: POST '/session/{sessionId}/window'
*
* @param req request with payload:
* handle : target window handle
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* 404 - no such window
* @see Switch To Window
*/
public static HttpResponse switchToWindow(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Map content = fromJson(req, MAP_OF_STRINGS);
try {
driver.switchTo().window(content.get("handle"));
} catch (NoSuchWindowException e) {
return errorForException(e);
}
return successWithData(null);
}
/**
* Handle remote 'New Window' request :: POST '/session/{sessionId}/window/new'
*
* @param req request with payload:
* type : new window type [window, tab]
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* handle : new window handle
* type : new window type [window, tab]
* 400 - invalid argument
* 404 - invalid session ID
* @see New Window
*/
public static HttpResponse switchToNewWindow(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Map content = fromJson(req, MAP_OF_STRINGS);
WindowType type = WindowType.fromString(content.get("type"));
if (type == null) {
return errorForException(new InvalidArgumentException(
"Invalid window type: " + String.valueOf(content.get("type"))));
}
driver.switchTo().newWindow(type);
Map data = Map.of("handle", driver.getWindowHandle(), "type", type.toString());
return successWithData(data);
}
/**
* Handle remote 'Get Window Handles' request :: GET '/session/{sessionId}/window/handles'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* value : list of window handles
* 404 - invalid session ID
* @see Get Window Handles
*/
public static HttpResponse getWindowHandles(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.getWindowHandles());
}
/**
* Handle remote 'Switch To Frame' request :: POST '/session/{sessionId}/frame'
*
* @param req request with payload:
* id : {@code null}, index, or element identifier
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* 404 - no such window
* 404 - no such frame
* @see Switch To Frame
*/
public static HttpResponse switchToFrame(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Map content = fromJson(req, MAP_OF_OBJECTS);
Object frameId = new JsonToHtmlUnitWebElementConverter(driver).apply(content.get("id"));
try {
if (frameId == null) {
driver.switchTo().defaultContent();
} else if (frameId instanceof Long) {
driver.switchTo().frame(((Long) frameId).intValue());
} else if (frameId instanceof String) {
driver.switchTo().frame((String) frameId);
} else if (frameId instanceof WebElement) {
driver.switchTo().frame((WebElement) frameId);
} else {
throw new NoSuchFrameException("Frame ID must be 'null', Integer, String, or WebElement; "
+ "was: " + frameId.getClass().getName());
}
} catch (NoSuchWindowException | NoSuchFrameException e) {
return errorForException(e);
}
return successWithData(null);
}
/**
* Handle remote 'Switch To Parent Frame' command :: POST '/session/{sessionId}/frame/parent'
*
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* 404 - no such window
* @see Switch To Parent Frame
*/
public static HttpResponse switchToParentFrame(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
try {
driver.switchTo().parentFrame();
} catch (NoSuchWindowException e) {
return errorForException(e);
}
return successWithData(null);
}
/**
* Handle remote 'Get Window Rect' command :: GET '/session/{sessionId}/window/rect'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* width : width of current window
* height : height of current window
* x : current window 'X' coordinate
* y : current window 'Y' coordinate
* 404 - invalid session ID
* @see Get Window Rect
*/
public static HttpResponse getWindowRect(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Dimension size = driver.manage().window().getSize();
Point posn = driver.manage().window().getPosition();
return successWithData(Map.of("width", size.width, "height", size.height, "x", posn.x, "y", posn.y));
}
/**
* Handle remote 'Set Window Rect' command :: POST '/session/{sessionId}/window/rect'
*
* @param req request with payload:
* width : target width for current window
* height : target height for current window
* x : target 'X' coordinate for current window
* y : target 'Y' coordinate for current window
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* width : width of current window
* height : height of current window
* x : current window 'X' coordinate
* y : current window 'Y' coordinate
* 400 - invalid argument
* 404 - invalid session ID
* @see Set Window Rect
*/
public static HttpResponse setWindowRect(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Map content = fromJson(req, MAP_OF_INTEGERS);
boolean didSet = false;
Integer width = content.get("width");
Integer height = content.get("height");
Integer x = content.get("x");
Integer y = content.get("y");
if (width != null && height != null) {
didSet = true;
driver.manage().window().setSize(new Dimension(width, height));
}
if (x != null && y != null) {
didSet = true;
driver.manage().window().setPosition(new Point(x, y));
}
if (!didSet) {
return errorForException(new InvalidArgumentException("SetWindowRect must specify size and/or position"));
}
return successWithWindowRect(driver);
}
/**
* Handle remote 'Maximize Window' request :: POST '/session/{sessionId}/window/maximize'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* width : width of current window
* height : height of current window
* x : current window 'X' coordinate
* y : current window 'Y' coordinate
* 404 - invalid session ID
* @see Maximize Window
*/
public static HttpResponse maximizeWindow(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.manage().window().maximize();
return successWithWindowRect(driver);
}
/**
* Handle remote 'Fullscreen Window' request :: POST '/session/{sessionId}/window/fullscreen'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* width : width of current window
* height : height of current window
* x : current window 'X' coordinate
* y : current window 'Y' coordinate
* 404 - invalid session ID
* @see Fullscreen Window
*/
public static HttpResponse fullscreenWindow(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.manage().window().fullscreen();
return successWithWindowRect(driver);
}
/**
* Handle remote 'Get Active Element' request :: GET '/session/{sessionId}/element/active'
*
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* element-6066-11e4-a52e-4f735466cecf : element identifier
* 404 - invalid session ID
* 404 - no such element
* @see Get Active Element
*/
public static HttpResponse getActiveElement(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
try {
return successWithWebElement(driver.switchTo().activeElement());
} catch (NoSuchElementException e) {
return errorForException(e);
}
}
/**
* Handle remote 'Find Element' request :: POST '/session/{sessionId}/element'
*
* @param req request with payload:
* value : element selector
* using : element locator strategy:
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* element-6066-11e4-a52e-4f735466cecf : element identifier
* 400 - invalid argument
* 400 - invalid selector
* 404 - invalid session ID
* 404 - no such element
* 404 - no such window
* @see Find Element
*/
public static HttpResponse findElement(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return findElement(req, driver);
}
/**
* Handle remote 'Find Elements' request :: POST '/session/{sessionId}/elements'
*
* @param req request with payload:
* value : element selector
* using : element locator strategy:
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* element-6066-11e4-a52e-4f735466cecf : element identifier
* 400 - invalid argument
* 400 - invalid selector
* 404 - invalid session ID
* 404 - no such window
* @see Find Elements
*/
public static HttpResponse findElements(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return findElements(req, driver);
}
/**
* Handle remote 'Find Element From Element' request :: POST ' /session/{sessionId}/element/{elementId}/element'
*
* @param req request with payload:
* value : element selector
* using : element locator strategy:
* @param sessionId target session ID
* @param elementId search context element ID
* @return response:
* 200 - success with data:
* element-6066-11e4-a52e-4f735466cecf : element identifier
* 400 - invalid argument
* 400 - invalid selector
* 404 - invalid session ID
* 404 - no such element
* 404 - no such window
* 404 - stale element reference
* @see Find Element From Element
*/
public static HttpResponse findElementFromElement(final HttpRequest req, final String sessionId, final String elementId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return findElement(req, driver.toWebElement(elementId));
}
/**
* Handle remote 'Find Elements From Element' request :: POST '/session/{sessionId}/element/{elementId}/elements'
*
* @param req request with payload:
* value : element selector
* using : element locator strategy:
* @param sessionId target session ID
* @param elementId search context element ID
* @return response:
* 200 - success with data:
* element-6066-11e4-a52e-4f735466cecf : element identifier
* 400 - invalid argument
* 400 - invalid selector
* 404 - invalid session ID
* 404 - no such window
* 404 - stale element reference
* @see Find Elements From Element
*/
public static HttpResponse findElementsFromElement(final HttpRequest req, final String sessionId, final String elementId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return findElements(req, driver.toWebElement(elementId));
}
/**
* Find the first element in the specified search context that matches the locator encoded in the specified request.
*
* @param req request with payload:
* value : element selector
* using : element locator strategy:
* @param context {@link SearchContext} - either the target driver or a root web element
* @return response:
* 200 - success with data:
* element-6066-11e4-a52e-4f735466cecf : element identifier
* 400 - invalid selector
* 404 - no such element
* 404 - stale element reference
*/
private static HttpResponse findElement(final HttpRequest req, final SearchContext context) {
By locator = locatorFrom(req);
try {
return successWithWebElement(context.findElement(locator));
} catch (NoSuchElementException | InvalidSelectorException e) {
return errorForException(e);
}
}
/**
* Find the all elements in the specified search context that match the locator encoded in the specified request.
*
* @param req request with payload:
* value : element selector
* using : element locator strategy:
* @param context {@link SearchContext} - either the target driver or a root web element
* @return response:
* 200 - success with data:
* element-6066-11e4-a52e-4f735466cecf : element identifier
* 400 - invalid selector
* 404 - stale element reference
*/
private static HttpResponse findElements(final HttpRequest req, final SearchContext context) {
By locator = locatorFrom(req);
try {
return successWithWebElement(context.findElements(locator));
} catch (InvalidSelectorException e) {
return errorForException(e);
}
}
/**
* Handle remote 'Is Element Selected' request :: GET '/session/{sessionId}/element/{elementId}/selected'
*
* @param sessionId target session ID
* @param elementId target element ID
* @return response:
* 200 - success with data:
* value : {@code true} if element is selected; otherwise {@code false}
* 404 - invalid session ID
* 404 - stale element reference
* @see Is Element Selected
*/
public static HttpResponse isElementSelected(final String sessionId, final String elementId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.toWebElement(elementId).isSelected());
}
/**
* Handle remote 'Get Element Attribute' request :: GET '/session/{sessionId}/element/{elementId}/attribute/{name}'
*
* @param sessionId target session ID
* @param elementId target element ID
* @param attrName attribute name
* @return response:
* 200 - success with data:
* value : attribute value if set; otherwise {@code null}
* 404 - invalid session ID
* 404 - stale element reference
* @see Get Element Attribute
*/
public static HttpResponse getElementDomAttribute(final String sessionId, final String elementId, final String attrName) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.toWebElement(elementId).getDomAttribute(attrName));
}
/**
* Handle remote 'Get Element Property' request :: GET '/session/{sessionId}/element/{elementId}/property/{name}'
*
* @param sessionId target session ID
* @param elementId target element ID
* @param propName property name
* @return response:
* 200 - success with data:
* value : property value if set; otherwise {@code null}
* 404 - invalid session ID
* 404 - stale element reference
* @see Get Element Property
*/
public static HttpResponse getElementDomProperty(final String sessionId, final String elementId, final String propName) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.toWebElement(elementId).getDomProperty(propName));
}
/**
* Handle remote 'Get Element CSS Value' request :: GET '/session/{sessionId}/element/{elementId}/css/{name}'
*
* @param sessionId target session ID
* @param elementId target element ID
* @param propName property name
* @return response:
* 200 - success with data:
* value : computed CSS property value if set; otherwise {@code null}
* 404 - invalid session ID
* 404 - stale element reference
* @see Get Element CSS Value
*/
public static HttpResponse getElementCssValue(final String sessionId, final String elementId, final String propName) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.toWebElement(elementId).getCssValue(propName));
}
/**
* Handle remote 'Get Element Text' request :: GET '/session/{sessionId}/element/{elementId}/text'
*
* @param sessionId target session ID
* @param elementId target element ID
* @return response:
* 200 - success with data:
* value : visible text of target element
* 404 - invalid session ID
* 404 - stale element reference
* @see Get Element Text
*/
public static HttpResponse getElementText(final String sessionId, final String elementId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.toWebElement(elementId).getText());
}
/**
* Handle remote 'Get Element Tag Name' request :: GET '/session/{sessionId}/element/{elementId}/name'
*
* @param sessionId target session ID
* @param elementId target element ID
* @return response:
* 200 - success with data:
* value : tag name of target element
* 404 - invalid session ID
* 404 - stale element reference
* @see Get Element Tag Name
*/
public static HttpResponse getElementTagName(final String sessionId, final String elementId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.toWebElement(elementId).getTagName());
}
/**
* Handle remote 'Get Element Rect' request :: GET '/session/{sessionId}/element/{elementId}/rect'
*
* @param sessionId target session ID
* @param elementId target element ID
* @return response:
* 200 - success with data:
* width : width of target element bounding rectangle
* height : height of target element bounding rectangle
* x : X position of target element top-left corner
* y : Y position of target element top-left corner
* 404 - invalid session ID
* 404 - stale element reference
* @see Get Element Rect
*/
public static HttpResponse getElementRect(final String sessionId, final String elementId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Rectangle rect = driver.toWebElement(elementId).getRect();
return successWithData(Map.of("width", rect.width, "height", rect.height, "x", rect.x, "y", rect.y));
}
/**
* Handle remote 'Is Element Enabled' request :: GET '/session/{sessionId}/element/{elementId}/enabled'
*
* @param sessionId target session ID
* @param elementId target element ID
* @return response:
* 200 - success with data:
* value : {@code true} if element is enabled; otherwise {@code false}
* 404 - invalid session ID
* 404 - stale element reference
* @see Is Element Enabled
*/
public static HttpResponse isElementEnabled(final String sessionId, final String elementId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.toWebElement(elementId).isEnabled());
}
/**
* Handle remote 'Element Click' request :: POST '/session/{sessionId}/element/{elementId}/click'
*
* @param sessionId target session ID
* @param elementId target element ID
* @return response:
* 200 - success
* 400 - element not interactable
* 400 - invalid element state
* 404 - invalid session ID
* 404 - stale element reference
* @see Element Click
*/
public static HttpResponse elementClick(final String sessionId, final String elementId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.toWebElement(elementId).click();
return successWithData(null);
}
/**
* Handle remote 'Element Clear' request :: POST '/session/{sessionId}/element/{elementId}/clear'
*
* @param sessionId target session ID
* @param elementId target element ID
* @return response:
* 200 - success
* 400 - element not interactable
* 400 - invalid element state
* 404 - invalid session ID
* 404 - stale element reference
* @see Element Clear
*/
public static HttpResponse elementClear(final String sessionId, final String elementId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.toWebElement(elementId).clear();
return successWithData(null);
}
/**
* Handle remote 'Element Send Keys' request :: POST '/session/{sessionId}/element/{elementId}/value'
*
* @param req request with data
* @param sessionId target session ID
* @param elementId target element ID
* @return response:
* 200 - success
* 400 - element not interactable
* 400 - invalid argument
* 400 - invalid element state
* 404 - invalid session ID
* 404 - no such window
* 404 - stale element reference
* @see Element Send Keys
*/
public static HttpResponse elementSendKeys(final HttpRequest req, final String sessionId, final String elementId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Map content = fromJson(req, MAP_OF_OBJECTS);
String keysToSend = content.get("text").toString();
driver.toWebElement(elementId).sendKeys(keysToSend);
return successWithData(null);
}
/**
* Handle remote 'Get Page Source' request :: GET '/session/{sessionId}/source'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* value : page source of target session
* 404 - invalid session ID
* 404 - no such window
* @see Get Page Source
*/
public static HttpResponse getPageSource(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.getPageSource());
}
/**
* Handle remote 'Execute (Async) Script' :: POST '/session/{sessionId}/execute/[sync|async]'
*
* @param req request with payload:
* script : JavaScript to execute
* args : list of arguments (may be empty)
* @param sessionId target session ID
* @param async {@code false} for synchronous execution; {@code true} for asynchronous execution
* @return response:
* 200 - success with data:
* value : result of script execution
* 404 - invalid session ID
* 404 - no such window
* 500 - javascript error
* 500 - script timeout
* @see Execute Script
* @see Execute Async Script
*/
public static HttpResponse executeScript(final HttpRequest req, final String sessionId, final boolean async) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Map content = fromJson(req, MAP_OF_OBJECTS);
Object script = content.get("script");
Object args = new JsonToHtmlUnitWebElementConverter(driver).apply(content.get("args"));
String errorMessage;
if (script instanceof String) {
if (args instanceof List) {
if (async) {
return successWithWebElement(driver.executeAsyncScript((String) script, ((List>) args).toArray()));
} else {
return successWithWebElement(driver.executeScript((String) script, ((List>) args).toArray()));
}
} else {
errorMessage = "Property 'args' is not a List";
}
} else {
errorMessage = "Property 'script' is not a String";
}
return errorForException(new InvalidArgumentException(errorMessage));
}
/**
* Handle remote 'Get All Cookies' request :: GET '/session/{sessionId}/cookie'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* value : list of target session cookies
* 404 - invalid session ID
* 404 - no such window
* @see Get All Cookies
*/
public static HttpResponse getAllCookies(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.manage().getCookies());
}
/**
* Handle remote 'Get Named Cookie' request :: GET '/session/{sessionId}/cookie/{name}'
*
* @param sessionId target session ID
* @param cookieName name of target cookie
* @return response:
* 200 - success with data:
* value : named cookie from target session; {@code null} if not found
* 404 - invalid session ID
* 404 - no such window
* @see Get Named Cookie
*/
public static HttpResponse getNamedCookie(final String sessionId, final String cookieName) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.manage().getCookieNamed(cookieName));
}
/**
* Handle remote 'Add Cookie' request :: POST '/session/{sessionId}/cookie'
*
* @param req request with payload:
* cookie : cookie object:
* name : cookie name
* value : cookie value
* domain : domain cookie is visible to (default: active document's domain)
* path : cookie path (default: "/")
* secure : {@code true} if cookie is secure (default: {@code false})
* httpOnly : {@code true} if cookie is HTTP-only (default: {@code false})
* sameSite : whether cookie applies to a Same Site policy (default: {@code None})
* expiry : when cookie expires in seconds since Unix Epoch (may be omitted)
* @param sessionId target session ID
* @return response:
* 200 - success
* 400 - invalid argument
* 400 - invalid cookie domain
* 404 - invalid session ID
* 404 - no such window
* 500 - javascript error
* 500 - script timeout
* @see Add Cookie
*/
public static HttpResponse addCookie(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Map content = fromJson(req, MAP_OF_COOKIES);
driver.manage().addCookie(content.get("cookie"));
return successWithData(null);
}
/**
* Handle remote 'Delete Named Cookie' request :: DELETE '/session/{sessionId}/cookie/{name}'
*
* @param sessionId target session ID
* @param cookieName name of target cookie
* @return response:
* 200 - success
* 404 - invalid session ID
* 404 - no such window
* @see Delete Named Cookie
*/
public static HttpResponse deleteNamedCookie(final String sessionId, final String cookieName) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.manage().deleteCookieNamed(cookieName);
return successWithData(null);
}
/**
* Handle remote 'Delete All Cookies' request :: DELETE '/session/{sessionId}/cookie'
*
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* 404 - no such window
* @see Delete All Cookies
*/
public static HttpResponse deleteAllCookies(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.manage().deleteAllCookies();
return successWithData(null);
}
/**
* Handle remote 'Perform Actions' request :: POST '/session/{sessionId}/actions'
*
* @param req request with payload:
* actions : map of source-specific {@link Sequence} objects
* @param sessionId target session ID
* @return response:
* 200 - success
* 400 - invalid argument
* 404 - invalid session ID
* 404 - no such element
* 404 - no such window
* @see Perform Actions
*/
public static HttpResponse performActions(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Map content = fromJson(req, MAP_OF_ACTIONS);
content.get("actions").resolveOrigins(driver).build().perform();
return successWithData(null);
}
/**
* Handle remote 'Release Actions' request :: DELETE '/session/{sessionId}/actions'
*
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* 404 - no such window
* @see Release Actions
*/
public static HttpResponse releaseActions(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.resetInputState();
return successWithData(null);
}
/**
* Handle remote 'Dismiss Alert' request :: POST '/session/{sessionId}/alert/dismiss'
*
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* 404 - no such alert
* 404 - no such window
* @see Dismiss Alert
*/
public static HttpResponse dismissAlert(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.getAlert().dismiss();
return successWithData(null);
}
/**
* Handle remote 'Accept Alert' request :: POST '/session/{sessionId}/alert/accept'
*
* @param sessionId target session ID
* @return response:
* 200 - success
* 404 - invalid session ID
* 404 - no such alert
* 404 - no such window
* @see Accept Alert
*/
public static HttpResponse acceptAlert(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
driver.getAlert().accept();
return successWithData(null);
}
/**
* Handle remote 'Get Alert Text' request :: GET '/session/{sessionId}/alert/text'
*
* @param sessionId target session ID
* @return response:
* 200 - success with data:
* value : text of active alert (may be {@code null})
* 404 - invalid session ID
* 404 - no such alert
* 404 - no such window
* @see Get Alert Text
*/
public static HttpResponse getAlertText(final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
return successWithData(driver.getAlert().getText());
}
/**
* Handle remote 'Send Alert Text' request :: GET '/session/{sessionId}/alert/text'
*
* @param req request with payload:
* text : character sequence to send to the alert
* @param sessionId target session ID
* @return response:
* 200 - success
* 400 - element not interactable
* 400 - invalid argument
* 404 - invalid session ID
* 404 - no such alert
* 404 - no such window
* 500 - unsupported operation
* @see Send Alert Text
*/
public static HttpResponse sendAlertText(final HttpRequest req, final String sessionId) {
HtmlUnitDriver driver = getDriverSession(sessionId);
Map content = fromJson(req, MAP_OF_OBJECTS);
driver.getAlert().sendKeys(content.get("text"));
return successWithData(null);
}
/**
* Extract session ID from the specified request parameters.
*
* @param params map of request parameters
* @return target session ID
*/
private static String sessionIdFrom(final Map params) {
return params.get("sessionId");
}
/**
* Extract element ID from the specified request parameters.
*
* @param params map of request parameters
* @return target element ID
*/
private static String elementIdFrom(final Map params) {
return params.get("elementId");
}
/**
* Extract name from the specified request parameters.
*
* @param params map of request parameters
* @return target name (attribute/property/value/cookie)
*/
private static String nameFrom(final Map params) {
return params.get("name");
}
/**
* Extract element locator from the specified request parameters.
*
* @param params map of request parameters
* @return element locator
*/
private static By locatorFrom(final HttpRequest req) {
Map content = fromJson(req, MAP_OF_STRINGS);
String value = content.get("value");
switch (content.get("using")) {
case "css selector":
return By.cssSelector(value);
case "link text":
return By.linkText(value);
case "partial link text":
return By.partialLinkText(value);
case "tag name":
return By.tagName(value);
case "xpath":
return By.xpath(value);
}
return null;
}
/**
* Get count of active driver sessions.
*
* @return count of active driver sessions
*/
static int getDriverCount() {
return driverMap.size();
}
/**
* Get driver session with the specified session ID.
*
* @param sessionId session ID
* @return {@link HtmlUnitDriver} with the specified ID
* @throws NoSuchSessionException if specific ID is not found
*/
static HtmlUnitDriver getDriverSession(final String sessionId) {
HtmlUnitDriver driver = driverMap.get(sessionId);
if (driver == null) {
throw new NoSuchSessionException("Failed finding session with identifier: " + sessionId);
}
return driver;
}
/**
* Assemble a 'success' response with the specified data.
*
* @param data data to include with response
* @return {@link HttpResponse} object with specified data
*/
private static HttpResponse successWithData(final Object data) {
Map content = new HashMap<>();
content.put("value", data);
return new HttpResponse().setContent(asJson(content));
}
/**
* Assemble a 'success' response with the specified data, encoding included web element.
*
* @param data data to include with response
* @return {@link HttpResponse} object with specified data, encoding {@link HtmlUnitWebElement} objects
*/
private static HttpResponse successWithWebElement(final Object data) {
return successWithData(new HtmlUnitWebElementToJsonConverter().apply(data));
}
/**
* Assemble a 'success' response with window rectangle dimensions of the specified session.
*
* @param driver target session driver
* @return {@link HttpResponse} object with data:
* width : width of current window
* height : height of current window
* x : current window 'X' coordinate
* y : current window 'Y' coordinate
*/
private static HttpResponse successWithWindowRect(final WebDriver driver) {
Dimension newSize = driver.manage().window().getSize();
Point newPosition = driver.manage().window().getPosition();
Map data = Map.of(
"width", newSize.getWidth(),
"height", newSize.getHeight(),
"x", newPosition.getX(),
"y", newPosition.getY());
return successWithData(data);
}
/**
* Assemble a 'success' response with timeout values of the specified session.
*
* @param driver target session driver
* @return {@link HttpResponse} object with data:
* script : script timeout (mS)
* pageLoad : page load timeout (mS)
* implicit : implicit timeout (mS)
*/
private static HttpResponse successWithTimeouts(final WebDriver driver) {
Timeouts timeouts = driver.manage().timeouts();
Map data = Map.of(
"script", timeouts.getScriptTimeout().toMillis(),
"pageLoad", timeouts.getPageLoadTimeout().toMillis(),
"implicit", timeouts.getImplicitWaitTimeout().toMillis());
return successWithData(data);
}
/**
* Assemble an error response for the specified exception.
*
* @param e exception encountered during request handling
* @return {@link HttpResponse} object with status and content for specified exception
*/
private static HttpResponse errorForException(final Throwable e) {
ErrorCodec codec = ErrorCodec.createDefault();
return new HttpResponse()
.setStatus(codec.getHttpStatusCode(e))
.setContent(asJson(codec.encode(e)));
}
}