How to instantiate Appium Driver based on platform? - android

I am a beginner in automation testing. I am trying to write common test project for my android and ios app. Both the apps on ios and android have almost same UI and flow. I want to know how can I instantiate Appium driver for based on the platform.
As of now, I am thinking to have a boolean variable isAndroid which I would have to manually change in the code before running the tests.Based on isAndroid I instantiate AppiumDriver to AndroidDriver or IOSDriver and elements will be located as per #AndroidFindby or #IOSFindBy
When I start Appium from the terminal, I mention the parameter platformName, is there a way to fetch that information in my code so that I do not have to manually change isAndroid variable and exactly same test code runs on both platforms.

Are you able to try one platform, catch the exception and then try the other?
try:
driver = webdriver.Remote('http://localhost:4723/wd/hub', ios_caps)
run_iOS_tests(driver)
except selenium.common.exceptions.WebDriverException:
driver = webdriver.Remote('http://localhost:4723/wd/hub', android_caps)
run_android_tests(driver)
Otherwise you'll need to use some external method to see what devices are connected (android, ios).

Related

Unable to Inspect Object com.android.incallui.service.SecCallPopupService on Samsung J5

I have a problem that I think is related with Android permissions, however I need some of your expertise to confirm it.
I have testing the old Samgung J5(Not rooted) with Android 8.1.0, Appium 1.10.0 with UiAutomator2 and ADB 10.0.40 (In administration mode) on some Call Handling scenarios where I need to check if determined display elements (identity, call duration, hold activated, on transfer information, etc) are displayed to user. I have seen multiple solutions to do this task, inclusively using adb to do it, but lets focus only on this problem, using only the display elements (GUI).
Scenario, user receives call.
The com.android.incallui.service.SecCallPopupService comes into action:
User receives call
When I try to inspect the com.android.incallui.service.SecCallPopupService window the Appium cannot found it:
Appium Inpector
Neither on UiAutomatorViewer:
UitAutomatorViewer
On Comment link (xml dump) you can seen the display elements that Appium, and UiAutomatorViewer can "see". Same result was obtained by using the command adb shell uiautomator dump /data/local/tmp/uidump.xml
After that, I installed the Appium Studio and try out the Appium official "Inspector" and the result was:
Appium Studio Object Spy with full access to all display elements. Very intriguim... after some research I found the following package com.experitest.uiautomator.test (running in background) was immediatelly installed on the device when I clicked on Object Spy feature and I think that is responsible to retrieve all the interface elements.
On comment link (logcat) Some logcat logs after doind object spy on Appium Studio:
Analysing the logcat we can see that Appium studios was requesting
{"response":"true","params":[],"command":"richDump"} and the package uses
some kind of node:android.view.accessibility.AccessibilityNode. Maybe using something like the Acessibility Tree node to get the elements ? I don't know...
I have read some similar questions on Stackoverflow but some solutions involves to root the device or using de ADB (its not an option),
Tryng to su root the device and chmod 777 /data/local/tmp, but if it's really necessary, how then Appium Studio can read all display elements?
Do you know any other solution that allows me to get all interface elements without root the device? How can I call the "richDump"?
Thank You for you help.

java.lang.SecurityException: adb clearing user data is forbidden.'; Code: '1'

I'm hitting this error:
java.lang.SecurityException: adb clearing user data is forbidden.'; Code: '1'
while running the below mentioned code on appium server in android 8.1.0 (oreo) but the same code is running fine in android 5.1 (lollipop). USB debugging is already on in mobile. Anyone having any idea why I'm hitting this error?`
package appium;
#BeforeTest
public void setcapbilities() throws Exception
{
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability("deviceName","Vipul");
cap.setCapability(CapabilityType.VERSION,"8.1");
cap.setCapability("platformName","Android");
cap.setCapability("appPackage","com.android.calculator2");
cap.setCapability("appActivity","com.android.calculator2.Calculator");
driver = new RemoteWebDriver(new URL("http://127.0.0.1:4723/wd/hub"),cap);
driver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);
}
#Test
public void firstt()
{
driver.findElement(By.xpath("//android.widget.Button")).click();
driver.findElement(By.xpath("7")).click();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
}
#AfterTest
public void kill()
{
driver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);
driver.quit();
}
There few pointers which you can try to solve the issue you're facing.
First, use latest stable Appium server and Java client available.
Second, use AndroidDriver <MobileElement> instead of RemoteWebDriver. Since, AndroidDriver extends RemoteWebDriver via AppiumDriver, it must have overiden the quit method functionality.
Third, you don't need to call implicit wait everywhere. You must call it once in your set up method.
Forth, update your Android SDK and tools to latest.
It is not neccessary that if a something works in andorid v5 , then it should also work on android v8
Reason
To make the devices more secure , latest android versions are imposing restrictions on some already working APIs.
e.g. You can enable airplane mode using Appium API in mobile devices till Android V6, from Android V7 onwards this API has been blocked.
Solution
looking at your code, it seems ,the session should get created successfully , the only thing u need to take care is how to make your test successfull. May be you need to change your Xpath as per the UI for Android V8.
did you try checking this Xpath in APPIUM Desktop ?
https://automationlab0000.wordpress.com/2018/12/31/appium-desktop-for-locating-elements/

