chromedriver working, verbs alpha

This commit is contained in:
Jonathan Shook
2020-04-15 09:37:47 -05:00
parent 42a3a2f0af
commit 281542f42e
73 changed files with 1490 additions and 67 deletions

View File

@@ -1,12 +0,0 @@
package io.nosqlbench.driver.web;
import io.nosqlbench.engine.api.activityapi.core.ActivityType;
public class NBWebDriver implements ActivityType<WebDriverActivity> {
@Override
public String getName() {
return null;
}
}

View File

@@ -1,30 +0,0 @@
package io.nosqlbench.driver.web;
import io.nosqlbench.engine.api.activityapi.core.BaseAsyncAction;
import io.nosqlbench.engine.api.activityapi.core.ops.fluent.opfacets.TrackedOp;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.function.LongFunction;
/**
* Holds the definition and tracking state for a web driver command.
*/
public class WebDriverAction extends BaseAsyncAction<WebDriverCmdState,WebDriverActivity> {
public WebDriverAction(WebDriverActivity activity, int slot) {
super(activity,slot);
}
@Override
public void startOpCycle(TrackedOp<WebDriverCmdState> opc) {
// WebDriver driver = new ChromeDriver();
// driver.get("http://docs.nosqlbench.io/");
// opc.start();
}
@Override
public LongFunction<WebDriverCmdState> getOpInitFunction() {
return (cycle) -> new WebDriverCmdState(this,cycle);
}
}

View File

@@ -1,12 +0,0 @@
package io.nosqlbench.driver.web;
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
import io.nosqlbench.engine.api.activityimpl.SimpleActivity;
public class WebDriverActivity extends SimpleActivity{
public WebDriverActivity(ActivityDef activityDef) {
super(activityDef);
}
}

View File

@@ -0,0 +1,56 @@
package io.nosqlbench.driver.webdriver;
import io.nosqlbench.engine.api.activityconfig.yaml.StmtDef;
import io.nosqlbench.engine.api.activityimpl.motor.ParamsParser;
import io.nosqlbench.nb.api.errors.BasicError;
import io.nosqlbench.virtdata.core.bindings.BindingsTemplate;
import io.nosqlbench.virtdata.core.templates.ParsedTemplate;
import io.nosqlbench.virtdata.core.templates.StringBindings;
import io.nosqlbench.virtdata.core.templates.StringBindingsTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.InvalidParameterException;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Use the {@link StmtDef} template form as a property template for parameterized
* commands. This is a general purpose template which uses a map of named parameters.
* The {@code command} property designates the verb component of the command.
*/
public class CommandTemplate {
private final static Logger logger = LoggerFactory.getLogger(CommandTemplate.class);
private LinkedHashMap<String, StringBindings> cmdspec = new LinkedHashMap<>();
public CommandTemplate(StmtDef stmt) {
Map<String,String> cmdMap = ParamsParser.parse("command="+stmt.getStmt());
Map<String, String> paramsMap = stmt.getParams();
paramsMap.forEach((k,v) -> {
if (cmdMap.containsKey(k)) {
logger.warn("command property override: '" + k + "' superseded by param form with value '" + v + "'");
}
cmdMap.put(k,v);
});
cmdMap.forEach((param,value) -> {
ParsedTemplate paramTemplate = new ParsedTemplate(value, stmt.getBindings());
BindingsTemplate paramBindings = new BindingsTemplate(paramTemplate.getBindPoints());
StringBindings paramStringBindings = new StringBindingsTemplate(value, paramBindings).resolve();
cmdspec.put(param,paramStringBindings);
});
}
public Map<String,String> getCommand(long cycle) {
LinkedHashMap<String, String> cmd = new LinkedHashMap<>(cmdspec.size());
cmdspec.forEach((k,v) -> {
cmd.put(k,v.bind(cycle));
});
return cmd;
}
}

View File

