com.ats.executor.drivers.engines.SapDriverEngine 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!
package com.ats.executor.drivers.engines;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebElement;
import com.ats.data.Dimension;
import com.ats.data.Point;
import com.ats.data.Rectangle;
import com.ats.driver.ApplicationProperties;
import com.ats.element.AtsBaseElement;
import com.ats.element.AtsSapElement;
import com.ats.element.FoundElement;
import com.ats.element.RemoteRootElement;
import com.ats.element.SapDialogBox;
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.drivers.IDriverInfo;
import com.ats.executor.drivers.desktop.DesktopWindow;
import com.ats.executor.drivers.desktop.SystemDriver;
import com.ats.generator.ATS;
import com.ats.generator.objects.MouseDirection;
import com.ats.generator.variables.CalculatedProperty;
import com.ats.generator.variables.CalculatedValue;
import com.ats.script.actions.ActionApi;
import com.ats.script.actions.ActionSelect;
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.collect.ImmutableMap;
import com.google.common.io.CharStreams;
import com.google.gson.JsonSyntaxException;
import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class SapDriverEngine extends DriverEngine implements IDriverEngine {
public static final String START_TIMEOUT_OPTION = "--start-timeout";
private static final Pattern SAP_URL_PATTERN = Pattern.compile("(.*):(.*)@(.*)", Pattern.CASE_INSENSITIVE);
private final byte[] SAP_ICON = Base64.getDecoder().decode("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");
private final static String SESSION = "session";
private final static String SHUTDOWN = "shutdown";
private final static String START = "start";
private final static String STOP = "stop";
private final static String SCROLL = "scroll";
private final static String ELEMENTS = "elements";
private final static String ELEMENT = "element";
private final static String PRESS = "press";
private final static String DBL_CLICK = "dbclick";
private final static String DIALOG_BOX = "dialogBox";
private final static String TEXT = "text";
private final static String TREE = "tree";
private final static String OPTIONS = "options";
private final static String SELECT = "select";
private final static String PARENTS = "parents";
private final static String WINDOW = "window";
private final static String SWITCH = "switch";
private final static String CLOSE = "close";
private final static String SCRIPT = "script";
private final static String GOTO_URL = "gotoUrl";
private final static String FOCUS = "focus";
public final static String SAP_NETWORKOPTION = "NetworkOption";
public final static String SAP_ENDPOINT = "Endpoint";
public final static String SAP_MAJOR_VERSION = "MajorVersion";
public final static String SAP_NETWORKOPTION_FAST = "fast";
public final static String SAP_NETWORKOPTION_SLOW = "slow";
public final static String SAP_CONNECTION_ID = "connectionId";
private String sapUser;
private String sapPassword;
private String sapClient = "001";
private String sapLang = "EN";
private String applicationName;
private OkHttpClient httpClient;
private String userAgent;
private String sapDriverUrl;
private String connectionId;
private List elementMapLocation;
private FoundElement currentElement;
private final ObjectMapper jsonMapper = new ObjectMapper();
final private RemoteRootElement root = new RemoteRootElement();
private String networkOption = "";
private static final int ACTION_WAIT = 150; //maybe one day it will be needed to add this value in atsProperties file
public SapDriverEngine(
Channel channel,
ActionStatus status,
String application,
IDriverInfo driverInfo,
SystemDriver systemDriver,
ApplicationProperties props,
boolean enableLearning) {
super(channel, driverInfo, systemDriver, props, ACTION_WAIT, 0, enableLearning);
final String channelName = channel.getName();
if(props.getUri() != null) {
application = props.getUri();
}else {
application = application.replaceFirst("^sap:\\/\\/", "");
}
if(channelName.isBlank()) {
status.setError(ActionStatus.CHANNEL_START_ERROR, "channel name cannot be empty");
return;
}
sapDriverUrl = getDriverInfo().getDriverServerUri().resolve("/").toString();
String auth = channel.getAuthenticationValue();
if(props.getAuthentication() != null) {
auth = props.getAuthentication();
}
if(auth != null && !auth.isBlank()){
final String authenticationDecoded = new String(Base64.getDecoder().decode(auth), StandardCharsets.UTF_8);
final String[] authenticationData = authenticationDecoded.split(":");
if(authenticationData.length > 1) {
sapUser = authenticationData[0];
final CalculatedValue passValue = new CalculatedValue(channel.getTestScript(), authenticationData[1]);
passValue.uncrypt(channel.getTestScript());
sapPassword = passValue.getCalculated();
String[] appUrl = application.split(":");
if(appUrl.length > 1) {
application = appUrl[0];
sapClient = appUrl[1];
if(appUrl.length > 2) {
sapLang = appUrl[2];
}
}else {
appUrl = application.split("/");
if(appUrl.length > 1) {
application = appUrl[0];
sapClient = appUrl[1];
if(appUrl.length > 2) {
sapLang = appUrl[2];
}
}else {
status.setError(ActionStatus.CHANNEL_START_ERROR, "missing client ID");
return;
}
}
}else {
status.setError(ActionStatus.CHANNEL_START_ERROR, "no user and password defined");
return;
}
}else {
final Matcher mv = SAP_URL_PATTERN.matcher(application);
if (mv.find()) {
sapUser = mv.group(1);
checkPassword(new CalculatedValue(channel.getTestScript(), mv.group(2)), 0);
application = mv.group(3);
}else {
channel.getArguments().forEach(c -> checkArgs(c));
}
}
applicationName = application;
applicationPath = applicationName;
this.httpClient = new Builder().cache(null).connectTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).readTimeout(80, TimeUnit.SECONDS).build();
this.userAgent = "AtsSapDriver/" + ATS.getAtsVersion() + "," + System.getProperty("user.name") + ",";
// -------------------------------------------------------------------------------------------------
// try to connect to sap driver
// -------------------------------------------------------------------------------------------------
ImmutableMap connexionMap;
if(sapUser != null && sapPassword != null) {
connexionMap = ImmutableMap.of("connection", applicationName, "user", sapUser, "password", sapPassword, "client", sapClient, "lang", sapLang, "channel", channelName);
}else {
connexionMap = ImmutableMap.of("connection", applicationName, "channel", channelName);
}
int maxTry = 0;
JsonNode response = executeRequest(connexionMap, SESSION, START);
while(response == null && maxTry < 30) {
maxTry++;
channel.sleep(500);
response = executeRequest(connexionMap, SESSION, START);
}
String sapGuiVersion = "";
String warning = "";
if (response == null) {
status.setError(ActionStatus.CHANNEL_START_ERROR, "unable to connect to sap driver");
return;
}else {
final JsonNode error = response.findValue("error");
if(error != null) {
status.setError(ActionStatus.CHANNEL_START_ERROR, error.findValue("Message").asText());
return;
}
final JsonNode network = response.findValue(SAP_NETWORKOPTION);
if (network != null) {
setNetworkOption(network.asText().toLowerCase());
if(SAP_NETWORKOPTION_SLOW.equals(getNetworkOption())) {
warning = "Slow network connection detected !";
}
}
final JsonNode version = response.findValue(SAP_MAJOR_VERSION);
if (version != null) {
sapGuiVersion = version.asText();
}
}
// -------------------------------------------------------------------------------------------------
// try to connect to get main sap window
// -------------------------------------------------------------------------------------------------
final JsonNode window = response.findValue("window");
if(window != null) {
connectionId = response.findValue("ConnexionId").asText();
getSystemDriver().setEngine(new SystemDriverEngine(channel, enableLearning));
final int pId = window.get("ProcessId").asInt(0);
channel.setApplicationData(
Channel.SAP,
getSystemDriver().getOsName() + " (" + getSystemDriver().getOsVersion() +")",
"SAP Gui",
sapGuiVersion,
getSystemDriver().getDriverVersion(),
pId,
window.get("Handle").asInt(0),
SAP_ICON,
warning,
sapDriverUrl);
channel.getDimension().update(
window.get("ScreenX").asDouble(0.0),
window.get("ScreenY").asDouble(0.0),
window.get("Width").asDouble(0.0),
window.get("Height").asDouble(0.0));
final List windows = getSystemDriver().getWindowsByPid(pId);
for(DesktopWindow win : windows) {
final String s = win.getAttribute("Title");
if(s != null && s.toLowerCase().contains("sap logon")) {
getSystemDriver().ostracon(status, win.getHandle());
// break;
}
if(s != null && s.toLowerCase().contains("sap easy access")) {
getSystemDriver().getEngine().window = win;
}
}
}else {
status.setError(ActionStatus.CHANNEL_START_ERROR, "unable to find main SAP window");
}
}
private void checkArgs(CalculatedValue cv) {
final String v = cv.getCalculated();
if(v.startsWith("user=")) {
sapUser = v.substring(5);
}else if(v.startsWith("pass=")) {
checkPassword(cv, 5);
}else if(v.startsWith("password=")) {
checkPassword(cv, 9);
}else if(v.startsWith("client=")) {
sapClient = v.substring(7);
}
}
private void checkPassword(CalculatedValue cv, int start) {
cv.setCalculated(cv.getCalculated().substring(start));
cv.uncrypt(channel.getTestScript());
sapPassword = cv.getCalculated();
}
//----------------------------------------------------------------------------------------------
// Request to driver
//----------------------------------------------------------------------------------------------
private JsonNode executeRequest(ImmutableMap map, String ... reqUrl) {
final String url = sapDriverUrl + Stream.of(reqUrl).map(Object::toString).collect(Collectors.joining("/"));
final Request.Builder requestBuilder = new Request.Builder();
requestBuilder.url(url);
final Request request = requestBuilder
.addHeader("User-Agent", userAgent)
.addHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF8")
.post(RequestBody.Companion.create(jsonMapper.valueToTree(map).toString(), Utils.JSON_MEDIA))
.build();
try {
final Response response = httpClient.newCall(request).execute();
final String responseData = CharStreams.toString(new InputStreamReader(response.body().byteStream(), Charsets.UTF_8));
response.close();
return jsonMapper.readTree(responseData);
} catch (JsonSyntaxException | IOException e) {
return null;
}
}
//----------------------------------------------------------------------------------------------
// functions
//----------------------------------------------------------------------------------------------
private void loadElementsByTag(String parentId, String tagName, List list, int line, String controlType) {
Map m;
m = new HashMap<>(ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "tag", tagName, "line", String.valueOf(line), "controlType", controlType));
if(parentId != null) {
m.put("parent", parentId);
}
final JsonNode response = executeRequest(ImmutableMap.copyOf(m), ELEMENTS);
if (response != null) {
JsonNode elements = response.findValue("elements");
if(elements != null) {
for (final JsonNode element : elements) {
list.add(new AtsSapElement(jsonMapper, element));
}
}
}
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
@Override
public WebElement getRootElement(Channel cnl) {
return root;
}
@Override
public void close() {
if(connectionId != null) {
executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId), SESSION, STOP);
}
}
@Override
public void quit() {
executeRequest(ImmutableMap.of(), SHUTDOWN);
}
@Override
public boolean switchWindow(ActionStatus status, int index, int tries, boolean refresh) {
JsonNode resp = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "index", index), WINDOW, SWITCH);
int maxTry = 1 + tries;
while(resp.findValue("error") != null && maxTry > 0) {
channel.sleep(1000);
resp = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "index", index), WINDOW, SWITCH);
maxTry--;
}
if (resp != null) {
JsonNode window = resp.findValue("window");
if(window != null) {
channel.getDimension().update(
window.get("ScreenX").asDouble(0.0),
window.get("ScreenY").asDouble(0.0),
window.get("Width").asDouble(0.0),
window.get("Height").asDouble(0.0));
channel.setWinHandle(window.get("Handle").asInt());
channel.toFront();
status.setPassed(true);
}else {
JsonNode error = resp.findValue("error");
if(error != null) {
status.setError(ActionStatus.WINDOW_NOT_FOUND, error.get("Message").asText());
}
}
}
return false;
}
@Override
public void closeWindow(ActionStatus status) {
final JsonNode response = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId), WINDOW, CLOSE);
if (response != null) {
JsonNode window = response.findValue("window");
if(window != null) {
channel.getDimension().update(
window.get("ScreenX").asDouble(0.0),
window.get("ScreenY").asDouble(0.0),
window.get("Width").asDouble(0.0),
window.get("Height").asDouble(0.0));
channel.setWinHandle(window.get("Handle").asInt());
channel.toFront();
}else {
JsonNode error = response.findValue("error");
if(error != null) {
status.setError(ActionStatus.WINDOW_NOT_FOUND, error.get("Message").asText());
}
}
}
}
@Override
public Object executeScript(ActionStatus status, String script, Object... params) {
return null;
}
@Override
public Object executeJavaScript(ActionStatus status, String script, TestElement element) {
return executeScript(status, element.getWebElementId(), script);
}
@Override
public Object executeJavaScript(ActionStatus status, String script, boolean returnValue) {
try {
if(returnValue) {
final Object result = executeScript(status, "", script);
status.setMessage(result.toString());
return result;
}else {
executeScript(status, "", script);
}
status.setPassed(true);
}catch(StaleElementReferenceException e0) {
throw e0;
}catch(Exception e1) {
status.setException(ActionStatus.JAVASCRIPT_ERROR, e1);
}
return null;
}
private String executeScript(ActionStatus status, String elementId, String script) {
final JsonNode response = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "id", elementId, "script", script), ELEMENT, SCRIPT);
if (response != null) {
final JsonNode jsonError = response.findValue("error");
if(jsonError != null) {
status.setError(jsonError.get("Code").asInt(0), jsonError.get("Message").asText());
return "";
}else {
JsonNode result = response.findValue("result");
if(result != null && !result.isNull()) {
return result.asText();
}
}
}
return "";
}
@Override
public void goToUrl(ActionStatus status, String url) {
final JsonNode response = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "url", url), GOTO_URL);
if (response != null) {
final JsonNode jsonError = response.findValue("error");
if(jsonError != null) {
status.setError(jsonError.get("Code").asInt(0), jsonError.get("Message").asText());
}
}
}
@Override
public List findElements(boolean sysComp, TestElement testObject, String tagName, String[] attributes, String[] attributesValues, Predicate searchPredicate, WebElement startElement) {
final List list = new ArrayList<>();
final TestElement parent = testObject.getParent();
int line = 0;
String parentId = null;
if (parent != null) {
parentId = parent.getWebElementId();
}
if (attributes.length == 0 && testObject.getIndex() != 0) {
//In the case of a line research without arguments
line = testObject.getIndex();
}
String controlType = (sysComp) ? "WIN" : "SAP";
loadElementsByTag(parentId, tagName, list, line, controlType);
return list.parallelStream().filter(searchPredicate).map(FoundElement::new).collect(Collectors.toCollection(ArrayList::new));
}
@Override
public Rectangle getBoundRect(TestElement testElement) {
return null;
}
@Override
public void waitAfterAction(ActionStatus status) {
actionWait();
}
@Override
public void updateDimensions() {
final JsonNode response = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId), WINDOW);
if (response != null) {
JsonNode window = response.findValue("window");
if(window != null && !window.isNull()) {
channel.getDimension().update(
window.get("ScreenX").asDouble(0.0),
window.get("ScreenY").asDouble(0.0),
window.get("Width").asDouble(0.0),
window.get("Height").asDouble(0.0));
}
}
}
@Override
public FoundElement getElementFromPoint(Boolean syscomp, Double x, Double y) {
final double xPos = x;
final double yPos = y;
if (elementMapLocation != null && elementMapLocation.size() > 0) {
final Optional fe = elementMapLocation.stream().filter(e -> e.isActive() && e.getRectangle().contains(xPos, yPos)).findFirst();
if(fe.isPresent()) {
return fe.get();
}
}
return null;
}
@Override
public FoundElement getElementFromRect(Boolean syscomp, Double x, Double y, Double w, Double h) {
return null;
}
@Override
public String getAttribute(ActionStatus status, FoundElement element, String attributeName, int maxTry) {
final CalculatedProperty[] properties = getAttributes(element, true);
for (CalculatedProperty prop : properties) {
if(prop.getName().equals(attributeName)) {
return prop.getValue().getCalculated();
}
}
return null;
}
@Override
public CalculatedProperty[] getAttributes(FoundElement element, boolean reload) {
JsonNode response;
response = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "id", element.getId()), ELEMENT);
if (response != null) {
JsonNode jsonElement = response.findValue("element");
if(jsonElement != null) {
final AtsSapElement elem = new AtsSapElement(jsonMapper, jsonElement);
return elem.getAttributes();
}
}
return new CalculatedProperty[0];
}
@Override
public CalculatedProperty[] getHtmlAttributes(FoundElement element) {
return getAttributes(element, true);
}
@Override
public List loadSelectOptions(TestElement element) {
final ArrayList result = new ArrayList<>();
JsonNode response = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "id", element.getWebElementId()), ELEMENT, OPTIONS);
if (response != null) {
final JsonNode jsonOptions = response.findValue("options");
jsonOptions.fields().forEachRemaining(f -> result.add(new String[] {f.getKey(), f.getValue().asText()}));
}
return result;
}
@Override
public List findSelectOptions(TestBound dimension, TestElement element) {
return null;
}
@Override
public void selectOptionsItem(ActionStatus status, TestElement testElement, CalculatedProperty selectProperty, boolean keepSelect) {
final String searchedValue = selectProperty.getValue().getCalculated();
final List items = loadSelectOptions(testElement);
String key;
if(ActionSelect.SELECT_INDEX.equals(selectProperty.getName())){
final int index = Utils.string2Int(searchedValue);
if(items.size() > index) {
key = items.get(index)[0];
}else {
status.setError(ActionStatus.OBJECT_NOT_INTERACTABLE, "index not found, max length options : " + items.size());
return;
}
}else {
Optional foundOption;
int idx = 1;
if(ActionSelect.SELECT_VALUE.equals(selectProperty.getName())){
idx = 0;
}
final int dataIndex = idx;
if(selectProperty.isRegexp()) {
foundOption = items.stream().filter(e -> e[dataIndex].matches(searchedValue)).findFirst();
}else {
foundOption = items.stream().filter(e -> e[dataIndex].equals(searchedValue)).findFirst();
}
if(foundOption.isPresent()) {
key = foundOption.get()[0];
}else {
status.setError(ActionStatus.OBJECT_NOT_INTERACTABLE, "option not found : " + searchedValue);
return;
}
}
checkResultError(
executeRequest(
ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "id", testElement.getWebElementId(), "key", key), ELEMENT, SELECT),
status);
}
@Override
public void loadParents(FoundElement hoverElement) {
JsonNode response = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "id", hoverElement.getId()), ELEMENT, PARENTS);
if (response != null) {
final double channelX = channel.getDimension().getX();
final double channelY = channel.getDimension().getY();
final JsonNode jsonParent = response.findValue("parent");
if(jsonParent != null && !jsonParent.isNull()) {
hoverElement.setParent(new FoundElement(channelX, channelY, jsonParent, jsonParent.get("Parent")));
}
}
}
private void checkResultError(JsonNode node, ActionStatus status) {
if (node != null) {
final JsonNode jsonError = node.findValue("error");
if(jsonError != null) {
status.setError(jsonError.get("Code").asInt(0), jsonError.get("Message").asText());
}
}
}
@Override
public void sendTextData(ActionStatus status, TestElement element, ArrayList textActionList, int waitChar, ActionTestScript topScript) {
boolean precIsSpecialKey = false;
for(SendKeyData kd : textActionList) {
if (kd.getData().length() > 0 || kd.getSpecialKey() != null) {
String keySequence = kd.getSequenceMobile();
String elementStr = (precIsSpecialKey ? "root" : element.getWebElementId());
if (kd.getData() != null && kd.getData() != "" && kd.getDownKey() != null) {
keySequence = "$KEY-" + kd.getDownKey().name() + "-" + kd.getData();
}
if (kd.getSpecialKeyString() == null || !keySequence.startsWith("$KEY-")) {
checkResultError(
executeRequest(
ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "element", elementStr, "text", keySequence),
TEXT),
status);
if (status.getCode() == ActionStatus.OBJECT_NOT_INTERACTABLE) { // Not interactable
throw new ElementNotInteractableException(status.getMessage());
}
} else {
if (elementStr != "root") {
checkResultError(
executeRequest(
ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "element", elementStr, "text", keySequence),
FOCUS),
status);
}
}
if (kd.getSpecialKey() != null && kd.getDownKey() == null && getSystemDriver() != null && getSystemDriver().getEngine() != null) {
ArrayList specialKeyArray = new ArrayList<>();
specialKeyArray.add(kd);
getSystemDriver().getEngine().sendTextData(status, element, specialKeyArray, waitChar, topScript);
precIsSpecialKey = true;
waitAfterAction(status);
} else {
precIsSpecialKey = false;
}
}
}
}
@Override
public void mouseClick(ActionStatus status, FoundElement element, MouseDirection position, int offsetX, int offsetY) {
String tag =element.getTag();
if (tag.equalsIgnoreCase("toolbarmenu") || tag.equalsIgnoreCase("menu")) {
//click to extend the menu
int x = (int)Math.round(element.getScreenX() + (element.getWidth()/2));
int y = (int)Math.round(element.getScreenY() + (element.getHeight()/2));
getSystemDriver().mouseMove(x,y);
getSystemDriver().mouseClick();
} else {
checkResultError(
executeRequest(
ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "id", element.getId()),
ELEMENT, PRESS),
status);
if (status.getCode() == ActionStatus.OBJECT_NOT_INTERACTABLE) { // Not interractable
throw new ElementNotInteractableException(status.getMessage());
}
}
}
@Override
public void mouseMoveToElement(ActionStatus status, FoundElement foundElement, MouseDirection position, boolean desktopDragDrop, int offsetX, int offsetY) {
currentElement = foundElement;
}
@Override
public void mouseMoveToElement(FoundElement foundElement) {
currentElement = foundElement;
ActionStatus status = new ActionStatus(this.channel, "", 0);
checkResultError(
executeRequest(
ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "id", foundElement.getId()),
ELEMENT, FOCUS),
status);
if(status.getCode() == ActionStatus.OBJECT_NOT_INTERACTABLE) { // Not interractable
throw new ElementNotInteractableException(status.getMessage());
}
}
@Override
public void doubleClick() {
if(currentElement != null) {
ActionStatus status = new ActionStatus(this.channel, "", 0);
checkResultError(
executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "id", currentElement.getId()), ELEMENT, DBL_CLICK),
status
);
if(status.getCode() == ActionStatus.OBJECT_NOT_INTERACTABLE) { // Not interractable
throw new ElementNotInteractableException(status.getMessage());
}
}
}
@Override
public void setWindowToFront() {
channel.toFront();
}
@Override
public void refreshElementMapLocation() {
new Thread(new LoadMapElement(channel, connectionId, this)).start();
}
private static class LoadMapElement implements Runnable {
final TestBound channelDimension;
final String connectionId;
final SapDriverEngine driver;
public LoadMapElement(Channel channel, String connectionId,SapDriverEngine driver) {
this.channelDimension = channel.getDimension();
this.connectionId = connectionId;
this.driver = driver;
}
@Override
public void run() {
final JsonNode response = driver.executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId), ELEMENTS, TREE);
if (response != null) {
final JsonNode elements = response.findValue("elements");
if(elements != null) {
final ArrayList list = new ArrayList<>();
final double channelX = channelDimension.getX();
final double channelY = channelDimension.getY();
elements.elements().forEachRemaining(node -> list.add(new FoundElement(channelX, channelY, node)));
driver.setElementMapLocation(list);
}
}
}
}
public void setElementMapLocation(ArrayList value) {
elementMapLocation = value;
}
@Override
public String getTextData(FoundElement e) {//TODO implement text data
return getAttribute(null, e, "Text", 5);
}
@Override
public String getSelectedText(TestElement e) {
return ""; //NOT implemented
}
//--------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------
@Override
public void setSysProperty(String propertyName, String propertyValue) {}
@Override
public void scroll(int delta) {}
@Override
public void scroll(FoundElement element) {}
@Override
public void scroll(FoundElement element, int delta) {
if (currentElement != null) {
ActionStatus status = new ActionStatus(this.channel, "", 0);
checkResultError(
executeRequest(
ImmutableMap.of(
SAP_CONNECTION_ID,
connectionId,
"id",
currentElement.getId(),
"value",
delta),
SCROLL),
status);
}
}
@Override
public void clearText(ActionStatus status, TestElement testElement, MouseDirection md) {}
@Override
public void rightClick() {
int x = (int) (currentElement.getScreenX() + (Math.round(currentElement.getWidth()) / 2 ));
int y = (int) (currentElement.getScreenY() + (Math.round(currentElement.getHeight()) / 2 ));
getSystemDriver().mouseMove(x, y);
getSystemDriver().mouseRightClick();
}
@Override
public void middleClick(ActionStatus status, MouseDirection position, TestElement element) {}
@Override
public void buttonClick(ActionStatus status, String id) {}
@Override
public void tap(int count, FoundElement element) {}
@Override
public void press(int duration, ArrayList paths, FoundElement element) {}
@Override
public void drag(ActionStatus status, FoundElement element, MouseDirection position, int offsetX, int offsetY, boolean offset) {}
@Override
public void drop(FoundElement element, MouseDirection md, boolean desktopDragDrop) {}
@Override
public void swipe(ActionStatus status, FoundElement element, MouseDirection position, MouseDirection direction) {}
@Override
public void keyDown(Keys key) {}
@Override
public void keyUp(Keys key) {}
@Override
public void moveByOffset(int hDirection, int vDirection) {}
@Override
public SapDialogBox switchToAlert() {
final JsonNode response = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId), ELEMENT, DIALOG_BOX);
try {
final String id = response.findValue("Id").asText();
final String title = ""; //response.findValue("Title").asText();
final String text = response.findValue("Text").asText();
final String type = response.findValue("Tag").asText();
return new SapDialogBox(this, id, title, text, type);
}catch(Exception e) {
throw new NoAlertPresentException();
}
}
public void dialogBoxExecute(ActionStatus status, String id, String action) {
JsonNode result = executeRequest(ImmutableMap.of(SAP_CONNECTION_ID, connectionId, "id", id, "execute", action), ELEMENT, DIALOG_BOX);
final String response = result.findValue("result").asText();
if ("ko".equalsIgnoreCase(response))
{
status.setMessage("Error: " + result.findValue("error").asText());
status.setPassed(false);
}
}
@Override
public boolean switchToDefaultContent(boolean dialog) {
return false;
}
@Override
public void switchToFrameId(String id) {
}
@Override
public String getSource() {
return null;
}
@Override
public void api(ActionStatus status, ActionApi api) {
}
@Override
public void windowState(ActionStatus status, Channel channel, String state) {
}
@Override
public String getTitle() {
return null;
}
@Override
public int getNumWindows() {
return 0;
}
@Override
public String getUrl() {
return null;
}
@Override
protected void setPosition(Point pt) {
}
@Override
protected void setSize(Dimension dim) {
}
@Override
public String getCookies() {
return "";
}
@Override
public String getHeaders(ActionStatus status) {
return "";
}
public String getNetworkOption() {
return networkOption;
}
public void setNetworkOption(String value) {
this.networkOption = value;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy