Appium testing automatization: locate element with #ref id in Android Studio - android

I have the element in Android:
<android.support.design.widget.TextInputLayout
android:layout_width="-1"
android:layout_height="-2">
<AutoCompleteTextView
android:id="#ref/0x7f0c007c"
android:layout_width="-1"
android:layout_height="-2"
android:hint="#ref/0x7f060035"
android:maxLines="1"
android:singleLine="true"
android:inputType="0x21" />
</android.support.design.widget.TextInputLayout>
the name for 0x7f0c007c is password inside the ids.xml file.
This TextInputLayout is in the LoginActivity which starts right after SplashScreenActivity.
This is my class for the test:
public class test02 {
WebDriver driver;
#Before
public void testApp() throws MalformedURLException, InterruptedException {
String apkpath = "C:\\Users\\0013498\\Desktop\\qa-XXX-2-2-4-2.apk";
File app = new File(apkpath);
DesiredCapabilities capabilities= new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME,"Android");
capabilities.setCapability("deviceName","Emulator");
capabilities.setCapability("platformName","Android");
capabilities.setCapability("app",app.getAbsolutePath());
capabilities.setCapability("appPackage", "com.XXX.XXX");
capabilities.setCapability("appActivity", "com.XXX.XXX.SplashScreenActivity");
driver = new AppiumDriver(new URL("http://127.0.0.1:4725/wd/hub"),capabilities);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//int KEYCODE_BACK Back key. Constant Value: 4
}
#Test
public void appiumExampleTest() throws Exception {
//WebElement emailEV=driver.findElement(By.id("com.XXX.XXX:id/email"));
//WebElement emailEV=driver.findElement(By.id("com.XXX.XXX.android:id/email"));
WebElement emailEV=driver.findElement(By.xpath(".//*[#id='email']"));
emailEV.sendKeys("#");
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
}
}
As you can see, I'm simply trying to set a text using the id of the AutoCompleteTextView.
My problem is that my test is unable to locate the element, and I have tried this 3 ways:
WebElement emailEV=driver.findElement(By.id("com.XXX.XXX:id/email"));
WebElement emailEV=driver.findElement(By.id("com.XXX.XXX.android:id/email"));
WebElement emailEV=driver.findElement(By.xpath(".//*[#id='email']"));
but none of them works.
the error message is:
org.openqa.selenium.NoSuchElementException: An element could not be located on the page using the given search parameters.
I'm beginner on automatization testing with Appium & Android, and I'm a bit lost.
Please, any help?
Thx
EDIT:
as suggested in an answer to my question, i started using UI Automator Viewer. It is a .bat file located in the /sdk/tools folder.
I started an android emulator device and run the UI automator Viewer. Then, when clicked on Device Screenshot, i got the all the elements and their attributes.
That way i could see the correct id:
I finally used:
AndroidElement emailEV=driver.findElement(By.id("com.mobgen.interview.mobgeninterviewtest:id/email"));
emailEV.setValue("#"); // although i'm stuck here now
thanks for the help!

Step 1: element is the xpath=//android.widget.EditText[contains(#resource-id,"email")]
Step 2:public void click(String element) {
WebElement webElement = appiumDriver.findElement(By.xpath(element));
webElement.click();
System.out.println("Click element: "+element+" index = "+index);
}
Step 3:
public void elementSendText(String element, String text) {
WebElement webElement = appiumDriver.findElement(By.xpath(element));
webElement.sendKeys(text);
}

Related

Program gets hanged when trying to automate a mobile application

Below program hangs completely, after trying to find elements. Doesn't look like anything wrong with xpath either. I need to terminate the program manually each time. Is there anything which i need to change in code or should i need to add something?
public class Test123 {
public static void main(String[] args) throws MalformedURLException, InterruptedException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("noReset", "true");
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "Appium");
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.1.0");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME,"Android");
capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath());
capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.talentpace.substk");
capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, "com.talentpace.substk.MainActivity");
URL url=new URL("http://127.0.0.1:4723/wd/hub");
AndroidDriver driver=new AndroidDriver(url,capabilities);
Thread.sleep(5000);
driver.findElementByXPath("//node[#class='android.widget.EditText']").click();
}
}
Change your AUTOMATION_NAME in desired capabilites from Appium to uiautomator2
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "uiautomator2");
Seems that you have given the wrong xpath
the correct one should look like this
//android.widget.EditText[#class='Enter Class name here..']

