All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ats.executor.drivers.engines.MobileDriverEngine Maven / Gradle / Ivy

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