Find and element on Android using Selenium and Appium - android

I'm using this code in order to find an element on my Android (Native App) device using selenium and Appium :
var wait = new WebDriverWait(_driver,TimeSpan.FromSeconds(15));
var phone = wait.Until(x => x.FindElements(By.Id("foo")));
The problem is that Selenium finds the element only seemingly. Meaning it finds it, but with no attributes at all.
But when using :
System.Threading.Thread.Sleep(5000)
everything works like a charm.
I have tried to increase the seconds in the driver's wait, but it didn't help.

I think the element is not getting loaded at the time script is performing an operation on it.
Try to add a visibility check before performing any operation on that element
WebDriverWait wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.locator);

Related

Protractor locators does not work in PageObjectModel structure

Framework: Appium + Protractor + Cucumber + Typescript using POM model
I have the protractor framework for appium designed in POM structure
The initial page of the app will identify the locators calling in a different ts file and the functions such as tap, isDisplayed calling it in a different ts file.
But once it passes the initial pages in the app,say 3 pages. the locators are not identified which are calling other function, but they are identified when they are passed directly ( like driver.findelements(by.css('')).click ) this works.
The problem is I can't pass this code like this within the step definition .ts file always as it is not a good structure
Note: By the way, this script was working fine earlier.
tried to test using a different workaround, like building the binary again, trying to run on android and ios application, downgrading or upgrading the node packages. But nothing solved the problem. has anyone faced this kind of issue. Any suggestions or solutions for this problem, please?
Code which works: (Passing the locators directly in the function, rather than from the onboarding.ts file will work)
Then(/^VIC should be selected from the state or territory drop down$/, async () => {
await browser.driver.findElement(by.css('button[sp-automation-id=\'select-state-toggle\']')).click();
await browser.driver.findElement(by.css('page-action-sheet label[sp-automation-id=\'action-sheet-option-VIC\']')).click(); });
Code which does not work: (Onboarding.ts file contains the locators defined for State and VIC same as the above code block. But reading from there it does not work.)
Then(/^VIC should be selected from the state or territory drop down$/, async () => {
await AutomationAction.tap(Onboarding.State);
await AutomationAction.tap(Onboarding.VIC); });
Code which works (The below code is called before the above code block, it's a page before calling the above pages)
Then(/^I enter the mobile number and tap next button on the your mobile number screen$/, async () => {
MobileNo = AutomationAction.getMobileNumber("mobileNumber");
SameMobileNo = MobileNo;
await AutomationAction.sendKeyText(Onboarding.InputMobileNo,MobileNo);
await AutomationAction.tap(Onboarding.Next_BTN_YourMobileNumber);
});
Because of the page where it is failing the automation thinks its as non-angular page and the locators used to fail or not locate them when calling it in a different function. When I introduced browser.ignoreSycnhronization=true to make Angular sync for non-angular apps/pages it worked.

cordova.file.* (all directories) are null

I'm working on Ionic mobile app development.
My requirement is to create client side logger to track issues in app. I used the methods mentioned in https://github.com/pbakondy/filelogger, and I could able to create the log file in both Android and iOS.
For the first time when I open the app, it creates the log file in cordova.file.dataDirectory, when I close and reopen the app in i*OS, I'm trying to read the content of the file which was created using the below
$fileLogger.getLogfile().then(function (loggerContent) {
var temp =loggerContent;
});
But the application says
{
"applicationDirectory":null,
"applicationStorageDirectory":null,
"dataDirectory":null,
"cacheDirectory":null,
"externalApplicationStorageDirectory":null,
"externalDataDirectory":null,
"externalCacheDirectory":null,
"externalRootDirectory":null,
"tempDirectory":null,
"syncedDataDirectory":null,
"documentsDirectory":null,
"sharedDirectory":null
}
So I couldn't able to find the file where i saved my logs.
Please help me resolve this issue or if you could recommend me a different method to get around this issue, that would be great!
Thanks for the answers
There is a check list here and should solve your problem :
1-Be sure that the cordova-file-plugin is installed and works in your test environment.
2-Be sure that the cordova.js file is refrenced by your html and before your code usage.
3-Be sure to call your codes after device_ready state :
check this
4-Call your function after a short delay (use setTimeOut in Javascirpt)
Ali's item 4 is very important:
I had a similiar problem on different platforms: cordova.file.dataDirectory was null.
I tracked cordova.file.dataDirectory over the lifecycle and it was first accessed by my Ionic 2 code BEFORE the device ready event was fired.
My "mistake": I wanted to load data during the constructor(!) of a service. Seems too early.

Android Read Result From MySQL

My code used to work, it does not work anymore, I tried troubleshooting and can't figure out why.
I have this piece of code in my PHP:
$android_id_01 = $_GET['pmysql_room_id'];
$android_id_02 = "";
$f = fopen("00_android_id_01.txt", "w");
fwrite($f, print_r($android_id_01, true));
fclose($f);
$f = fopen("00_android_id_02.txt", "w");
fwrite($f, print_r($android_id_02, true));
fclose($f);
For troubleshooting I created two android IDs ($android_id_01 and $android_id_02) which are both empty (The first one is From Android and the second one I created directly from PHP).
Now when I launch my Android device, the PHP file is executed from server side and both the text files are created empty and identical. Now my code only works when I use $android_id_02 and not $android_id_01 from the code below:
if ($android_id == '')
{
//my code
}
(Yes when I use either one of the $android_id_01 OR $android_id_02 I rename it to $android_id and comment out the other one)
My question is, although this was working yesterday, why does it work with $android_id_02 = ""; and not $android_id_01 = $_GET['pmysql_room_id']; even though they are both empty????
I don't know what changed from yesterday to today.
Ok after a bit of troubleshooting I found a solution, strange though.
On the server side "display_errors" under PHP settings must be turned off. Somehow having this on interferes with the json_encode sent back to android client. (even though my code is not generating any errors)

error with pymtp to work on python 3

I want to access a android device from python to download some photos.
libmtp works from the CLI.
Than pymtp. It's been around for a while but it's designed for python 2 and i'm using python 3. Meanwhile fixed several minor issues but i'm stuck at an error from function get_filelisting
specially this section:
ret = []
next = files
while next:
ret.append(next.contents)
if (next(next.contents) is None):
break
next = next(next.contents)
The error is related to the "next".
That section looks strange to me, i've been coding in python for a while but i'm new to ctypes. Tried a lot of variants, they all failed. The "next" could be confusing with python buildin function so i renamed it to nextpointer and came to this code:
ret = []
nextpointer = files
while nextpointer:
ret.append(nextpointer.contents)
nextpointer = nextpointer.contents.next
It seems to work but did it work by accident ? does it have any design flaws ? Could anyone with experience on python ctypes confirm this a solution ? Any suggestion welcome.
From python2.7 documentation
next(iterator[, default])
Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is
exhausted, otherwise StopIteration is raised.
from python3 documentation
next(iterator[, default])
Retrieve the next item from the iterator by calling its __next__() method. If default is given, it is returned if the iterator is
exhausted, otherwise StopIteration is raised.
Notice that next() method was removed from python3 but the function still exists.
This is all I can say about the next function and .next()/__next__() methods.
I downloaded the pymtp module and get_filelisting() is slightly different from what you posted in your ported code, here it is:
ret = []
next = files
while next:
ret.append(next.contents)
if (next.contents.next == None):
break
next = next.contents.next
If none of this helped you (which probably didn't :D), the version of pymtp library that I am using is 0.0.6 download using pip.

Appium: "An element could not be located on the page using the given search parameters" error

I am new to Appium and have been trying to automate the Conversion Calculator app for Android. Am getting the error "org.openqa.selenium.NoSuchElementException: An element could not be located on the page using the given search parameters", when trying to find a EditText element. Using Appium ver 1.0.0 and Android 4.3
The following is my code:
List<WebElement> textViews = driver.findElements(By.className("android.widget.TextView"));
for (i=0; i<textViews.size(); i++) {
if(textViews.get(i).getText().toLowerCase().contains("memory")) {
textViews.get(i).click();
}
}
Thread.sleep(5000);
WebElement editText = driver.findElement(By.className("android.widget.EditText"));
editText.sendKeys("123");
Even findElement by ID is not working. Please let me know what I am doing wrong here or if I need to provide more details.
I would use
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); instead of Thread.sleep(5000).
Try to use a newer version of Appium, I's been improved a lot. You can download the latest version of Appium and Appium clients here:http://appium.io/downloads.html
But be careful because in the newer version the findElement throws an Exception if there are more then one result of the search.
I would write this in a comment but I've not enough reputation :/
Possible Cause:
Multiple EditText in the current screen.
Please try with the following:
Solution1:
List<WebElement> editText = driver.findElements(By.className("android.widget.EditText"));
editText.get(0).sendKeys("123");
0 - Index of EditText
Solution2:
Use any other locating strategy like Xpath.
Maybe you could try waiting until the element is visible or enabled using a WebDriverWait object?
Avoid using sleep as much as possible, try using the WAIT command.
Sleep without waiting for the time that has been determined, even if the element is already on the screen.
In the case of the wait command, as soon as the element appears, the action will already be performed, this along the code will reduce the execution time considerably.
The issue for me was the app path I was using. If you are using a config file make sure to declare the application separately from the device.
If not, make sure the "app" capability has the right path. Here is the code in my config file for example:
devices_by_ids = {
"platformName": "Android",
"appium:DEVICE ADB ID": {
"android_version": "13",
"device_name": "google_Pixel_5a",
"DEVICE ADB ID": "DEVICE ADB ID",
"port":"4723",
"autoGrantPermissions": "true",
},
"appium:app": "YOUR APP PATH",
"appium:appWaitActivity": "*"
}
In Appium v2 use
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

Categories

Resources