Getting exception upon clicking Ionic based icon "Exception in thread "main" org.openqa.selenium.WebDriverException" [duplicate]

I used explicit waits and I have the warning:
org.openqa.selenium.WebDriverException:
Element is not clickable at point (36, 72). Other element would receive
the click: ...
Command duration or timeout: 393 milliseconds
If I use Thread.sleep(2000) I don't receive any warnings.
#Test(dataProvider = "menuData")
public void Main(String btnMenu, String TitleResultPage, String Text) throws InterruptedException {
WebDriverWait wait = new WebDriverWait(driver, 10);
driver.findElement(By.id("navigationPageButton")).click();
try {
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(btnMenu)));
} catch (Exception e) {
System.out.println("Oh");
}
driver.findElement(By.cssSelector(btnMenu)).click();
Assert.assertEquals(driver.findElement(By.cssSelector(TitleResultPage)).getText(), Text);
}
WebDriverException: Element is not clickable at point (x, y)
This is a typical org.openqa.selenium.WebDriverException which extends java.lang.RuntimeException.
The fields of this exception are :
BASE_SUPPORT_URL : protected static final java.lang.String BASE_SUPPORT_URL
DRIVER_INFO : public static final java.lang.String DRIVER_INFO
SESSION_ID : public static final java.lang.String SESSION_ID
About your individual usecase, the error tells it all :
WebDriverException: Element is not clickable at point (x, y). Other element would receive the click
It is clear from your code block that you have defined the wait as WebDriverWait wait = new WebDriverWait(driver, 10); but you are calling the click() method on the element before the ExplicitWait comes into play as in until(ExpectedConditions.elementToBeClickable).
Solution
The error Element is not clickable at point (x, y) can arise from different factors. You can address them by either of the following procedures:
1. Element not getting clicked due to JavaScript or AJAX calls present
Try to use Actions Class:
WebElement element = driver.findElement(By.id("navigationPageButton"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
2. Element not getting clicked as it is not within Viewport
Try to use JavascriptExecutor to bring the element within the Viewport:
WebElement myelement = driver.findElement(By.id("navigationPageButton"));
JavascriptExecutor jse2 = (JavascriptExecutor)driver;
jse2.executeScript("arguments[0].scrollIntoView()", myelement);
3. The page is getting refreshed before the element gets clickable.
In this case induce ExplicitWait i.e WebDriverWait as mentioned in point 4.
4. Element is present in the DOM but not clickable.
In this case induce ExplicitWait with ExpectedConditions set to elementToBeClickable for the element to be clickable:
WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.elementToBeClickable(By.id("navigationPageButton")));
5. Element is present but having temporary Overlay.
In this case, induce ExplicitWait with ExpectedConditions set to invisibilityOfElementLocated for the Overlay to be invisible.
WebDriverWait wait3 = new WebDriverWait(driver, 10);
wait3.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("ele_to_inv")));
6. Element is present but having permanent Overlay.
Use JavascriptExecutor to send the click directly on the element.
WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
In case you need to use it with Javascript
We can use arguments[0].click() to simulate click operation.
var element = element(by.linkText('webdriverjs'));
browser.executeScript("arguments[0].click()",element);
I ran into this error while trying to click some element (or its overlay, I didn't care), and the other answers didn't work for me. I fixed it by using the elementFromPoint DOM API to find the element that Selenium wanted me to click on instead:
element_i_care_about = something()
loc = element_i_care_about.location
element_to_click = driver.execute_script(
"return document.elementFromPoint(arguments[0], arguments[1]);",
loc['x'],
loc['y'])
element_to_click.click()
I've also had situations where an element was moving, for example because an element above it on the page was doing an animated expand or collapse. In that case, this Expected Condition class helped. You give it the elements that are animated, not the ones you want to click. This version only works for jQuery animations.
class elements_not_to_be_animated(object):
def __init__(self, locator):
self.locator = locator
def __call__(self, driver):
try:
elements = EC._find_elements(driver, self.locator)
# :animated is an artificial jQuery selector for things that are
# currently animated by jQuery.
return driver.execute_script(
'return !jQuery(arguments[0]).filter(":animated").length;',
elements)
except StaleElementReferenceException:
return False
You can try
WebElement navigationPageButton = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("navigationPageButton")));
navigationPageButton.click();
Scrolling the page to the near by point mentioned in the exception did the trick for me. Below is code snippet:
$wd_host = 'http://localhost:4444/wd/hub';
$capabilities =
[
\WebDriverCapabilityType::BROWSER_NAME => 'chrome',
\WebDriverCapabilityType::PROXY => [
'proxyType' => 'manual',
'httpProxy' => PROXY_DOMAIN.':'.PROXY_PORT,
'sslProxy' => PROXY_DOMAIN.':'.PROXY_PORT,
'noProxy' => PROXY_EXCEPTION // to run locally
],
];
$webDriver = \RemoteWebDriver::create($wd_host, $capabilities, 250000, 250000);
...........
...........
// Wait for 3 seconds
$webDriver->wait(3);
// Scrolls the page vertically by 70 pixels
$webDriver->executeScript("window.scrollTo(0, 70);");
NOTE: I use Facebook php webdriver
If element is not clickable and overlay issue is ocuring we use arguments[0].click().
WebElement ele = driver.findElement(By.xpath("//div[#class='input-group-btn']/input"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
The best solution is to override the click functionality:
public void _click(WebElement element){
boolean flag = false;
while(true) {
try{
element.click();
flag=true;
}
catch (Exception e){
flag = false;
}
if(flag)
{
try{
element.click();
}
catch (Exception e){
System.out.printf("Element: " +element+ " has beed clicked, Selenium exception triggered: " + e.getMessage());
}
break;
}
}
}
In C#, I had problem with checking RadioButton,
and this worked for me:
driver.ExecuteJavaScript("arguments[0].checked=true", radio);
Can try with below code
WebDriverWait wait = new WebDriverWait(driver, 30);
Pass other element would receive the click:<a class="navbar-brand" href="#"></a>
boolean invisiable = wait.until(ExpectedConditions
.invisibilityOfElementLocated(By.xpath("//div[#class='navbar-brand']")));
Pass clickable button id as shown below
if (invisiable) {
WebElement ele = driver.findElement(By.xpath("//div[#id='button']");
ele.click();
}

Install Android APK on emulator using appium Node server

I have an appium server created in NODE.JS. I am working out to make the appium test to run an emulator and install the apk. Not able to find any particular examples online that has example on how to do it using Node server. Mostly examples are with the desktop installed appium server. I need some guidelines on how to do that. To further break it down, I want to perform following things using the appium Node server (Not to right any test case in the application source code)
Start the emulator or possible if can do it on real device
Install the APK on the emulator/device
Fire an intent that launches the app on emulator/device . Intent also contains data in bundle
Perform a click on a button inside the app.
start appium server in your terminal
appium
Output of above command like below on your terminal
Sample code here :
public class AppTest {
AppiumDriver driver;
MobileElement appTitle;
#Before
public void setup() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "7.0");
desiredCapabilities.setCapability(MobileCapabilityType.NO_RESET, true);
desiredCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Moto");
desiredCapabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.android.vending");
desiredCapabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, "com.google.android.finsky.activities.MainActivity");
driver = new AndroidDriver(new URL("http://0.0.0.0:4723/wd/hub"), desiredCapabilities);
}
#Test
public void testGooglePlayApp() throws InterruptedException {
String appName = "Amazon Now - Grocery Shopping";
//How to scroll to specific text
MobileElement scrollToText = (MobileElement) driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView(new UiSelector().text(\"" + appName + "\"));"));
scrollToText.click();
// Verifying the app detail page
appTitle = (MobileElement) driver.findElementById("com.android.vending:id/title_title");
Assert.assertTrue(appName.equals(appTitle.getText().trim()));
driver.navigate().back();
//Clicking the search bar icon
MobileElement scrollToElement = (MobileElement) driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView(new UiSelector().description(\"Search\"));"));
scrollToElement.click();
MobileElement editText = (MobileElement) driver.findElementById("com.android.vending:id/search_box_text_input");
editText.sendKeys(appName);
Thread.sleep(1000);
List<MobileElement> listOfSuggestedResults = driver.findElementsById("com.android.vending:id/suggest_text");
for (MobileElement element : listOfSuggestedResults) {
if (appName.equals(element.getText().trim())) {
element.click();
break;
}
}
appTitle = (MobileElement) driver.findElementById("com.android.vending:id/title_title");
Assert.assertTrue(appName.equals(appTitle.getText().trim()));
}
#After
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
}
Sample code in github : https://github.com/tech-tock-tech/apptest
hope above will help if you still facing issue please check below video link -
https://www.youtube.com/watch?v=jP2NAY8ylp8

