com.ats.executor.drivers.engines.MobileDriverEngine Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ats-automated-testing Show documentation
Show all versions of ats-automated-testing Show documentation
Code generator library to create and execute GUI automated tests
The newest version!
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF 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 com.ats.executor.drivers.engines;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.imageio.ImageIO;
import com.ats.data.Point;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import com.ats.data.Dimension;
import com.ats.data.Rectangle;
import com.ats.driver.ApplicationProperties;
import com.ats.element.AtsBaseElement;
import com.ats.element.AtsMobileElement;
import com.ats.element.DialogBox;
import com.ats.element.FoundElement;
import com.ats.element.MobileRootElement;
import com.ats.element.MobileTestElement;
import com.ats.element.test.TestElement;
import com.ats.executor.ActionStatus;
import com.ats.executor.ActionTestScript;
import com.ats.executor.SendKeyData;
import com.ats.executor.TestBound;
import com.ats.executor.channels.Channel;
import com.ats.executor.channels.MobileChannel;
import com.ats.executor.drivers.IDriverInfo;
import com.ats.executor.drivers.desktop.DesktopWindow;
import com.ats.executor.drivers.desktop.SystemDriver;
import com.ats.executor.drivers.engines.mobiles.AndroidRootElement;
import com.ats.executor.drivers.engines.mobiles.IosRootElement;
import com.ats.executor.drivers.engines.mobiles.MobileAlert;
import com.ats.executor.drivers.engines.mobiles.RootElement;
import com.ats.generator.ATS;
import com.ats.generator.objects.BoundData;
import com.ats.generator.objects.Cartesian;
import com.ats.generator.objects.MouseDirection;
import com.ats.generator.variables.CalculatedProperty;
import com.ats.graphic.ImageTemplateMatchingSimple;
import com.ats.script.actions.ActionApi;
import com.ats.tools.Utils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Charsets;
import com.google.common.io.CharStreams;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class MobileDriverEngine extends DriverEngine implements IDriverEngine {
public final static String DRIVER = "driver";
private final static String APP = "app";
public final static String START = "start";
public final static String STOP = "stop";
private final static String SWITCH = "switch";
private final static String CAPTURE = "capture";
private final static String SYS_CAPTURE = "syscapture";
public final static String INPUT = "input";
public final static String ELEMENT = "element";
public final static String ALERT = "alert";
public final static String TAP = "tap";
public final static String PRESS = "press";
public final static String SWIPE = "swipe";
public final static String SELECT = "select";
public final static String SCRIPTING = "scripting";
public final static String SET_PROP = "property-set";
public final static String SYS_BUTTON = "sysbutton";
public final static String atsVersion = ATS.getAtsVersion();
private final static String SCREENSHOT_METHOD = "/screenshot";
private JsonNode source;
private MobileTestElement testElement;
private OkHttpClient client;
protected RootElement rootElement;
protected RootElement cachedElement;
protected long cachedElementTime = 0L;
private String userAgent;
private String token;
private String endPoint;
// public Rectangle2D.Double deadZone;
private final ObjectMapper jsonMapper = new ObjectMapper();
public String serialNumber;
public String chromeDriver;
public String chromeDriverVersion;
public String chromeVersion;
public String statusPage;
public MobileDriverEngine(
MobileChannel channel,
ActionStatus status,
String app,
IDriverInfo driverInfo,
SystemDriver systemDriver,
ApplicationProperties props,
String token,
boolean enableLearning) {
super(channel, driverInfo, systemDriver, props, 0, 60, enableLearning);
getSystemDriver().setEngine(new SystemDriverEngine(channel, new DesktopWindow(), enableLearning));
if (applicationPath == null) {
applicationPath = app;
}
final int start = applicationPath.indexOf("://");
if (start > -1) {
applicationPath = applicationPath.substring(start + 3);
}
final String[] appData = applicationPath.split("/");
if (appData.length > 0) {
endPoint = appData[0];
this.applicationPath = "http://" + endPoint;
this.client = new Builder().cache(null).connectTimeout(30, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS).readTimeout(40, TimeUnit.SECONDS).build();
this.userAgent = "AtsMobileDriver/" + ATS.getAtsVersion() + "," + System.getProperty("user.name") + ",";
this.token = token;
JsonNode response = executeRequest(DRIVER, START);
if (response == null) {
status.setError(ActionStatus.CHANNEL_START_ERROR, "unable to connect to [ mobile://" + endPoint + " ]");
return;
}
// handle driver start error
if (response.get("status").asInt() != 0) {
status.setError(ActionStatus.CHANNEL_START_ERROR, response.get("message").asText());
return;
}
this.token = response.get("token").asText();
channel.addSystemProperties(response.withArray("systemProperties").elements());
channel.addSystemButtons(response.withArray("systemButtons").elements());
final String systemName = response.get("systemName").asText();
final String driverVersion = response.get("driverVersion").asText();
final String userName = response.get("mobileUser").asText();
final String deviceName = response.get("deviceName").asText();
final String osBuild = response.get("osBuild").asText();
final String country = response.get("country").asText();
final String os = response.get("os").asText();
double deviceWidth = 0;
double deviceHeight = 0;
double channelWidth = 0;
double channelHeight = 0;
double scale = 1;
double captureScale = response.get("scale").asDouble();
if (os.equals("android")) {
serialNumber = response.get("serialNumber").asText();
chromeDriver = response.get("chromeDriver").asText();
chromeDriverVersion = response.get("chromeDriverVersion").asText();
if (response.has("chromeVersion")) {
chromeVersion = response.get("chromeVersion").asText();
} else {
chromeVersion = "0";
}
statusPage = response.get("statusPage").asText();
rootElement = new AndroidRootElement(this);
cachedElement = new AndroidRootElement(this);
deviceWidth = response.get("deviceWidth").asDouble();
deviceHeight = response.get("deviceHeightWithoutNavBar").asDouble();
channelWidth = response.get("channelWidth").asDouble();
channelHeight = response.get("channelHeightWithoutNavBar").asDouble();
scale = captureScale;
}
final int screenCapturePort = response.get("screenCapturePort").asInt();
String application = null;
if (appData.length > 1) {
application = appData[1];
response = executeRequest(APP, START, application);
} else {
if (os.equals("android")) {
response = executeRequest(APP, START);
} else {
status.setError(ActionStatus.CHANNEL_START_ERROR, "unable to connect : missing app");
return;
}
}
if (response == null) {
status.setError(ActionStatus.CHANNEL_START_ERROR, "unable to connect to : " + application);
return;
}
// handle app start error
if (response.get("status").asInt() != 0) {
status.setError(ActionStatus.CHANNEL_START_ERROR, response.get("message").asText());
return;
}
final String base64 = response.get("icon").asText();
byte[] icon = new byte[0];
if (!base64.isEmpty()) {
try {
icon = Base64.getDecoder().decode(base64);
} catch (Exception ignored) {}
}
if (os.equals("ios")) {
rootElement = new IosRootElement(this, captureScale);
cachedElement = new IosRootElement(this, captureScale);
deviceWidth = response.get("deviceWidth").asDouble();
deviceHeight = response.get("deviceHeight").asDouble();
channelWidth = response.get("channelWidth").asDouble();
channelHeight = response.get("channelHeight").asDouble();
}
final String[] endPointData = endPoint.split(":");
final String version = response.get("version").asText();
String udpInfo = endPointData[0] + ":" + screenCapturePort;
channel.setDimensions(new TestBound(0D, 0D, deviceWidth, deviceHeight), new TestBound(0D, 0D, channelWidth, channelHeight), scale, captureScale);
channel.setApplicationData(Channel.MOBILE, os, systemName, version, driverVersion, icon, udpInfo, application, userName, deviceName, osBuild, country);
getDriverInfo().setUdpInfo(endPointData[0] + ":" + screenCapturePort);
refreshElementMapLocation();
}
}
@Override
public WebElement getRootElement(Channel cnl) {
refreshElementMapLocation();
return new MobileRootElement(rootElement.getValue());
}
@Override
public TestElement getTestElementRoot(ActionTestScript script) {
refreshElementMapLocation();
return new TestElement(script, new FoundElement(rootElement.getValue()), channel);
}
@Override
public void refreshElementMapLocation() {
final JsonNode src = executeRequest(CAPTURE);
source = src;
if(src != null) {
rootElement.refresh(src);
}
}
private void refreshSystemElementMapLocation() {
final JsonNode src = executeRequest(SYS_CAPTURE);
source = src;
if(src != null) {
rootElement.refresh(src);
}
}
protected void loadCapturedElement() {
long current = System.currentTimeMillis();
if(cachedElement == null || current - 2500 > cachedElementTime) {
if (cachedElement != null) {
final JsonNode src = executeRequest(CAPTURE);
if(src != null) {
cachedElement.refresh(src);
}
}
cachedElementTime = System.currentTimeMillis();
}
}
@Override
public void close() {
final String application = channel.getApplication();
if (application != null) {
executeRequest(APP, STOP, application);
}
this.channel = null;
}
public void tearDown() {
JsonNode jsonObject = executeRequest(DRIVER, STOP);
if (jsonObject != null) {
this.token = null;
}
}
@Override
public FoundElement getElementFromPoint(Boolean syscomp, Double x, Double y) {
loadCapturedElement();
ArrayList listElements = new ArrayList<>();
loadList(cachedElement.getValue(), listElements, "A");
final double mouseX = channel.getSubDimension().getX() + x;
final double mouseY = channel.getSubDimension().getY() + y;
AtsMobileElement element = cachedElement.getValue();
listElements.sort(Comparator.comparing(AtsMobileElement::getPositionInDom));
for (AtsMobileElement child : listElements) {
double coordinateX = child.getX();
double coordinateY = child.getY();
double coordinateW = child.getWidth();
double coordinateH = child.getHeight();
if (child.getRect().contains(mouseX, mouseY) &&
(
element.getRect().contains(coordinateX, coordinateY)
|| element.getRect().contains(coordinateX + coordinateW, coordinateY)
|| element.getRect().contains(coordinateX + coordinateW, coordinateY + coordinateH)
|| element.getRect().contains(coordinateX, coordinateY + coordinateH)
)
) {
element = child;
}
}
return element.getFoundElement();
}
@Override
public FoundElement getElementFromRect(Boolean syscomp, Double x, Double y, Double w, Double h) {
loadCapturedElement();
ArrayList listElements = new ArrayList<>();
loadList(cachedElement.getValue(), listElements, "A");
final double mouseX = channel.getSubDimension().getX() + x;
final double mouseY = channel.getSubDimension().getY() + y;
AtsMobileElement element = cachedElement.getValue();
listElements.sort(Comparator.comparing(AtsMobileElement::getPositionInDom));
for (AtsMobileElement child : listElements) {
final Rectangle childRect = child.getRect();
if (childRect.contains(new Rectangle(mouseX, mouseY, w, h)) && element.getRect().contains(childRect)) {
element = child;
}
}
return element.getFoundElement();
}
public String getToken() {
return token;
}
public String getEndPoint() {
return endPoint;
}
private void loadList(AtsMobileElement element, ArrayList list, String order) {
final AtsMobileElement[] children = element.getChildren();
if(children != null) {
for (int i=0; i 0 && i < 27 ? String.valueOf((char)(i + 64)) : "Z";
}
@Override
public void loadParents(FoundElement element) {
final AtsMobileElement atsElement = getCapturedElementById(element.getId(), false);
if(atsElement != null) {
FoundElement currentParent;
AtsMobileElement parent = atsElement.getParent();
if(parent != null) {
element.setParent(parent.getFoundElement());
currentParent = element.getParent();
parent = parent.getParent();
while (parent != null && !parent.isRoot()) {
currentParent.setParent(parent.getFoundElement());
currentParent = currentParent.getParent();
parent = parent.getParent();
}
}
}
}
@Override
public String getTextData(FoundElement e) {//TODO implement text data
return e.getInnerText();
}
@Override
public CalculatedProperty[] getAttributes(FoundElement element, boolean reload) {
final AtsMobileElement atsElement = getCapturedElementById(element.getId(), reload);
if(atsElement != null) {
return atsElement.getMobileAttributes();
}
return new CalculatedProperty[0];
}
@Override
public CalculatedProperty[] getHtmlAttributes(FoundElement element) {
return getAttributes(element, true);
}
private AtsMobileElement getCapturedElementById(String id, boolean reload) {
if (reload) {
return getElementById(rootElement.getValue(), id);
} else if(cachedElement != null) {
return getElementById(cachedElement.getValue(), id);
} else {
return null;
}
}
@Override
public String getAttribute(ActionStatus status, FoundElement element, String attributeName, int maxTry) {
final AtsMobileElement atsElement = getElementById(element.getId());
if(atsElement != null) {
return atsElement.getAttribute(attributeName);
}
return null;
}
@Override
public List findElements(boolean sysComp, TestElement testObject, String tagName, String[] attributes, String[] attributesValues, Predicate searchPredicate, WebElement startElement) {
List list = new ArrayList<>();
final TestElement parent = testObject.getParent();
if (sysComp) {
if (TestElement.SYSCOMP.equalsIgnoreCase(tagName)) {
list = new ArrayList<>(List.of(rootElement.getValue()));
} else {
refreshElementMapLocation();
loadElementsByTag(rootElement.getValue(), tagName, list);
}
} else if (parent == null) {
refreshElementMapLocation();
loadElementsByTag(rootElement.getValue(), tagName, list);
} else {
loadElementsByTag(getElementById(parent.getWebElementId()), tagName, list);
}
return list.parallelStream().filter(searchPredicate).map(FoundElement::new).collect(Collectors.toCollection(ArrayList::new));
}
@Override
public List findElements(TestElement parent, ImageTemplateMatchingSimple template) {
final byte[] screenshot = getSystemDriver().getMobileScreenshotByte(getScreenshotPath());
return template.findOccurrences(screenshot).parallelStream()
.map(r -> new FoundElement(channel, channel.getSubDimension(), r)).collect(Collectors.toCollection(ArrayList::new));
}
public void loadElementsByTag(AtsMobileElement root, String tag, List list)
{
if(root == null) return;
if(root.checkTag(tag)) {
list.add(root);
}
for (AtsMobileElement child : root.getChildren()) {
loadElementsByTag(child, tag, list);
}
}
//-------------------------------------------------------------------------------------------------------------
@Override
public void buttonClick(ActionStatus status, String type) {
final JsonNode result = executeRequest(SYS_BUTTON, type);
final int code = result.get("status").asInt();
final String message = result.get("message").asText();
if (code == 0) {
status.setNoError(message);
} else {
status.setError(ActionStatus.SYS_BUTTON_ERROR, message);
}
}
@Override
public void tap(int count, FoundElement element) {
rootElement.tap(element, count);
}
@Override
public void press(int duration, ArrayList paths, FoundElement element) {
rootElement.press(element, paths, duration);
}
@Override
public void mouseClick(ActionStatus status, FoundElement element, MouseDirection position, int offsetX, int offsetY) {
cachedElementTime = 0L;
rootElement.tap(status, element, position);
}
@Override
public void drag(ActionStatus status, FoundElement element, MouseDirection position, int offsetX, int offsetY, boolean offset) {
testElement = rootElement.getCurrentElement(element, position);
}
@Override
public void swipe(ActionStatus status, FoundElement element, MouseDirection position, MouseDirection direction) {
drag(status, element, position, 0, 0, false);
moveByOffset(direction.getHorizontalDirection(), direction.getVerticalDirection());
drop(element, direction, false);
}
@Override
public void moveByOffset(int hDirection, int vDirection) {
rootElement.swipe(testElement, hDirection, vDirection);
}
@Override
public void sendTextData(ActionStatus status, TestElement element, ArrayList textActionList, int waitChar, ActionTestScript topScript) {
rootElement.textInput(element, textActionList);
}
@Override
public List loadSelectOptions(TestElement element) {
return Collections.emptyList();
}
@Override
public List findSelectOptions(TestBound dimension, TestElement element) {
return Collections.emptyList();
}
@Override
public void selectOptionsItem(ActionStatus status, TestElement element, CalculatedProperty selectProperty, boolean keepSelect) {
executeRequest(ELEMENT,element.getFoundElement().getId(), SELECT, selectProperty.getName(), selectProperty.getValue().getCalculated());
}
@Override
public void clearText(ActionStatus status, TestElement te, MouseDirection md) {
mouseClick(status, te.getFoundElement(), md, 0, 0);
rootElement.clearInput(te);
}
@Override
public void updateScreenshot(TestBound dimension, boolean isRef) {
if(channel != null) {
getSystemDriver().updateMobileScreenshot(channel.getSubDimension(), isRef, getScreenshotPath());
}
}
@Override
public byte[] getScreenshot(WebElement element, TestBound bound) {
final byte[] screen = getSystemDriver().getMobileScreenshotByte(getScreenshotPath());
if(screen != null) {
ImageIO.setUseCache(false);
final int x = bound.getX().intValue();
final int y = bound.getY().intValue();
final int w = bound.getWidth().intValue();
final int h = bound.getHeight().intValue();
final InputStream in = new ByteArrayInputStream(screen);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final BufferedImage subImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
final Graphics g = subImage.getGraphics();
try {
//final BufferedImage subImage = ImageIO.read(in).getSubimage(x.intValue(), y.intValue(), width.intValue(), height.intValue());
g.drawImage(ImageIO.read(in), 0, 0, w, h, x, y, x + w, y + h, null);
g.dispose();
ImageIO.write(subImage, "png", baos);
baos.flush();
final byte[] result = baos.toByteArray();
baos.close();
return result;
} catch (IOException ignored) {}
}
return new byte[1];
}
@Override
public void createVisualAction(Channel channel, boolean stop, String actionType, int scriptLine, String scriptName, long timeline, boolean sync) {
getSystemDriver().createMobileRecord(stop, actionType, scriptLine, scriptName, timeline, channel.getName(), channel.getSubDimension(), getScreenshotPath(), sync);
}
private String getScreenshotPath() {
return getApplicationPath() + SCREENSHOT_METHOD;
}
//----------------------------------------------------------------------------------------------------------------------------------------------
@Override
public void api(ActionStatus status, ActionApi api) {}
@Override
public boolean switchWindow(ActionStatus status, int index, int tries, boolean refresh) {
return true;
}
@Override
public void closeWindow(ActionStatus status) {}
@Override
public Object executeScript(ActionStatus status, String script, Object... params) {
return null;
}
@Override
public void goToUrl(ActionStatus status, String url) {}
@Override
public void waitAfterAction(ActionStatus status) {}
@Override
public void scroll(FoundElement element) {}
@Override
public void scroll(int value) {}
@Override
public void scroll(FoundElement element, int delta) {}
@Override
public void middleClick(ActionStatus status, MouseDirection position, TestElement element) {}
@Override
public void mouseMoveToElement(FoundElement element) {
}
@Override
public void mouseMoveToElement(ActionStatus status, FoundElement foundElement, MouseDirection position, boolean desktopDragDrop, int offsetX, int offsetY) {}
@Override
public String setWindowBound(BoundData x, BoundData y, BoundData width, BoundData height) {return "";}
@Override
public void keyDown(Keys key) {}
@Override
public void keyUp(Keys key) {}
@Override
public void drop(FoundElement element, MouseDirection md, boolean desktopDriver) {}
@Override
public void doubleClick() {}
@Override
public void rightClick() {}
@Override
public DialogBox switchToAlert() {
return new MobileAlert(this);
}
public List getDialogBox(boolean isSystem) {
if (isSystem) {
refreshSystemElementMapLocation();
} else {
refreshElementMapLocation();
}
final List list = new ArrayList<>();
loadElementsByTag(rootElement.getValue(), "Alert", list);
return list;
}
@Override
public String getTitle() {
return "";
}
@Override
public boolean switchToDefaultContent(boolean dialog) {return true;}
@Override
public void setWindowToFront() {
String application = channel.getApplication();
if (application != null) {
executeRequest(APP, SWITCH, channel.getApplication());
} else {
executeRequest(APP, SWITCH);
}
}
@Override
public void switchToFrameId(String id) {}
@Override
public void updateDimensions() {}
//----------------------------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------------------------
private AtsMobileElement getElementById(String id) {
return getElementById(rootElement.getValue(), id);
}
private AtsMobileElement getElementById(AtsMobileElement root, String id) {
if(root.getId().equals(id)) {
return root;
}
for(AtsMobileElement elem : root.getChildren()) {
elem.setParent(root);
AtsMobileElement found = getElementById(elem, id);
if(found != null) {
return found;
}
}
return null;
}
public JsonNode executeRequest(String type, String ... data) {
return executeRequestToMobile(
applicationPath + "/" + type,
token,
userAgent,
client,
jsonMapper,
data);
}
public static JsonNode executeRequestToMobile(
String url,
String token,
String userAgent,
OkHttpClient client,
ObjectMapper jsonMapper,
String ... data) {
final Request.Builder requestBuilder = new Request.Builder();
requestBuilder.url(url);
requestBuilder.addHeader("Ats-Version", atsVersion);
if (token != null) {
requestBuilder.addHeader("Token", token);
}
final Request request = requestBuilder
.addHeader("User-Agent", userAgent)
.addHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF8")
.post(RequestBody.Companion.create(Stream.of(data).map(Object::toString).collect(Collectors.joining("\n")), Utils.JSON_MEDIA))
.build();
try {
final Response response = client.newCall(request).execute();
final String responseData;
JsonNode jsonNode = null;
if (response.body() != null) {
responseData = CharStreams.toString(new InputStreamReader(response.body().byteStream(), Charsets.UTF_8));
jsonNode = jsonMapper.readTree(responseData);
}
response.close();
return jsonNode;
} catch (JsonSyntaxException | IOException e) {
return null;
}
}
@Override
public String getSource() {
refreshElementMapLocation();
return source.toString();
}
@Override
public void windowState(ActionStatus status, Channel channel, String state) { }
@Override
public void setSysProperty(String propertyName, String propertyValue) {
executeRequest(SET_PROP, propertyName, propertyValue);
}
@Override
public Object executeJavaScript(ActionStatus status, String script, TestElement element) {
final JsonObject result = (JsonObject)rootElement.scripting(script, element.getFoundElement());
return handleResult(status, result);
}
@Override
public Object executeJavaScript(ActionStatus status, String script, boolean returnValue) {
final JsonObject result = (JsonObject)rootElement.scripting(script);
return handleResult(status, result);
}
private Object handleResult(ActionStatus status, JsonObject result) {
int code = result.get("status").getAsInt();
String message = result.get("message").getAsString();
if (code == 0) {
status.setNoError(message);
} else {
status.setError(ActionStatus.JAVASCRIPT_ERROR, message);
}
return result;
}
@Override
public String getSelectedText(TestElement e) {
return ""; //NOT implemented
}
@Override
protected void setPosition(Point pt) { }
@Override
protected void setSize(Dimension dim) { }
@Override
public int getNumWindows() {
return 1;
}
@Override
public String getUrl() {
return applicationPath;
}
@Override
public Rectangle getBoundRect(TestElement testElement) {
return null;
}
public double getOffsetX(Rectangle rect, double scale, MouseDirection position) {
return getCartesianOffset((int) (rect.getWidth() / scale), position.getHorizontalPos(), Cartesian.LEFT, Cartesian.CENTER, Cartesian.RIGHT);
}
public double getOffsetY(Rectangle rect, double scale, MouseDirection position) {
return getCartesianOffset((int) (rect.getHeight() / scale), position.getVerticalPos(), Cartesian.TOP, Cartesian.MIDDLE, Cartesian.BOTTOM);
}
@Override
public String getCookies() {
return "";
}
@Override
public String getHeaders(ActionStatus status) {
return "";
}
@Override
public void quit() {
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy