I am trying to automate a test on a mobile app, and I having trouble simulating a clicking action on an element. I use Appium Studio to record the action, then copy the codes to Eclipse for modification. In Appium Studio, the syntax for the element in question is given as:
driver_App.findElement(By.xpath("//*[#id='home_icon' and (./preceding-sibling::* | ./following-sibling::*)[#text='Razer Gold Mini App']]")).click();
However, when I copy this line over to my automation script in Eclipse, the clicking action is not simulated and the whole automation stops operating without any error message until it hit
org.apache.http.NoHttpResponseException: localhost:4723 failed to respond
Probably due to inactivity.
Following is my automation script:
static void RazerPayPage() throws InterruptedException{
Thread.sleep(3000);
driver_App.findElement(By.xpath("//*[#text='Region']")).click();
driver_App.findElement(By.xpath("//*[#text='Malaysia']")).click();
driver_App.findElement(By.xpath("//*[#text='Mobile number']")).sendKeys("123456");
driver_App.findElement(By.xpath("//*[#text='NEXT']")).click();
Thread.sleep(5000);
driver_App.findElement(By.xpath("//*[#text='Log in password']")).sendKeys("password");
driver_App.findElement(By.xpath("//*[#text='LOG IN']")).click();
Thread.sleep(8000);
new WebDriverWait(driver_App, 10).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[#text='OK']")));
driver_App.findElement(By.xpath("//*[#text='OK']")).click();
driver_App.findElement(By.xpath("//*[#id='home_icon' and (./preceding-sibling::* | ./following-sibling::*)[#text='Razer Gold Mini App']]")).click();
Hope to have advice on what mistake I have commit. Feel free to let me know if further details are required.
Try to send click event in this way after implicit wait :
driver_App.execute_script("arguments[0].click()", item)
Related
Occasionally, the instrumentation tests (Espresso) are failing on Google's Firebase Test Lab due to a keyboard on-boarding popup (screenshot) that blocks the screen and prevents tap/type events.
This only happens on the Samsung Galaxy S9+
Here is the exception:
android.support.test.espresso.PerformException: Error performing 'type text(666666)' on view '(is descendant of a: (with id: XXX) and an instance of android.widget.EditText)'.
Caused by: android.support.test.espresso.InjectEventSecurityException: java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission
at android.support.test.espresso.base.InputManagerEventInjectionStrategy.injectKeyEvent(InputManagerEventInjectionStrategy.java:113)
Any suggestions?
Maybe you can try to play around with "ime" command from ADB to enable another keyboard (you can log for example the return of ime list in order to get the IDs) before running your tests (e.g. #Before):
getInstrumentation().getUiAutomation().executeShellCommand("ime enable ID");
Thread.sleep(1000);
getInstrumentation().getUiAutomation().executeShellCommand("ime set ID");
Else you can workaround with uiautomator and implement a check before using the keyboard with this kind of piece of code :
...
onView(withId(R.id.inputField)).perform(click());
if (Build.VERSION.SDK_INT >= 23) {
UiDevice device = UiDevice.getInstance(getInstrumentation());
UiObject skipButton = device.findObject(new UiSelector().text("SKIP"));
if (skipButton.exists()) {
try {
skipButton.click();
Timber.e(e, "Dismissed popup on Keyboard");
} catch (UiObjectNotFoundException e) {
Timber.e(e, "There is no popup displayed on Keyboard");
}
}
}
onView(withId(R.id.inputField)).perform(typeText("some"), pressImeActionButton());
...
Hope this help !
I also faced this problem. It's on Firebase Test Lab side, and you shouldn't try to find a workaround. Sometimes there are problems with devices you are not responsible for. Instead you should report about it to Firebase team directly if you want it to be fixed as soon as possible.
The fastest way to do it is to go to #test-lab channel of the Firebase Slack community and report them about an issue like that. They will ask you to provide your matrix ID where you experienced something wrong.
As for layout popup, it was fixed the next day it was reported, so you shouldn't see it now.
Hi i have written testCases using espresso for the Android app.
Below is my code. my requirement is i need to manally Login to my app by entering credentials before i test the title bar Text.
So i am going into sleep for 2 min. when i enter credentials and click Login button below error is coming.
"D/InputEventConsistencyVerifier: TouchEvent: Touch event stream contains events from multiple sources: previous device id 0, previous source 2, new device id 0, new source 1002 "
Please let me know how to achieve this....
#Test
public void checkTitleBarText() throws InterruptedException {
sleep(120000);
onView(withId(R.id.drawer_layout)).perform(actionOpenDrawer());
Assert.assertEquals("SomeText", (String) textView.getText());
}
Why can't you just login with espresso? I'd be much easier...
However, If it's really your requirement, You can always launch tests with debuger attached and put a breakpoint in test code (which is stopping test thread). Login manually then and resume execution.
I would appreciate some help with some test automation on Android devices. We use Appium and RemoteWebDriver code to access the Android emulator, open up our application, tap and move around the application UI, and this all seems to work well.
However, as part of my testing, I would like to use Appium to initiate a telephone call on the device, keep the call open for a minute or so, and then hang up. Is there away to do this through the RemoteWebDriver object?
If not, what is the recommended way to make calls on the emulator? I have seen some discussion of using direct telnet calls to the emulator, but hope there is a better way!
You may set these desired capabilities :
capabilities.setCapability("androidPackage", "com.android.dialer");
capabilities.setCapability("appActivity", "DialtactsActivity");
and use this snippet to make call via Appium :
remoteWebDriver.findElement(By.id("com.android.dialer:id/search_view")).sendKeys("NAME_OF_PERSON");
remoteWebDriver.findElements(By.id("com.android.dialer:id/dialer_search_item_view")).get(0).click();
This would make call to the first search item
try {
Thread.sleep(60000); //
} catch (InterruptedException e) {
e.printStackTrace();
}
remoteWebDriver.findElement(By.id("com.android.dialer:id/endButton")).click();
This would disconnect the call after 60 seconds.
You can use a start a phone call using ADB:
public static int makePhoneCall(AppiumDriver driver, Srting deviceId, String phoneNum, int callDuration) throws IOException, InterruptedException {
callDuration *= 1000;
cmd = "adb -s " + deviceId + " shell am start -a android.intent.action.CALL -d tel:" + phoneNum; //open a Dialer and placing a call right away
Process exec = Runtime.getRuntime().exec(cmd); //starting a call and..
Thread.sleep(callDuration);//..waiting for callDuration seconds before hangup
driver.sendKeyEvent(6);// hang up phonecall
return exec.exitValue();
}
It turns out that this is possible, though perhaps a little more painfully than I expected. I had to do two things: specify the correct app to open, and work out the xpath references to the buttons on the dial pad. The activity is com.android.contacts.activities.DialtactsActivity and the xpaths to some of the buttons are:
Number text field: /linear/linear/editText
Number 1 button: /linear/table/row[1]/imageButton[1]
Number 5 button: /linear/table/row[2]/imageButton[2]
Dial button: /linear/frame/imageButton
If anyone has a better way to do this, I'd be very pleased to see it! Martin
press home button
driver.sendKeyEvent(3);
Press call button.
dr.sendKeyEvent(5);
locate dial pad
driver.findElementById("com.android.dialer:id/dialpad_button").click();
type number by send key or by sendKeyEvents.
driver.findElement(By.className("android.widget.EditText")).sendKeys(phoneNumber);
Press call button
driver.findElementById("com.android.dialer:id/dial_button").click();
put some wait and press End call button.
dr.findElementById("com.android.dialer:id/endButton").click();
I have a problem setting up Robotium tests to run on Travis without random false posivities.
Every couple of builds I get
pl.mg6.agrtt.TestActivityTests > testCanEnterTextAndPressButton[test(AVD) - 4.4.2] FAILED
junit.framework.AssertionFailedError: EditText is not found!
at com.robotium.solo.Waiter.waitForAndGetView(Waiter.java:540)
on all my tests.
I have created a simple project on GitHub to show the issue.
You may see how it builds on Travis. Note build #7 failed after modyfing unrelated file.
I'm suspecting this to be caused by emulator being locked or its sceeen dimmed. I could reproduce this issue on local machine by turning connected device's screen off and then running
./gradlew connectedAndroidTest
After modyfing tests I got a different error message, which is somewhat more informative, so I'm adding it just in case someone tries to find a solution:
pl.mg6.agrtt.TestActivityTests > testCanFindViewsEnterTextAndPressButton[test(AVD) - 4.4.2] FAILED
junit.framework.AssertionFailedError: Click at (160.0, 264.0) can not be completed! (java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission)
at com.robotium.solo.Clicker.clickOnScreen(Clicker.java:106)
While the root cause of this problem is still unknown to me, after some investigation and with a help from Robotium's author Renas Reda I could confirm what I initially suspected that emulator indeed locks itself.
A workaround I'm using now is this code put in setUp method:
getInstrumentation().runOnMainSync(new Runnable() {
#Override
public void run() {
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
});
Robotium discards invisible views when using enterText(int, String). Instead use getView(int) of Solo to use resulting view in enterText(View, String).
Like this:
public void testCanEnterTextAndPressButton() {
solo.enterText(((EditText) solo.getView(R.id.editText1)), "my login");
solo.enterText(((EditText) solo.getView(R.id.editText2)), "my password");
solo.clickOnView(solo.getView(R.id.button));
}
And if the device screen is locked Robotium fails to run those instructions you gave. You might want to disable screen locking.
By code above my tests pass.
Your guess is probably right. One way to be sure that it is is to catch the exception that is thrown and call
solo.takeScreenshot("screenshotFileName");
and then take a look at the screenshot that is saved to your phone's SD card to see what your phone was doing at the time of the error.
I solved this problem by turning on the device's "Stay Awake" setting so it won't sleep while recharging.
Whether I use this:
process = Runtime.getRuntime().exec("logcat -d time");
or that:
process = new ProcessBuilder()
.command("logcat", "-d", "time")
.redirectErrorStream(true)
.start();
I get the same results: it often hangs within the exec() or start() call, no matter what I tried to do!
The thread running this cannot even be interrupted with Thread.interrupt()! The child process is definitely started and if killed the above commands return.
These calls may fail on first attempt, so THERE IS NO WAY TO READ THEIR OUTPUT! I can also use a simple "su -c kill xxx" command line, same result!
EDIT: Started debugging the java_lang_ProcessManager.cpp file in an NDK project with some debugging logs! So here is what I found so far, after the fork() the parent does this:
int result;
int count = read(statusIn, &result, sizeof(int)); <- hangs there
close(statusIn);
Though the child process is not supposed to block on it: That's what the child does (if started at all!):
// Make statusOut automatically close if execvp() succeeds.
fcntl(statusOut, F_SETFD, FD_CLOEXEC); <- make the parent will not block
// Close remaining unwanted open fds.
closeNonStandardFds(statusOut, androidSystemPropertiesFd); <- hangs here sometimes
...
execvp(commands[0], commands);
// If we got here, execvp() failed or the working dir was invalid.
execFailed:
int error = errno;
write(statusOut, &error, sizeof(int));
close(statusOut);
exit(error);
The child can fail for 2 reproducible reasons:
1- child code is not running, but the parent believes it is!
2- child blocks on
closeNonStandardFds(statusOut, androidSystemPropertiesFd);
In either case the read(statusIn...) in the parent ends in deadlock! and a child process is left dead (and cannot be accessed, pid unknown, no Process object)!
This problem is fixed in Jelly Bean (Android 4.1) but not in ICS (4.0.4) and I guess it will never be fixed in ICS.
Above solution didn't prove to be reliable in any ways, causing more issues on some devices!
So I reverted back to the standard .exec() and kept digging...
Looking at the child code that hangs, I noticed the child process will hang while trying to close all file descriptors inherited from the parent (except the one created within the exec() call) !
So I search the whole app code for any BufferedReader/Writer and similar classes to make sure those would be closed when calling exec()!
The frequency of the issue was considerably reduced, and actually never occured again when I removed the last opened file descriptor before calling exec().
NB: Make sure SU binary is up-to-date, it can actually cause this issue too!
Enjoy your search ;)
Bug fix in Bionic was commited monthes ago, but it still hasn't been included in Android 4.0.4.
I have the same problem on ICS (seem to works fine on Android < 4). Did you find a solution?
A simple workaround could be to call the "exec" method in a dedicated thread with a timeout-join so that this situation could be "detected" (yes I know it's not very elegant...)