@@ -0,0 +1,93 @@
package io.nosqlbench.driver.webdriver;
import org.openqa.selenium.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public class WebContext {
private final static Logger logger = LoggerFactory.getLogger(WebContext.class);
private final WebDriver rootwindow;
WebDriver focus;
LinkedList<WebElement> elements = new LinkedList<>();
private LinkedList<Cookie> cookies = new LinkedList<>();
private HashMap<String,Object> vars = new HashMap<>();
private Alert alert;
public WebContext(WebDriver initial) {
this.focus = initial;
this.rootwindow = initial;
}
public void pushElement(WebElement element) {
elements.push(element);
}
public WebElement peekElement() {
return elements.peek();
}
public LinkedList<Cookie> getCookies() {
return cookies;
}
public LinkedList<WebElement> getElements() {
return elements;
}
public void setElements(List<WebElement> elements) {
this.elements.clear();
this.elements.addAll(elements);
}
public void pushCookie(Cookie cookie) {
this.cookies.push(cookie);
}
public void setCookies(Collection<Cookie> cookies) {
this.cookies.clear();
this.cookies.addAll(cookies);
}
public void setAlert(Alert alert) {
this.alert = alert;
}
public Alert getAlert() {
return alert;
}
public WebDriver driver() {
return focus;
}
public void setFocus(WebDriver driver) {
this.focus =driver;
}
public void clearAlert() {
this.alert=null;
}
public void setVar(String key, Object value) {
this.vars.put(key,value);
logger.debug("context vars: '" + key + "'='" + value.toString() + "'");
}
public <T> T getVar(String name, Class<? extends T> type) {
Object o = this.vars.get(name);
if (o==null) { return null; }
if (type.isAssignableFrom(o.getClass())) {
return type.cast(o);
}
throw new RuntimeException("Could not cast named var '" + name + "' to a " + type.getCanonicalName());
}
}

View File

@@ -0,0 +1,54 @@
package io.nosqlbench.driver.webdriver;
import io.nosqlbench.driver.webdriver.verbs.WebDriverVerbs;
import io.nosqlbench.engine.api.activityapi.core.ActivityDefObserver;
import io.nosqlbench.engine.api.activityapi.core.SyncAction;
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
import org.openqa.selenium.WebDriver;
/**
* Holds the definition and tracking state for a web driver command.
*/
public class WebDriverAction implements SyncAction, ActivityDefObserver {
private final WebDriverActivity activity;
private final int slot;
// warn or count, or stop
private String errors;
private boolean dryrun;
private WebContext context;
public WebDriverAction(WebDriverActivity activity, int slot) {
super();
this.activity = activity;
this.slot = slot;
}
@Override
public void init() {
onActivityDefUpdate(activity.getActivityDef());
}
@Override
public void onActivityDefUpdate(ActivityDef activityDef) {
this.errors = activityDef.getParams().getOptionalString("errors").orElse("stop");
this.dryrun = activityDef.getParams().getOptionalBoolean("dryrun").orElse(false);
this.context = activity.getWebContext(slot);
}
// TODO: resolve inner templates early, perhaps optionally
// As it is right now, all commands are resolved dynamically, which is still not going to be the limiting
// factor.
@Override
public int runCycle(long value) {
try {
CommandTemplate commandTemplate = activity.getOpSequence().get(value);
WebDriverVerbs.execute(value, commandTemplate, context, dryrun);
return 0;
} catch (Exception e) {
return 1;
}
}
}

View File

