Open Swetha-Boddu opened 1 year ago
Then use it without action.
You cannot use actions to perform clicks directly using appium, you have to use a work around of this kind to perform actions:package com.desktop.automation.utils;
import java.io.IOException; import java.net.URI; import java.net.URLEncoder; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.stream.Collectors;
import org.openqa.selenium.Keys; import org.openqa.selenium.remote.RemoteWebElement;
import com.desktop.automation.constant.Constant.DesktopParamKeyName;
import io.appium.java_client.windows.WindowsDriver; import lombok.extern.log4j.Log4j2;
@Log4j2 public class AppiumWokaround {
private static AppiumWokaround appiumWokaround;
public static AppiumWokaround getInstance() {
if (appiumWokaround == null) {
appiumWokaround = new AppiumWokaround();
}
return appiumWokaround;
}
public static void launchApplicationDirectly(String appPath) {
// Include 'automationName' and 'platformName' in the capabilities
String jsonCapabilities = String.format(
"{\"capabilities\": {\"alwaysMatch\": {\"app\": \"%s\", \"appium:automationName\": \"Windows\", \"platformName\": \"Windows\"}}}",
URLEncoder.encode(appPath, StandardCharsets.UTF_8)
);
String newSessionUrl = DesktopParamKeyName.WIN_APP_DRIVER_URL + "/session";
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(newSessionUrl))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonCapabilities))
.build();
try {
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.info("Response status code: {}", response.statusCode());
log.info("Response body: {}", response.body());
} catch (Exception e) {
log.error("Error sending request to Appium server: " + e.getMessage(), e);
}
}
private enum ActionType {
CLICK, DOUBLE_CLICK, BUTTON_DOWN, BUTTON_UP
}
private String getUri(WindowsDriver driver, String action) {
return String.format(
"%s/session/%s/%s",
DesktopParamKeyName.WIN_APP_DRIVER_URL,
driver.getSessionId().toString(),
action
);
}
private void performActionOnElement(WindowsDriver driver, RemoteWebElement element, ActionType action) {
this.moveToElement(driver, element);
switch (action) {
case CLICK:
callRest(getUri(driver, "click"), HttpRequest.BodyPublishers.noBody());
break;
case DOUBLE_CLICK:
callRest(getUri(driver, "doubleclick"), HttpRequest.BodyPublishers.noBody());
break;
case BUTTON_DOWN:
callRest(getUri(driver, "buttondown"), HttpRequest.BodyPublishers.noBody());
break;
case BUTTON_UP:
callRest(getUri(driver, "buttonup"), HttpRequest.BodyPublishers.noBody());
break;
}
}
public void moveToElement(WindowsDriver driver, RemoteWebElement element) {
String uri = getUri(driver, "moveto");
String json = String.format("{\"element\":\"%s\"}", element.getId());
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
public void moveToElement(WindowsDriver driver, RemoteWebElement element,int x, int y) {
moveToElement(driver,element);
String uri = getUri(driver, "moveto");
String json = String.format("{\"xoffset\":%d,\"yoffset\":%d}", x, y);
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
public void contextClick(WindowsDriver driver, RemoteWebElement element) {
this.moveToElement(driver, element);
String uri = getUri(driver, "click");
String json = String.format("{\"button\":2}");
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
public void contextClick(WindowsDriver driver) {
String uri = getUri(driver, "click");
String json = String.format("{\"button\":2}");
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
public void contextClick(WindowsDriver driver, RemoteWebElement element, int x, int y) {
// Move to the specified coordinates relative to the top-left corner of the element
this.moveToElementWithOffset(driver,element, x, y);
// Perform the right-click
String uri = getUri(driver, "click");
String json = String.format("{\"button\":2}");
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
public void doubleClick(WindowsDriver driver, RemoteWebElement element) {
performActionOnElement(driver, element, ActionType.DOUBLE_CLICK);
}
public void doubleClickAtCurrentLocation(WindowsDriver driver) {
String uri = getUri(driver, "doubleclick");
callRest(uri, HttpRequest.BodyPublishers.noBody());
}
public void click(WindowsDriver driver, RemoteWebElement elementToClick) {
performActionOnElement(driver, elementToClick, ActionType.CLICK);
}
public void moveToElementAndSendKeys(WindowsDriver driver, RemoteWebElement element, String keyToSend) {
this.moveToElement(driver, element);
String uri = getUri(driver, "keys");
String json = String.format("{\"value\":[\"%s\"]}", keyToSend);
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
public void moveToElementAndClick(WindowsDriver driver, RemoteWebElement element) {
this.moveToElement(driver, element);
performActionOnElement(driver, element, ActionType.CLICK);
}
public void clickWithoutElement(WindowsDriver driver) {
String uri = getUri(driver, "click");
callRest(uri, HttpRequest.BodyPublishers.noBody());
}
public void sendKeysWithoutElement(WindowsDriver driver, String text) {
String uri = getUri(driver, "keys");
String json = String.format("{\"value\":[\"%s\"]}", text);
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
public void moveToElementWithOffsetAndClick(WindowsDriver driver, RemoteWebElement element, int xCoordinates, int yCoordinates) {
this.moveToElementWithOffset(driver,element, xCoordinates, yCoordinates);
clickWithoutElement(driver);
}
public void moveToElementWithOffset(WindowsDriver driver, RemoteWebElement element, int xCoordinates, int yCoordinates) {
this.moveToElement(driver, element);
moveByOffset(driver, xCoordinates, yCoordinates);
}
public void clickAndHoldAndMoveToElement(WindowsDriver driver, RemoteWebElement sourceElement, RemoteWebElement destinationElement) {
performActionOnElement(driver, sourceElement, ActionType.BUTTON_DOWN);
this.moveToElement(driver, destinationElement);
}
public void dragAndDrop(WindowsDriver driver, RemoteWebElement dragElement, RemoteWebElement dropElement) {
clickAndHoldAndMoveToElement(driver, dragElement, dropElement);
performActionOnElement(driver, dropElement, ActionType.BUTTON_UP);
}
public void dragAndDropBy(WindowsDriver driver, RemoteWebElement element, int xcords, int ycords) {
performActionOnElement(driver, element, ActionType.BUTTON_DOWN);
moveByOffset(driver, xcords, ycords);
performActionOnElement(driver, element, ActionType.BUTTON_UP);
}
public void moveByOffset(WindowsDriver driver, int xCoordinates, int yCoordinates) {
String uri = getUri(driver, "moveto");
String json = String.format("{\"xoffset\":%d,\"yoffset\":%d}", xCoordinates, yCoordinates);
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
public void moveByOffsetAndClick(WindowsDriver driver, int xCoordinates, int yCoordinates) {
moveByOffset(driver, xCoordinates, yCoordinates);
clickWithoutElement(driver);
}
public void release(WindowsDriver driver, RemoteWebElement element) {
performActionOnElement(driver, element, ActionType.BUTTON_UP);
}
public void clickAndHold(WindowsDriver driver, RemoteWebElement element) {
performActionOnElement(driver, element, ActionType.BUTTON_DOWN);
}
private static void callRest(String uri, HttpRequest.BodyPublisher body) {
log.info("URI: {}", uri);
//log.info("body: {}", body.toString());
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(uri))
.header("Content-Type", "application/json")
.POST(body)
.build();
try {
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.info("RETURN status code: {}", response.statusCode());
//log.info("RETURN: {}", response.body());
} catch (IOException e) {
log.error("IO Exception during HTTP call", e);
throw new RuntimeException(e);
} catch (InterruptedException e) {
log.error("Interrupted Exception during HTTP call", e);
Thread.currentThread().interrupt(); // Preserve the interrupt status
throw new RuntimeException(e);
}
}
public void sendKeysWithoutElement(WindowsDriver driver, Keys keyToSend) {
sendKeysWithoutElement(driver, keyToSend.toString());
}
public void pressKeysSimultaneously(WindowsDriver driver, String[] keys) {
// Convert the String array to a JSON array representation
String jsonKeysArray = Arrays.stream(keys)
.map(key -> "\"" + key + "\"")
.collect(Collectors.joining(",", "[", "]"));
String uri = getUri(driver, "keys");
String json = String.format("{\"value\":%s}", jsonKeysArray);
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
public void holdKey(WindowsDriver driver, String key) {
// This will simulate a key down action
String uri = getUri(driver, "keydown");
String json = String.format("{\"value\":[\"%s\"]}", key);
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
public void releaseKey(WindowsDriver driver, String key) {
// This will simulate a key up action
String uri = getUri(driver, "keyup");
String json = String.format("{\"value\":[\"%s\"]}", key);
callRest(uri, HttpRequest.BodyPublishers.ofString(json));
}
}
Hi,
I am executing below command from ADO pipeline to run cases in VM in locked(local PC) mode.
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "$sessionid=((quser $env:USERNAME | select -Skip 1) -split '\s+')[2]; tscon $sessionid /dest:console" 2> UnlockErrors.log
VM gets disconnected and 70%cases are passing. Whereas 30 % cases are failing because when we select source element and paste into flowsheet , it is navigating properly to the selected co-ordinates but the click is not happening, hence it is failing.
Can you please verify below code lines and suggest if any solution.
//(I wanted to paste source element on flowsheet at particular x y co-ordinates (659, 241))
//(Whereas without action class the click is working fine on same flowsheet as shown below.) Appsession.FindElementByXPath("//Pane[@ClassName=\"AfxFrameOrView140\"]").Click(); But i wanted to click at given x, y co-ordinates.
Note: The above code is absolutely working fine in interactive mode.
Thanks, Swetha