Appium, running two phones at once for user and agent

I have a situation where I need to run one browser as a client and another browser as an agent. On desktop this is easy and we use the browser of choice for the user and phantom for the agent.
Using Appium and running on the Android emulator I am having problems trying to replicate the desktop setup. I first tried to have the computer run the phantom and then run the Appium tests but I was getting told by Appium that it didn't recognize phantom. I couldn't find a way to have phantom run on the desktop while still using Appium for the phone.
Next I thought I would just automate the agent side directly in Chrome on the phone to avoid the split between desktop and phone. However, I still ran into problems as I can't seem to create new tabs in Chrome to switch to and even with running two different phones I can't switch between them.
We decided to use RobotFramework and AppiumLibrary to code this due to readability for possible end users of this automation.
These are the first keywords run:
*** Keywords ***
Specifying a Known Mobile Device
API Login regression password
sleep 10
Agent Login
Open Application http://localhost:4723/wd/hub platformName=Android browserName=Chrome platformVersion=7.1.1 deviceName=Nexus6P app=com.android.chrome automationName=appium appPackage=com.android.browser appActivity=com.google.android.apps.chrome.Main
go to url blahblah.com
Check Availability Regression Flow HSSMobile
API login and Agent login are:
API Login
[Arguments] ${UN} ${PW}
Set Global Variable ${ACCOUNTNAME} ${UN}
Set Global Variable ${ACCOUNTPWD} ${PW}
Open Application http://localhost:4725/wd/hub platformName=Android browserName=Chrome platformVersion=7.1.1 deviceName=Pixel app=com.android.chrome automationName=appium appPackage=com.android.browser appActivity=com.google.android.apps.chrome.Main
go to url blahblahapi.com
Agent Login
MobileLibrary.Wait Until Element Is Visible ${USERNAME} 25
MobileLibrary.Input Text ${USERNAME} ${ACCOUNTNAME}
MobileLibrary.Input Text ${PASSWORD} ${ACCOUNTPWD}
MobileLibrary.Click Element ${LOGIN}
I imagine I am doing something wrong in the Open Application keyword but I'm not sure. I am running two instances of Appium in the command line.
appium
and
appium -p 4725
Yet, everything runs on only one of the phones.

Can I run Appium for mobile with no target app?

Since I'm working in a platform which works with many apps (rather than a single target app), I find the selection of a target app inefficient for my needs. I wondered if I could do something to avoid it.
I'd like to run freely, sending UI commands to iOS and Android real devices, including installing an app from another app (like Play Store, Apple Store, Test Flight, etc.)
Thanks for the help,
David.
The rule is: 1 Webdriver instance per application.
You can run Appium's server with no --app argument by making sure auto-launch is set to false, and not setting bundleId or app.
Then, in your client/test framework, you use several webdrivers, configured to use different desired capabilities, to tie it all together under a single test case/suite.
The solution:
You may have a test suite that sets desired_capabilities to launch the Safari app, then you install the app, then you quit the webdriver.
Then you change the desired_capabilities to point to the bundle_id of the new app, launch another webdriver instance, do your tests, quit the webdriver..
Then you change the desired_capabilities to point to (etc., etc.)
driver = webdriver.new(url, desired_capabilities)
// do some stuff
driver.quit()
desired_capabilities['app'] = 'company.app.com'
driver = webdriver.new(url, desired_capabilities)
// do some stuff
driver.quit()
desired_capabilities['app'] = '/path/to/application.app'
driver = webdriver.new(url, desired_capabilities)
// do some stuff
driver.quit()

How to take screenshot using remote android webdriver in real device

hi iam using andriod driver to test my product in mobile.i want to
take snapshot of tests running in real device .is there any solutions?
I believe AndroidDriver extends RemoteWebDriver. RemoteWebDriver does not implement TakeScreenshot interface. Therefore you need to use augmenter like below. I never tried this on Android device but am thinking this should technically work.
driver = new AndroidDriver();
driver = (new Augmenter()).augment(driver);
File temp = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(temp, new File("C:\\my\\picture\\test.png"));
Edit#1
I checked that AndroidDriver implementes TakeScreenshot interface here. That means you don't need to augment the driver.

Categories

Resources