@@ -0,0 +1,101 @@
package io.nosqlbench.driver.webdriver;
import io.nosqlbench.engine.api.activityapi.planning.OpSequence;
import io.nosqlbench.engine.api.activityapi.planning.SequencePlanner;
import io.nosqlbench.engine.api.activityapi.planning.SequencerType;
import io.nosqlbench.engine.api.activityconfig.StatementsLoader;
import io.nosqlbench.engine.api.activityconfig.yaml.StmtDef;
import io.nosqlbench.engine.api.activityconfig.yaml.StmtsDocList;
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
import io.nosqlbench.engine.api.activityimpl.SimpleActivity;
import io.nosqlbench.engine.api.templating.StrInterpolator;
import io.nosqlbench.nb.api.errors.BasicError;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class WebDriverActivity extends SimpleActivity {
private final static Logger logger = LoggerFactory.getLogger(WebDriverActivity.class);
private final StmtsDocList stmtsDocList;
private OpSequence<CommandTemplate> opSequence;
private static ThreadLocal<WebContext> TL_WebContext = new ThreadLocal<>();
private ConcurrentHashMap<Integer,WebContext> contexts = new ConcurrentHashMap<>();
public WebDriverActivity(ActivityDef activityDef) {
super(activityDef);
StrInterpolator interp = new StrInterpolator(activityDef);
String yaml_loc = activityDef.getParams().getOptionalString("yaml", "workload").orElse("default");
this.stmtsDocList = StatementsLoader.load(logger, yaml_loc, interp, "activities");
}
@Override
public void initActivity() {
super.initActivity();
this.opSequence = initOpSequence();
onActivityDefUpdate(activityDef);
}
private OpSequence<CommandTemplate> initOpSequence() {
SequencerType sequencerType = getParams()
.getOptionalString("seq")
.map(SequencerType::valueOf)
.orElse(SequencerType.bucket);
SequencePlanner<CommandTemplate> planner = new SequencePlanner<>(sequencerType);
String tagfilter = activityDef.getParams().getOptionalString("tags").orElse("");
List<StmtDef> stmts = stmtsDocList.getStmts(tagfilter);
if (stmts.size() == 0) {
throw new BasicError("There were no active statements with tag filter '" + tagfilter + "'");
}
for (StmtDef optemplate : stmts) {
long ratio = Long.parseLong(optemplate.getParams().getOrDefault("ratio", "1"));
CommandTemplate cmd = new CommandTemplate(optemplate);
planner.addOp(cmd, ratio);
}
return planner.resolve();
}
public OpSequence<CommandTemplate> getOpSequence() {
return opSequence;
}
public synchronized WebContext getWebContext(int slot) {
try {
WebContext context = TL_WebContext.get();
if (context == null) {
logger.info("initializing chromedriver for thread " + slot);
System.setProperty("webdriver.http.factory", "okhttp");
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setHeadless(activityDef.getParams().getOptionalBoolean("headless").orElse(false));
WebDriver webdriver = new ChromeDriver(chromeOptions);
context = new WebContext(webdriver);
contexts.put(slot,context);
TL_WebContext.set(context);
} else {
logger.info("using cached chromedriver for thread " + slot);
}
return context;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void shutdownActivity() {
contexts.forEach((s, d) -> {
logger.debug("closing driver for thread " + s);
d.driver().quit();
});
}
}

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.driver.web;
package io.nosqlbench.driver.webdriver;
import io.nosqlbench.engine.api.activityapi.core.Action;
import io.nosqlbench.engine.api.activityapi.core.ActionDispenser;

View File

@@ -1,4 +1,4 @@
package io.nosqlbench.driver.web;
package io.nosqlbench.driver.webdriver;
public class WebDriverCmdState {

View File

@@ -0,0 +1,21 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Alert;
import java.security.InvalidParameterException;
public class AcceptAlert implements WebDriverVerb {
@Override
public void execute(WebContext context) {
Alert alert = context.getAlert();
if (alert==null) {
alert = context.driver().switchTo().alert();
}
if (alert==null) {
throw new InvalidParameterException("Alert is not present");
}
alert.accept();
context.clearAlert();
}
}

View File

@@ -0,0 +1,18 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Cookie;
public class AddCookie implements WebDriverVerb {
private final Cookie cookie;
public AddCookie(Cookie cookie) {
this.cookie = cookie;
}
@Override
public void execute(WebContext context) {
context.driver().manage().addCookie(this.cookie);
}
}

View File

@@ -0,0 +1,26 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import io.nosqlbench.nb.api.errors.BasicError;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AssertElement implements WebDriverVerb {
private final static Logger logger = LoggerFactory.getLogger(AssertElement.class);
private final By by;
public AssertElement(By by) {
this.by = by;
}
@Override
public void execute(WebContext context) {
WebElement element = context.driver().findElement(by);
context.pushElement(element);
}
}

View File

@@ -0,0 +1,31 @@
package io.nosqlbench.driver.webdriver.verbs;
import org.openqa.selenium.By;
import java.util.function.Function;
public enum Bys {
id(By::id),
link(By::linkText),
name(By::name),
css(By::cssSelector),
xpath(By::xpath),
classname(By::className);
private Function<String, By> initializer;
Bys(Function<String,By> initializer) {
this.initializer = initializer;
}
public static By get(String by) {
Bys bys =classname;
String[] parts = by.split("=", 2);
if (parts.length==2) {
bys= Bys.valueOf(parts[0]);
by = parts[1];
}
return bys.initializer.apply(by);
}
}

View File

@@ -0,0 +1,10 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class ClearElement implements WebDriverVerb {
@Override
public void execute(WebContext context) {
context.peekElement().clear();
}
}

View File

@@ -0,0 +1,17 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.By;
public class ClearElementBy implements WebDriverVerb {
private final By by;
public ClearElementBy(By by) {
this.by = by;
}
@Override
public void execute(WebContext context) {
context.peekElement().findElement(by).clear();
}
}

View File

@@ -0,0 +1,18 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.By;
public class ClickElementBy implements WebDriverVerb {
private final By by;
public ClickElementBy(By by){
this.by = by;
}
@Override
public void execute(WebContext context) {
context.driver().findElement(by).click();
}
}

View File

@@ -0,0 +1,22 @@
package io.nosqlbench.driver.webdriver.verbs;
import org.openqa.selenium.Cookie;
import java.sql.Date;
import java.util.Map;
import java.util.Optional;
public class CookieJar {
public static Cookie cookie(Map<String,String> props) {
String name = props.get("name");
String value = props.getOrDefault("value","");
Cookie.Builder builder = new Cookie.Builder(name, value);
Optional.ofNullable(props.get("domain")).ifPresent(builder::domain);
Optional.ofNullable(props.get("expiry")).map(Date::valueOf).ifPresent(builder::expiresOn);
Optional.ofNullable(props.get("ishttponly")).map(Boolean::valueOf).ifPresent(builder::isHttpOnly);
Optional.ofNullable(props.get("issecure")).map(Boolean::valueOf).ifPresent(builder::isSecure);
Optional.ofNullable(props.get("path")).ifPresent(builder::path);
return builder.build();
}
}

View File

@@ -0,0 +1,11 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class DeleteAllCookies implements WebDriverVerb {
@Override
public void execute(WebContext context) {
context.driver().manage().deleteAllCookies();
}
}

View File

@@ -0,0 +1,18 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Cookie;
public class DeleteCookie implements WebDriverVerb {
private final Cookie cookie;
public DeleteCookie(Cookie cookie) {
this.cookie = cookie;
}
@Override
public void execute(WebContext context) {
context.driver().manage().deleteCookie(cookie);
}
}

View File

@@ -0,0 +1,17 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class DeleteCookieNamed implements WebDriverVerb {
private final String cookieName;
public DeleteCookieNamed(String cookieName) {
this.cookieName = cookieName;
}
@Override
public void execute(WebContext context) {
context.driver().manage().deleteCookieNamed(cookieName);
}
}

View File

@@ -0,0 +1,21 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Alert;
import java.security.InvalidParameterException;
public class DismissAlert implements WebDriverVerb {
@Override
public void execute(WebContext context) {
Alert alert = context.getAlert();
if (alert==null) {
alert = context.driver().switchTo().alert();
}
if (alert==null) {
throw new InvalidParameterException("Alert is not present");
}
alert.dismiss();
context.clearAlert();
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.OutputType;
public class ElementScreenShot implements WebDriverVerb {
@Override
public void execute(WebContext context) {
String screenshotAs = context.peekElement().getScreenshotAs(OutputType.BASE64);
// This needs more work
}
}

View File

@@ -0,0 +1,16 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class ElementSendKeys implements WebDriverVerb {
private final CharSequence keys;
public ElementSendKeys(CharSequence keys) {
this.keys = keys;
}
@Override
public void execute(WebContext context) {
context.peekElement().sendKeys(keys);
}
}

View File

@@ -0,0 +1,10 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class ElementSubmit implements WebDriverVerb {
@Override
public void execute(WebContext context) {
context.peekElement().submit();
}
}

View File

@@ -0,0 +1,30 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FindElement implements WebDriverVerb {
private final static Logger logger = LoggerFactory.getLogger(FindElement.class);
private final By by;
public FindElement(String by) {
this.by = Bys.get(by);
}
@Override
public void execute(WebContext context) {
try {
WebElement element = context.driver().findElement(by);
context.pushElement(element);
} catch (NoSuchElementException nsee) {
context.pushElement(null);
}
}
}

View File

@@ -0,0 +1,19 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
public class FindElementInElementBy implements WebDriverVerb {
private final By by;
public FindElementInElementBy(By by) {
this.by = by;
}
@Override
public void execute(WebContext context) {
WebElement element = context.peekElement().findElement(by);
context.pushElement(element);
}
}

View File

@@ -0,0 +1,32 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class FindElements implements WebDriverVerb {
private final static Logger logger = LoggerFactory.getLogger(FindElements.class);
private final By by;
public FindElements(String by) {
this.by = Bys.get(by);
}
@Override
public void execute(WebContext context) {
try {
List<WebElement> elements = context.driver().findElements(by);
context.setElements(elements);
} catch (NoSuchElementException nsee) {
context.pushElement(null);
}
}
}

View File

@@ -0,0 +1,22 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.List;
public class FindElementsInElementBy implements WebDriverVerb {
private final By by;
public FindElementsInElementBy(By by) {
this.by = by;
}
@Override
public void execute(WebContext context) {
List<WebElement> elements = context.peekElement().findElements(by);
context.setElements(elements);
}
}

View File

@@ -0,0 +1,10 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class FullScreen implements WebDriverVerb {
@Override
public void execute(WebContext context) {
context.driver().manage().window().fullscreen();
}
}

View File

@@ -0,0 +1,21 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Get implements WebDriverVerb {
private final static Logger logger = LoggerFactory.getLogger(Get.class);
private final String target;
public Get(String target) {
this.target = target;
}
@Override
public void execute(WebContext context) {
context.driver().get(target);
}
}

View File

@@ -0,0 +1,18 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Cookie;
public class GetCookieNamed implements WebDriverVerb {
private final String cookieName;
public GetCookieNamed(String cookieName) {
this.cookieName = cookieName;
}
@Override
public void execute(WebContext context) {
Cookie cookie = context.driver().manage().getCookieNamed(cookieName);
context.pushCookie(cookie);
}
}

View File

@@ -0,0 +1,14 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Cookie;
import java.util.Set;
public class GetCookies implements WebDriverVerb {
@Override
public void execute(WebContext context) {
Set<Cookie> cookies = context.driver().manage().getCookies();
context.setCookies(cookies);
}
}

View File

@@ -0,0 +1,18 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class GetElementAttribute implements WebDriverVerb {
private final String name;
public GetElementAttribute(String name) {
this.name = name;
}
@Override
public void execute(WebContext context) {
String attribute = context.peekElement().getAttribute(name);
context.setVar("element.attribute",attribute);
}
}

View File

@@ -0,0 +1,16 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
class GetElementCssValue implements WebDriverVerb {
private final String propname;
public GetElementCssValue(String propname) {
this.propname = propname;
}
@Override
public void execute(WebContext context) {
String cssValue = context.peekElement().getCssValue(propname);
context.setVar("element.cssvalue",cssValue);
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Point;
public class GetElementLocation implements WebDriverVerb {
@Override
public void execute(WebContext context) {
Point location = context.peekElement().getLocation();
context.setVar("element.location",location);
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Rectangle;
public class GetElementRect implements WebDriverVerb {
@Override
public void execute(WebContext context) {
Rectangle rect = context.peekElement().getRect();
context.setVar("element.rect",rect);
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Dimension;
public class GetElementSize implements WebDriverVerb {
@Override
public void execute(WebContext context) {
Dimension size = context.peekElement().getSize();
context.setVar("element.size",size);
}
}

View File

@@ -0,0 +1,11 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class GetElementTagname implements WebDriverVerb {
@Override
public void execute(WebContext context) {
String tagName = context.peekElement().getTagName();
context.setVar("element.tagname",tagName);
}
}

View File

@@ -0,0 +1,11 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class GetElementText implements WebDriverVerb {
@Override
public void execute(WebContext context) {
String text = context.peekElement().getText();
context.setVar("element.text",text);
}
}

View File

@@ -0,0 +1,11 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class IsElementDisplayed implements WebDriverVerb {
@Override
public void execute(WebContext context) {
boolean displayed = context.peekElement().isDisplayed();
context.setVar("element.displayed",displayed);
}
}

View File

@@ -0,0 +1,11 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class IsElementEnabled implements WebDriverVerb {
@Override
public void execute(WebContext context) {
boolean enabled = context.peekElement().isEnabled();
context.setVar("element.enabled",enabled);
}
}

View File

@@ -0,0 +1,11 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class IsElementSelected implements WebDriverVerb {
@Override
public void execute(WebContext context) {
boolean selected = context.peekElement().isSelected();
context.setVar("element.selected",selected);
}
}

View File

@@ -0,0 +1,11 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class NavigateBack implements WebDriverVerb {
@Override
public void execute(WebContext context) {
context.driver().navigate().back();
}
}

View File

@@ -0,0 +1,10 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class NavigateForward implements WebDriverVerb {
@Override
public void execute(WebContext context) {
context.driver().navigate().forward();
}
}

View File

@@ -0,0 +1,10 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class NavigateRefresh implements WebDriverVerb {
@Override
public void execute(WebContext context) {
context.driver().navigate().refresh();
}
}

View File

@@ -0,0 +1,24 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import java.net.MalformedURLException;
import java.net.URL;
public class NavigateTo implements WebDriverVerb {
private final URL url;
public NavigateTo(String to) {
try {
this.url = new URL(to);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
@Override
public void execute(WebContext context) {
context.driver().navigate().to(url);
}
}

View File

@@ -0,0 +1,27 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Alert;
import java.security.InvalidParameterException;
public class SendKeysToAlert implements WebDriverVerb {
private final String keys;
public SendKeysToAlert(String keys) {
this.keys = keys;
}
@Override
public void execute(WebContext context) {
Alert alert = context.getAlert();
if (alert==null) {
alert = context.driver().switchTo().alert();
}
if (alert==null) {
throw new InvalidParameterException("Alert is not present");
}
alert.sendKeys(keys);
context.clearAlert();
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.WebElement;
public class SwitchToActiveElement implements WebDriverVerb {
@Override
public void execute(WebContext context) {
WebElement webElement = context.driver().switchTo().activeElement();
context.pushElement(webElement);
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Alert;
public class SwitchToAlert implements WebDriverVerb {
@Override
public void execute(WebContext context) {
Alert alert = context.driver().switchTo().alert();
context.setAlert(alert);
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.WebDriver;
public class SwitchToDefaultContent implements WebDriverVerb {
@Override
public void execute(WebContext context) {
WebDriver driver = context.driver().switchTo().defaultContent();
context.setFocus(driver);
}
}

View File

@@ -0,0 +1,18 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.WebDriver;
public class SwitchToFrameByName implements WebDriverVerb {
private String name;
public SwitchToFrameByName(String name) {
this.name = name;
}
@Override
public void execute(WebContext context) {
WebDriver frame = context.driver().switchTo().frame(this.name);
context.setFocus(frame);
}
}

View File

@@ -0,0 +1,19 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import java.security.InvalidParameterException;
public class SwitchToFrameElement implements WebDriverVerb {
@Override
public void execute(WebContext context) {
WebElement webElement = context.peekElement();
if (webElement==null) {
throw new InvalidParameterException("There was no previously found element to switch to.");
}
WebDriver frame = context.driver().switchTo().frame(webElement);
context.setFocus(frame);
}
}

View File

@@ -0,0 +1,22 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class SwitchToFrameElementBy implements WebDriverVerb {
private final By by;
public SwitchToFrameElementBy(String by) {
this.by = Bys.get(by);
}
@Override
public void execute(WebContext context) {
WebElement element = context.driver().findElement(by);
WebDriver frame = context.driver().switchTo().frame(element);
context.setFocus(frame);
}
}

View File

@@ -0,0 +1,18 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.WebDriver;
public class SwitchToFrameIdx implements WebDriverVerb {
private final int index;
public SwitchToFrameIdx(int index) {
this.index = index;
}
@Override
public void execute(WebContext context) {
WebDriver frame = context.driver().switchTo().frame(index);
context.setFocus(frame);
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.WebDriver;
public class SwitchToParentFrame implements WebDriverVerb {
@Override
public void execute(WebContext context) {
WebDriver webDriver = context.driver().switchTo().parentFrame();
context.setFocus(webDriver);
}
}

View File

@@ -0,0 +1,18 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.WebDriver;
public class SwitchToWindow implements WebDriverVerb {
private final String windowName;
public SwitchToWindow(String windowName) {
this.windowName = windowName;
}
@Override
public void execute(WebContext context) {
WebDriver window = context.driver().switchTo().window(this.windowName);
context.setFocus(window);
}
}

View File

@@ -0,0 +1,17 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.WebDriver;
/**
* All WebDriverVerb implementations are executable commands.
*/
public interface WebDriverVerb {
/**
* Execute the command.
*
* @param context The context object allows verbs to do have state from one command to the next. It is a
* {@link ThreadLocal} object which can be modified by any verb.
*/
void execute(WebContext context);
}

View File

@@ -0,0 +1,120 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.CommandTemplate;
import io.nosqlbench.driver.webdriver.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.InvalidParameterException;
import java.util.Map;
import java.util.function.Function;
public class WebDriverVerbs {
private final static Logger logger = LoggerFactory.getLogger(WebDriverVerbs.class);
public final static String COMMAND = "command";
public enum Verb {
get(Get.class, (m) -> new Get(m.get("target"))),
find_element(FindElement.class, (m) -> new FindElement(m.get("by"))),
find_elements(FindElements.class, (m) -> new FindElements(m.get("by"))),
// navigation
back(NavigateBack.class, (m) -> new NavigateBack()),
forward(NavigateForward.class, (m) -> new NavigateForward()),
refresh(NavigateRefresh.class, (m) -> new NavigateRefresh()),
to(NavigateTo.class, (m) -> new NavigateTo(m.get("to"))),
// options
add_cookie(AddCookie.class, (m) -> new AddCookie(CookieJar.cookie(m))),
delete_cookie(DeleteCookie.class, (m) -> new DeleteCookie(CookieJar.cookie(m))),
delete_all_cookies(DeleteAllCookies.class, (m) -> new DeleteAllCookies()),
delete_cookie_named(DeleteCookieNamed.class, (m) -> new DeleteCookieNamed(m.get("name"))),
get_cookie_named(GetCookieNamed.class, (m) -> new GetCookieNamed(m.get("name"))),
get_cookies(GetCookies.class, (m) -> new GetCookies()),
// TargetLocator (switchTo)
switchto_active_element(SwitchToActiveElement.class, (m) -> new SwitchToActiveElement()),
switchto_alert(SwitchToAlert.class, (m) -> new SwitchToAlert()),
switchto_default_content(SwitchToDefaultContent.class, (m) -> new SwitchToDefaultContent()),
switchto_frame_idx(SwitchToFrameIdx.class, (m) -> new SwitchToFrameIdx(Integer.parseInt(m.get("index")))),
switchto_frame_elem_by(SwitchToFrameElementBy.class, (m) -> new SwitchToFrameElementBy(m.get("by"))),
switchto_frame_elem(SwitchToFrameElement.class, (m) -> new SwitchToFrameElement()),
switchto_frame_name(SwitchToFrameByName.class, (m) -> new SwitchToFrameByName(m.get("name"))),
switchto_parent_frame(SwitchToParentFrame.class, (m) -> new SwitchToParentFrame()),
switchto_window(SwitchToWindow.class, (m) -> new SwitchToWindow(m.get("name"))),
// Alert
dismiss_alert(DismissAlert.class, (m) -> new DismissAlert()),
accept_alert(AcceptAlert.class, (m) -> new AcceptAlert()),
send_keys_to_alert(SendKeysToAlert.class, (m) -> new SendKeysToAlert(m.get("keys"))),
// Window
window_full_screen(FullScreen.class, (m) -> new FullScreen()),
window_get_size(WindowGetSize.class, (m) -> new WindowGetSize()),
window_set_size(WindowSetSize.class, (m) -> new WindowSetSize(m.get("width"), m.get("height"))),
window_maximize(WindowMaximize.class, (m) -> new WindowMaximize()),
window_set_position(WindowSetPosition.class, (m) -> new WindowSetPosition(m.get("x"),m.get("y"))),
window_get_position(WindowGetPosition.class, (m) -> new WindowGetPosition()),
// Elements
click_element_by(ClickElementBy.class, (m) -> new ClickElementBy(Bys.get(m.get("by")))),
clearElement(ClearElement.class, (m) -> new ClearElement()),
clearElement_by(ClearElementBy.class, (m) -> new ClearElementBy(Bys.get(m.get("by")))),
element_find_element_by(FindElementInElementBy.class, (m) -> new FindElementInElementBy(Bys.get(m.get("by")))),
element_find_elements_by(FindElementsInElementBy.class, (m)->new FindElementsInElementBy(Bys.get(m.get("by")))),
element_find_elements(FindElementsInElementBy.class, (m)->new FindElementsInElementBy(Bys.get(m.get("by")))),
element_get_attribute(GetElementAttribute.class, (m) -> new GetElementAttribute(m.get("name"))),
element_get_css_value(GetElementCssValue.class, (m) -> new GetElementCssValue(m.get("name"))),
element_get_location(GetElementLocation.class, (m) -> new GetElementLocation()),
element_get_rect(GetElementRect.class, (m) ->new GetElementRect()),
element_get_size(GetElementSize.class, (m) -> new GetElementSize()),
element_get_tagname(GetElementTagname.class, (m) -> new GetElementTagname()),
element_get_text(GetElementText.class, (m) -> new GetElementText()),
is_element_displayed(IsElementDisplayed.class, (m) -> new IsElementDisplayed()),
is_element_enabled(IsElementEnabled.class, (m) -> new IsElementEnabled()),
is_element_selected(IsElementSelected.class, (m) -> new IsElementSelected()),
element_send_keys(ElementSendKeys.class, (m) -> new ElementSendKeys(m.get("keys"))),
element_submit(ElementSubmit.class, (m) -> new ElementSubmit()),
element_get_screenshot(ElementScreenShot.class, (m) -> new ElementScreenShot())
;
private final Class<? extends WebDriverVerb> verbClass;
private final Function<Map<String, String>, WebDriverVerb> initializer;
Verb(Class<? extends WebDriverVerb> verbClass, Function<Map<String, String>, WebDriverVerb> initializer) {
this.verbClass = verbClass;
this.initializer = initializer;
}
public WebDriverVerb resolve(Map<String, String> commandProps) {
String cmd = commandProps.get(COMMAND);
if (cmd == null) {
throw new InvalidParameterException("command properties must always contain a 'command' entry'");
}
Verb verb = valueOf(cmd);
return verb.initializer.apply(commandProps);
}
}
public static void execute(
long cycle,
CommandTemplate commandTemplate,
WebContext context,
boolean dryrun
) {
Map<String, String> cmdprops = commandTemplate.getCommand(cycle);
logger.debug("cycle:" + cmdprops + " command:" + cmdprops);
String command = cmdprops.get("command");
Verb verb = Verb.valueOf(command);
WebDriverVerb resolve = verb.resolve(cmdprops);
if (dryrun) {
logger.info("skipping cycle " + cycle + " because dryrun is set to true");
return;
} else {
logger.info("running cycle " + cycle + " because dryrun is set to false");
}
resolve.execute(context);
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Point;
public class WindowGetPosition implements WebDriverVerb {
@Override
public void execute(WebContext context) {
Point position = context.driver().manage().window().getPosition();
context.setVar("window.position", position);
}
}

View File

@@ -0,0 +1,12 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Dimension;
public class WindowGetSize implements WebDriverVerb {
@Override
public void execute(WebContext context) {
Dimension size = context.driver().manage().window().getSize();
context.setVar("window.size",size);
}
}

View File

@@ -0,0 +1,10 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
public class WindowMaximize implements WebDriverVerb {
@Override
public void execute(WebContext context) {
context.driver().manage().window().maximize();
}
}

View File

@@ -0,0 +1,19 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Point;
public class WindowSetPosition implements WebDriverVerb {
private final int x;
private final int y;
public WindowSetPosition(String x, String y) {
this.x = Integer.parseInt(x);
this.y = Integer.parseInt(y);
}
@Override
public void execute(WebContext context) {
context.driver().manage().window().setPosition(new Point(x, y));
}
}

View File

@@ -0,0 +1,24 @@
package io.nosqlbench.driver.webdriver.verbs;
import io.nosqlbench.driver.webdriver.WebContext;
import org.openqa.selenium.Dimension;
public class WindowSetSize implements WebDriverVerb {
private final int width;
private final int height;
public WindowSetSize(int width, int height) {
this.width = width;
this.height = height;
}
public WindowSetSize(String width, String height) {
this.width = Integer.parseInt(width);
this.height = Integer.parseInt(height);
}
@Override
public void execute(WebContext context) {
context.driver().manage().window().setSize(new Dimension(width, height));
}
}

View File

@@ -0,0 +1,3 @@
# WebDriver Driver
welcome to the experimental webdriver prototype for nosqlbench.

View File

@@ -1,13 +1,11 @@
package io.nosqlbench.driver.web;
package io.nosqlbench.driver.webdriver;
import io.nosqlbench.nb.api.testutils.Perf;
import org.junit.Ignore;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.remote.RemoteWebElement;
/**