Appium Android Automation

This may be simple question for the experts. I am a beginner in appium and all these days i have been trying to make my test script for printing a page title in my script. Here is the part of My code below: i am unable to print the page title and then do a validation. Can someone help?
driver = new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
System.out.println(driver.getRemoteAddress());
}
public void ApkPushValidation() throws Exception {
Assert.assertEquals("Verify your phone number", driver.findElementByName("Verify your phone number").getText());
driver.wait(5000);
String i = driver.getTitle();
System.out.println(i);
if (driver.getTitle().equals("Verify your phone number") ) {
System.out.println("app installation is passed");
} else {
System.out.println("App installation is failed");
}
//System.out.println(i);---> my expectation is that this will print out Verify your Phone number. However this is not printing the page title.
Use UIAutomatorViewer to find out the xpath of the title.
use the following website for example on how to use the x-path. "http://software-testing-tutorials-automation.blogspot.ca/2015/10/ui-automator-viewer-get-android-app.html"
I think that driver.getTitle() is a method for Web page interaction, not meant for Native apps. I would suggest to use XPath or some other element locator to find the title.
Instead if getTitle(); try to use xPath, name or Id available for the title. Use Appium inspector or UI automator to locate that element and change it like this:
String i = driver.findElementById("Your ID").getText();
if (i.equals("Verify your phone number") ) {
System.out.println("app installation is passed");
} else {
System.out.println("App installation is failed");
}
What you probably what to perform should be done using the following piece of code :
WebElement title = driver.findElementByName("Verify your phone number"); // defining the element only once for multiple use
// different locator strategies could be used for locating the element above
Assert.assertEquals("Verify your phone number", title.getText());
driver.wait(5000);
String i = title.getText();
System.out.println(i);
if (i.equals("Verify your phone number") ) {
System.out.println("app installation is passed");
} else {
System.out.println("App installation is failed");
}
More on driver.getTitle() : It has been inherited from RemoteWebDriver and possibly should return the title of a webpage/webview instead of an native application view which seems to be your case.
Note: would add more to this about getTitle() as I get to know.

Can i use only an app's .apk to automate using appium? Or i need the app in my workspace?

I am asking this because when i automate an app(TestApp.apk) present in my workspace is working fine. But when i use another app(WnG.apk) which is not present in my workspace it doesn't works. At this time appium fails to locate the element. An error ("An element could not be located on the page using the given search parameters.") occurs.
Below is my code:
public class Appium {
WebDriver driver;
#BeforeClass
public void setUp() throws MalformedURLException{
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "Android Emulator");
capabilities.setCapability(CapabilityType.BROWSER_NAME, ""); //Name of mobile web browser to automate. Should be an empty string if automating an app instead.
capabilities.setCapability("platformVersion", "4.4");
capabilities.setCapability(CapabilityType.PLATFORM, "Windows");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("app", "C:/Appium/AppiumForWindows-1.2.4.1/WishAndGreet.apk");
capabilities.setCapability("app-package", "com.example.wishandgreet"); //Replace with your app's package
capabilities.setCapability("app-activity", ".LoginActivity"); //Replace with app's Activity
driver = new RemoteWebDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
}
#Test
public void loginTest(){
System.out.println("*************************************************************");
WebElement e1 = driver.findElement(By.id("com.example.wishandgreet:id/usernameEditText"));
System.out.println(e1.getText());
Assert.assertTrue(e1.getText() == "email / mobile number", "Username Text incorrect");
//Assert.assertEquals(e1.getText(),"email / mobile number");
e1.sendKeys("test#gmail.com");
WebElement e2 = driver.findElement(By.id("com.example.wishandgreet:id/passwordEditText"));
Assert.assertTrue(e2.getText() == "Password", "Pass text incorrect");
e2.sendKeys("1234");
System.out.println(e2);
WebElement e3 = driver.findElement(By.id("com.example.wishandgreet:id/loginButton"));
e3.click();
System.out.println(e1);
}
#AfterClass
public void tearDown(){
driver.quit();
}
In Android case, you need only .apk file to automate using Appium.
Looks like the issue you are facing is related to identifying an element. Please double check you are using right locators to identify required element and make sure that element appears on the view.

Categories

Resources