Tried the login use case with appium for android native app. But button click not working. But I am getting all test passed.Tried with mobile driver also.
#BeforeClass
public static void setUp() throws MalformedURLException
{
DesiredCapabilities capabilities=new DesiredCapabilities();
capabilities.setCapability("BROWSER_NAME","Chrome");
capabilities.setCapability("VERSION","4.3");
capabilities.setCapability("deviceName","SGH-T999L");
capabilities.setCapability("platformName","Android");
capabilities.setCapability("appPackage","org.odk.collect.android");
capabilities.setCapability("appActivity","com.fieldforce.android.activities.LoginActivity");
webDriver=new RemoteWebDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
// webDriver.manage().timeouts().implicitlyWait(80, TimeUnit.SECONDS);
}
#Test
public void testLogin() throws Exception
{
// webDriver.switchTo().window("NATIVE_APP");
WebDriverWait wait = new WebDriverWait(webDriver, 10);
WebElement userName= webDriver.findElement(By.id("txt_username"));
userName.sendKeys("733894");
WebElement password= webDriver.findElement(By.id("txt_password"));
password.sendKeys("Pass#123");
WebElement login_button= webDriver.findElement(By.id("org.odk.collect.android:id/btn_login"));
wait.until(ExpectedConditions.visibilityOf(login_button));
login_button.click();
}
#AfterClass
public static void tearDown()
{
webDriver.quit();
}
Of course the test will pass, as you are just trying to click on Login Button, it doesn't matter for your test case whether it should pass or fail unless you add some Assert after clicking on login button.
Try adding some wait after click on login
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
And then try asserting something in #test for method testLogin like add below two statement in the end, and make them compatible with locator you get after login
Actualtext = driver.findElement(By.xpath("locator to verify after login")).getText();
Assert.assertEquals(Actualtext, "assert Text");
I got the same issue.
Please make sure your submit button(UI) is not covered by the phone keyboard.
If it covers, Solution :
hide the keyboard before run the click [.click()] function.
keyboard hide code is here How to dismiss the keyboard in appium using Java?
Reason:
Coz Appium clicks the button using x&y UI coordinates and if the keyboard covers the submit button it clicks on the keyboard not on the button.
In my case I've also tried similar button clicking with no result. I've realized that I wasn't clicking the right element.
To verify what I was clicking I've printed element's Text and TagName:
List<MobileElement> views = driver.findElements(By.className ("android.widget.TextView"));
System.out.println("1: "+views.get(2).getText());
System.out.println("2: "+views.get(2).getTagName());
views.get(2).click();
Output was:
1: OK
2: android.widget.TextView
My classNames I got through UI Automator Viewer, Android/Sdk/tools/bin/uiautomatorviewer application.
Although, before list's getting you could temporarily use Thread.sleep(5000); with your own values to check assumption about slow element loading and replace it with proper time waiting method if required in case of time problem.
Sometimes a button could have multilayer structure and it is required to get the right layer you could click. In my case there were two layers.
Would suggest using
WebElement login_button= webDriver.findElement(By.id("btn_login")); //as used for other WebElement
Also i believe a general login page shall ideally be having the login visible, if that not be the case, you might want to perform a scroll down on the page instead of
wait.until(ExpectedConditions.visibilityOf(login_button));
PS - If you are receiving any error/exception post this. Please add to the question and let know.
As your keyboard hiding the Login button, so hide the keyboard by,
driver.hidekeyboard();
Related
UI Automator Viewer
Whenever I use below command to click on Ok button, it clicks on the same position as pointing in UI Automator viewer. (screenshot)
I need to click on Ok Button.
Driver.findElement(By.xpath("//android.widget.Button[#text='Ok']")).click();
First of all, since you have resource-id, the most reliable will be to use it for search:
driver.findElementById("confirm_button").click()
If it still click the wrong element you might need to wait a bit (for popup to be loaded) and then perform click
Can you try :
Driver.findElement(By.xpath("//*[#class='android.widget.Button and #text='Ok']")).click();
Have you tried to click by coordinates?
(Python code)
myElement = driver.find_element_by_id('confirm_button')
x = myElement.location['x']
y = myElement.location['y']
touchAction.tap(None, x, y, 1).perform()
I had the same problem when many layers are displayed at the same time...
Hope it helps
Update
(Java code)
WebElement myElement = driver.findElementById("confirm_button");
int x = myElement.getPosition().getX();
int y = myElement.getPosition().getY();
touchAction.tap(x, y).perform();
The problem was when i am trying enter data on signup page Keyboards opens and due to that UI Automator screenshot giving wrong position of button. So what i have done is to use below command to hide the keyboard before clicking signup button.
Driver.navigate().back();
delay(3000);
Driver.findElement(By.id("btn_register_signup")).click();
I'm using Appium 1.6.5 and Windows 10.
Using the demo app by Appium (ApiDemos-debug.apk), I am trying to drag and drop dots.
View app screen:
This is my current code:
TouchAction actions = new TouchAction(driver);
actions.tap((AndroidElement)driver.findElementByAndroidUIAutomator("text(\"Views\")")).perform();
driver.findElementByAndroidUIAutomator("text(\"Drag and Drop\")").click();
AndroidElement element1 = driver.findElement(By.id("io.appium.android.apis:id/drag_dot_1"));
AndroidElement element2 = driver.findElement(By.id("io.appium.android.apis:id/drag_dot_2"));
actions.longPress(element1).waitAction(3000).perform().release();
This error prints when test is run:
org.openqa.selenium.NoSuchElementException: An element could not be
located on the page using the given search parameters. (WARNING: The
server did not provide any stacktrace information)
Any combination of longPress() calls results in this error. I can click & tap, that's fine. When it comes to using other TouchAction methods, then errors occur.
Any idea how to resolve this? Need to know if it's my setup that's wrong or TouchAction method has issues.
You need to long press on that element and drag it to other element.Currently, you're only pressing long and performing the action without releasing it.
Try this:
actions.longPress(element1).moveTo(element2).release().perform();
My Android application has a button to download a file and then send it to an application on the device. Android pops up a screen listing the Applications on the device for the user to select which application to use.
I would like to automate this flow but i can not see how I can automate clicking on the Application Picker that Android presents. I presume this is because it is outside of my application.
I tried using Android Studio's "Record Expresso Test", I performed the following test steps
click on the action which sends my image to an app on the device (action1)
saw the Android Application picker appear and chose photos
Clicked back to close photos app and go back to my app
click on a different action in my app (action2)
I see in the recorded test code for steps 1 and 4 above, but nothing for 2 and 3. Therefore it makes me think that Expresso can not be used for this particular test flow.
Does anyone know how I could test this flow using Expresso?
EDIT:
Thank you to "John O'Reilly" for recommending UI Automator. I can see that I can use the UI Automator code within my Expresso test successfully. However I am having trouble writing a precise verification of the Application Selector.
The selector will have a title of "Open With". Using Android Device Monitor I can see the hierarchy of objects as illustrated below.
Some classes and IDs are internal so I can not search on those things. I do not want to code to look for a specific application as when the test is run on another machine it may not have that application. I just need to verify that the application picker has been displayed.
// the app selector has a FrameLayout as one of its parent views, and a child Text View which has the "Open With" title
UiObject labelOnly = new UiObject(new UiSelector()
.className("android.widget.FrameLayout")
.childSelector(new UiSelector()
.className("android.widget.TextView")
.text(openWithLabel)
)
);
boolean labelOnly_exists = labelOnly.exists();
// the app selector has a FrameLayout as one of its parent views, and a child ListView (containing the apps)
UiObject listOnly = new UiObject(new UiSelector()
.className("android.widget.FrameLayout")
.childSelector(new UiSelector()
.className("android.widget.ListView")
)
);
boolean listOnly_exists = listOnly.exists();
// I can use the listView to search for a specific app, but this makes the tests fragile if a different device does not have that app installed
UiObject listAndAppName = new UiObject(new UiSelector()
.className("android.widget.ListView")
.instance(0)
.childSelector(new UiSelector()
.text("Photos")));
boolean listAndAppName_exists = listAndAppName.exists();
How could i write a statement that verifies that what is on the screen is the application picker? I was hoping maybe have a selector that searches for a FrameLayout which has a child textView containing "Open With" and also contains a child ListView. With these 2 checks together it should identify only the application picker.
The credit for the answer to this question should go to John O'Reilly who pointed me to use the UI Automator.
I resolved the issue of checking what Android screen is invoked when my test clicks on an action by just checking there is a TextView on the screen with the title I am expecting. Its not perfect as this will pass if there is any TextView on the screen with the text so does not precisely check its the application picker.
However, for my test this should be enough of a check as my app (which would be behind the app picker) should not have a TextView with the expected title, so if the title is found its pretty much likely to be the application picker.
public static boolean verifyAndroidScreenTitlePresent(String title) {
UiDevice mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
UiObject titleTextUI = new UiObject(new UiSelector()
.className("android.widget.TextView")
.text(title)
);
boolean titleExists = titleTextUI.exists();
// close the app selector to go back to our app so we can carry on with Expresso
mDevice.pressBack();
return titleExists;
}
I'm unable to find an element (UiObject2) using UiAutomator within my androidTest. I obtained UiDevice instance and try to find the object with this:
MY_UI_DEVICE.findObject(By.res(CURRENT_PACKAGE, id));
CURRENT_PACKAGE is the package of my app MY_UI_DEVICE.getCurrentPackageName(). I tried also with this one:
MY_UI_DEVICE.wait(Until.findObject(By.res(CURRENT_PACKAGE, id)), 10000);
I can see the app is waiting for 10 seconds on the right screen (where the desired object persists), but after timeout it fails to find it and test fails. It always fails on emulator (API 23), but rarely works good on a real device (API 25).
When I debug the code I could see that manually I could obtain the right element by calling sequence of getChild(index) methods on AccessibilityNodeInfo but in the runtime it still fails even the app is waiting on the right screen where I expect the specific element.
I was playing with different UiDevice's functions, but none of the helped and I'm out of ideas, so any help will be appreciated.
There were 2 issues with my tests:
The first problem was in getting / initialising UiDevice instance in static block (as a static field in util class). I moved it into #Beforeand it helped to resolve the issue partially.
Another problem was occurring while searching for an element using a package name obtained from the UiDevice. I replaced getting package with InstrumentationRegistry.getTargetContext().getPackageName(); as it's done in google samples.
Make sure that your Test method is throwing the UiObjectNotFoundException. I had this issue with UiObject2 as well until I started forcing the error throw
#Test
public void clockTest() throws UiObjectNotFoundException, InterruptedException {
mDevice.click(1146,37); //click on clock top right corner
Thread.sleep(1500);//wait 1.5 seconds for screen to load
mDevice.click(1138,135);//clicks in shell
Thread.sleep(1500);//wait 1.5s for screen to load
UiObject2 dTSettingsButton = mDevice.findObject(By.text("Date & Time Settings"));
//assertNotNull(dTSettingsButton);//find and assert the settings button
dTSettingsButton.clickAndWait(Until.newWindow(), LAUNCH_TIMEOUT);//clicks the settings button
UiObject2 timeFormatButton = mDevice.findObject(By.text("Select Time Format"));
assertNotNull(timeFormatButton);//find and assert timeformat button
timeFormatButton.clickAndWait(Until.newWindow(), LAUNCH_TIMEOUT);//click timeformat button
UiObject2 twelveHourButton = mDevice.findObject(By.res("com.REDACTED.settings:id/first_btn"));
assertNotNull(twelveHourButton);//find and assert twelvehour button
twelveHourButton.clickAndWait(Until.newWindow(), LAUNCH_TIMEOUT);//click twelvehour button
}
Try use UiSelector methods. That worked for me much better than By selectors
Steps to repro
Log in to FB with new FB account I can see the webdialog showing me
current goals and other stuff, but I can not see Authorize OK cancel
buttons(probably moved down). I can not scroll to see those buttons
Can any one suggest me quick fix, without necessarily updating FB SDK
I can confirm this is affecting Facebook SDK 2 and 3 in Android. I can't speak to iOS. For some reason, scrollbars are disabled in their WebDialog.java code so I tried enabling scrollbars in setUpWebView. Scrollbars now appear in this prompt but the OK and Cancel buttons aren't there. So, it's not a case of the buttons being off-screen and unreachable but rather the buttons aren't part of the content at all when the Current Goals section is included.
It looks like this is a problem Facebook will need to resolve on their side.
I just posted this workaround to: webDialog "CURRENT GOALS" header but no button to authorize or cancel
In the FaceBookSDK I modified com/facebook/widget/WebDialog.java, so that once the web dialog was loaded it would look for the block that contains "Current Goals" and hide it (if it exists). Once you do that, the buttons are visible again (at least they were for me).
In com/facebook/widget/WebDialog.java:
private class DialogWebViewClient extends WebViewClient {
// ... other methods ...
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (!isDetached) {
spinner.dismiss();
}
/*
* Once web view is fully loaded, set the contentFrameLayout background to be transparent
* and make visible the 'x' image.
*/
contentFrameLayout.setBackgroundColor(Color.TRANSPARENT);
webView.setVisibility(View.VISIBLE);
crossImageView.setVisibility(View.VISIBLE);
// I don't know how to highlight in the code block
// So I just add this extra long comment to make it obvious
// Add a javascript call to hide that element, if it exists
webView.loadUrl("javascript:try{ document.getElementById('nux-missions-bar').style.display='none'; } catch (e) {}");
// End changes
}
This should help, at least until FaceBook fixes the API.
I was facing the same problem which is solved. I just changed my app permission which was running in sandbox mode> I just changed it to live mode and suddenly everything started working fine. I think there was a problem with fb sdk which is solved by now.....