I am working on automating tests for an Android application using Appium and Selenide. I have a scenario where I need to perform two separate actions on two different buttons. When I use a separate androidDriver.perform() method for each action, everything works fine. However, when I try to perform both actions within a single androidDriver.perform() method by passing both sequences to the method, I encounter an InvalidElementStateException.
if (isAndroid()) {
SelenideElement buttonsKeyBoard1 = $x("//android.widget.Button[contains(@resource-id, 'Keyboard_1Button')]").should(Condition.visible);
SelenideElement buttonsKeyBoard2 = $x("//android.widget.Button[contains(@resource-id, 'Keyboard_2Button')]");
List<SelenideElement> buttonsKeyBoard = new ArrayList<>();
buttonsKeyBoard.add(buttonsKeyBoard1);
buttonsKeyBoard.add(buttonsKeyBoard2);
// Create a list to hold the sequences
List<Sequence> sequences = new ArrayList<>();
// Process the first button
PointerInput finger1 = new PointerInput(PointerInput.Kind.TOUCH, "finger1");
PointerInput finger2 = new PointerInput(PointerInput.Kind.TOUCH, "finger2");
Sequence tap1 = new Sequence(finger1, 1);
Sequence tap2 = new Sequence(finger2, 1);
Point sourceLocation = buttonsKeyBoard1.getLocation();
Point sourceLocation2 = buttonsKeyBoard2.getLocation();
int centerX = sourceLocation.getX() + buttonsKeyBoard1.getSize().getWidth() / 2;
int centerY = sourceLocation.getY() + buttonsKeyBoard1.getSize().getHeight() / 2;
System.out.println("x1 and y1 " + centerX + " " + centerY);
int centerX2 = sourceLocation2.getX() + buttonsKeyBoard2.getSize().getWidth() / 2;
int centerY2= sourceLocation2.getY() + buttonsKeyBoard2.getSize().getHeight() / 2;
System.out.println("x2 and y2 " + centerX2 + " " + centerY2);
tap1.addAction(finger1.createPointerMove(Duration.ofMillis(500), PointerInput.Origin.viewport(), centerX, centerY));
tap1.addAction(finger1.createPointerDown(LEFT.asArg()));
tap1.addAction(finger1.createPointerUp(LEFT.asArg()));
sequences.add(tap1); // Add the sequence to the list of sequences
tap2.addAction(finger2.createPointerMove(Duration.ofMillis(500), PointerInput.Origin.viewport(), centerX2, centerY2));
tap2.addAction(finger2.createPointerDown(LEFT.asArg()));
tap2.addAction(finger2.createPointerUp(LEFT.asArg()));
sequences.add(tap2); // Add the sequence to the list of sequences
androidDriver.perform(sequences);
}
The error message that I receive is as follows:
Caused by: org.openqa.selenium.InvalidElementStateException: Unable to perform W3C actions. Check the logcat output for possible error reports and make sure your input actions chain is valid.
But when I change it to the follow, and create 2 seperate sequence and 2 different perform methods. the methode works. But I think that's not the idea, I want to execute as many sequences as possible with the same perform method.
sequences.add(tap1); // Add the sequence to the list of sequences
tap2.addAction(finger2.createPointerMove(Duration.ofMillis(10), PointerInput.Origin.viewport(), centerX2, centerY2));
tap2.addAction(finger2.createPointerDown(LEFT.asArg()));
tap2.addAction(finger2.createPointerUp(LEFT.asArg()));
sequences2.add(tap2); // Add the sequence to the list of sequences
androidDriver.perform(sequences);
androidDriver.perform(sequences2);
I got the solution, I only miss the pause after pointerDown.