I am trying to automate android application using appium when I launch the application and try to login the pop up asks me to have access to Contacts by tapping on "Allow". The pop up have a different appPackage and it is not part of the application package.
Locator for the allow button
addLocator(Locators.ALLOW_CONTACTS, "com.android.packageinstaller:id/permission_allow_button");
method to tap on Allow button
Button allowContactsButton() {
return new Button(getLocator(Locators.ALLOW_CONTACTS));
}
public void dismissAllowContact() {
allowContactsButton().tap();
}
The dismiss function does is able to locate the button but does not tap on it
You can turn on autoAcceptAlerts and grant permissions.
desiredCapabilities.setCapability("autoGrantPermissions", "true");
desiredCapabilities.setCapability("autoAcceptAlerts", "true");
For location service you will have to explicity set authorization using following:
desiredCapabilities.setCapability("locationServicesAuthorized", "true");
You can try similar approach for contacts.
Hoping this helps !
Related
I'm using webdriver.io to write a suite of Appium tests for a hybrid Cordova App.
"appium": "^1.10.0",
"wdio-appium-service": "^0.2.3",
"wdio-jasmine-framework": "^0.3.8",
"webdriverio": "^4.14.1",
In one of my tests I am trying to programmatically accept the Location Permissions native modal presented on App launch on top of the WebView.
I can easily do so in iOS using browser.alertAccept() but the latter does not seem to work for Android.
I also tried to switch to the native context to dismiss it but had no luck.
function dismissLocationPermissions() {
if (browser.isAndroid) {
new WebView().switchToContext(0);
browser.pause(2000);
const ANDROID_ACCEPT_ALERT_SELECTOR = "//*[#class='android.widget.Button'][2]";
// OR '*//android.widget.Button[#text="ALLOW"]' ?
$(ANDROID_ACCEPT_ALERT_SELECTOR).click();
WebView().switchToContext(1);
} else {
browser.alertAccept();
}
}
How can I dismiss the native alert on Android using wdio?
There is autoGrantPermissions DesiredCapability, if you set it to true - Appium will automatically determine which permissions are required by your application and grant them to the application during the installation procedure.
The capability is set to false by default so you need to explicitly set it like:
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.NO_RESET, false);
dc.setCapability(AndroidMobileCapabilityType.AUTO_GRANT_PERMISSIONS, true);
driver = new AndroidDriver<>(url, dc);
More information:
Appium Desired Capabilities
Application Setup
The permission dialog is native, so you don't need to switch to the webview to dismiss it.
There is an android id associated with the allow/deny permission button, so you can use that instead of the identifier you have used.
The id for allow button is: com.android.packageinstaller:id/permission_allow_button .
The id for deny button is: com.android.packageinstaller:id/permission_deny_button
From my device owner application, I'd like to create a new user and switch directly to it. For now, I can only create a new user, switch to it but:
it brings me to the keyguard screen, that I need to manually unlock.
then, tells me to setup the newly created user - with firstname, lastname, WIFI settings, and 3 Google usage statistics/reporting options.
I'd like to know if there's a way to programmatically setup the new user and switch directly to it's "session". I'd like to programmatically avoid the "unlock" page et pre-setup the newly created user with name, WIFI settings, but also available apps and security settings.
here's what I do so far :
// init block (in onCreate...)
DevicePolicyManager mDPM = (DevicePolicyManager) this.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName mDeviceAdminRcvr = new ComponentName(this, DeviceAdminRcvr.class);
// in my button "create a new user"
ComponentName profileOwnerComponent = new ComponentName(this, ProfileAdminRcvr.class);
Bundle adminExtras = new Bundle();
UserHandle userHandle = mDPM.createAndInitializeUser(mDeviceAdminRcvr, name, ownerName, profileOwnerComponent, adminExtras);
// TODO : place here missing instructions to provision the user...
mDPM.switchUser(mDeviceAdminRcvr, userHandle);
I couldn't find any documentation on the official Google page about device owner apps or profile apps.
Could anyone help me or point me to useful links ?
As far as I've seen, there is no way to programmatically unlock the screen lock. Even the Smart lock functionnality added in Lollipop will just disable the Key Guard, which means that the "PIN" or "Pattern" will transform into a "Swipe Lock" when a trusted agent unlocks the device. Even in this case, you'll need to manually swipe the screen to unlock the device.
Concerning the second point, it's possible to avoid the "Setup Wizard" proposed the first time you unlock a newly created user. Here's how to do it :
in your ProfileAdminRcvr.java, you'll need to hide the system application called com.google.android.setupwizard. You could do this in the onEnabled() method of your DeviceAdminReceiver's implementation (the one you set for your profile when creating the user).
To complete this, you can disable the "first use hint", by setting the Settings.Secure.SKIP_FIRST_USE_HINTS property.
Here's the code to do it :
public class ProfileOwnerRcvr extends DeviceAdminReceiver {
private DevicePolicyManager mDPM;
private ComponentName mProfileAdminRcvr;
#Override
public void onEnabled(Context context, Intent intent) {
mDPM.setProfileName(mProfileAdminRcvr, "My new user");
// ... setup other things by yourself...
mDPM.setApplicationHidden( mProfileAdminRcvr, "com.google.android.setupwizard", true);
mDPM.setSecureSetting(mProfileAdminRcvr, Settings.Secure.SKIP_FIRST_USE_HINTS, "1");
}
Google updated its demo app to use Android-N preview version, it seems that there will be a flag called DevicePolicyManager.SKIP_SETUP_WIZARD to do part of what you are trying to do (i.e skipping the wizard) in N.
How do I handle alerts in an Android web application using Appium server (1.0.1) and the Android SDK?
The below code is not working on android:
driver.switchTo().accept().alert();
Error message:
> -modal window does not get closed
You need to get the Alert before you try and accept it
This is code from some of the Appium Java Client Tests:
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
alert.accept();
This should work most of the time.
If accept() isn't working, replace the driver.switchTo().alert(); and alert.accept(); with code to find the button and then click it.
If it's not finding the button wrap findElementBy(Method) code in a try/retry block, and then click on it.
The best way is to use the appium inspector. Click on the element and copy the resource-id from it. Use this resource id in findElement(By.id()) method.
For me resource-id: android:id/button1
((AndroidDriver) driver).findElement(By.id("android:id/button1")).click();
This is for Android. For regular use you can use
driver.findElement(By.id("android:id/button1")).click();
Some alerts may be native Android's alerts, not generated by a browser. In this case the following code:
Alert alert = driver.switchTo().alert(); alert.accept();
may throw:
WebDriverException: unknown error: unhandled inspector error: {"code":-32603,"message":"No JavaScript dialog to handle"}
To handle such alert, just switch to the native application context, make required actions, and then switch back to the browser:
AppiumDriver<WebElement> appiumDriver = (AppiumDriver<WebElement>) webDriver;
String currentContext = appiumDriver.getContext();
appiumDriver.context("NATIVE_APP");
// actions within the alert
appiumDriver.findElements(By.xpath(OK_BUTTON_LOCATOR)).click(); // put locator instead of OK_BUTTON_LOCATOR
appiumDriver.context(currentContext);
// continue working
WebElement btn = driver.findElement(By.xpath("//android.widget.Button[#content-desc='OK']"));
TouchAction act = new TouchAction(driver);
act.tap(241,320).perform();
(241,320) these are X & Y c ordinates of alert
This work perfectly for me
Appium comes with a default capability to accept, dismiss alerts
capabilities.SetCapability("autoAcceptAlerts", true);
capabilities.SetCapability("autoDismissAlerts", true);
If the alert display on Ui , taking more time to display when we need to wait ..we can use fluent wait instead of this..
So an updated answer on this is this: an AlertDialog is a system level element, so clicking on accept button you should use:
androidDriver.findElementById("android:id/button1").click()
else for cancel do this:
androidDriver.findElementById("android:id/button2").click()
// first check alert is present or not
public boolean isAlertPresent() {
try {
mobDriver.switchTo().alert();
log.info("ALERT IS PRESENT !! ");
return true;
} catch (Exception e) {
log.info("ALERT IS NOT PRESENT !! ");
return false;
}
}
public void mobileAlertHandle() {
if (isAlertPresent()) {
Alert alert = mobDriver.switchTo().alert();
alert.accept();
}
}
if this does not work then inspect your element and try with id or name
ex: mobDriver.findElementById("android:id/button2").click()
Please use the below code, Add some wait before clicking on OK Button.
After that pass the xpath of you OK Button.
synchronized (driver)
{
driver.wait(2000);
}
driver.context(NATIVE_APP);
driver.findElementByXPath{("//android.widget.Button[#resourceid=
‘android:id/button1’]").click();
I have an android application which lists the system and installed apps of a device.Also launch the selected one on click.It works fine.Now i want to disable listing of following applications.
Task Manager(which shows on long pressing home button)
Settings
These are the names used in Samsung Galaxy devices.I want to get the package name and launcher activity name of the application using for these purpose in Sony Ericson,Google phones,HTC and Samsung devices.
Also i want the package name of applications Camera,Email & Gmail using in these devices.
In short : I want to get the package name of these applications in the specified device because there are many apps can be use for a single purpose.For eg : ,There are many apps which can be use as a Task Manager, also we can change the default task manager and use a custom app for this purpose.So i don,t know which is used in users device.We can find the home launcher applications using Intent and ResolverActivity.Like this is there any way to get list of all applications which can be use as task manager,camera handling applications etc...?
Any help is much appreaciating.
Thanks in Advance
see task manager and settings dont have package name you can disable task manager by using this code
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.d("Focus debug", "Focus changed !");
if(!hasFocus) {
Log.d("Focus debug", "Lost focus !");
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(closeDialog);
}
}
and settings goto by using
startActivityForResult(new Intent(android.provider.Settings.ACTION_SETTINGS), 0);
By using you can disale and enable. By last gmail,Email,camera you search by net and used in your code.
All the Best:)
Go to google play store and install package name viewer(https://play.google.com/store/apps/details?id=com.gijoon.pkgnameviewer&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5naWpvb24ucGtnbmFtZXZpZXdlciJd) you can see package name for each and every application.
I am writing automated testing code (using ActivityInstrumentationTestCase2) to test an app that involves in-app billing version 2 (subscriptions). I need help on figuring out how to programmatically get my testing code to click on the "Accept and Buy" button that appears inside the "Pay with credit card/Secured by Google Wallet" dialog which is supposedly created by some Google SDK code.
I can get the testing code to click on other buttons that are created by my own code/acitivty, usually by accessing the buttons from its parent activity or view, and then call the .performClick() method on the button. But this "Buy" button is not reachable from any activities as far as I know.
It appears this dialog may be created by com.google.android.finsky.activities.IabActivity based on the logcat output. I used an ActivityMonitor watching this activity, but it was never triggered. If you can help either directly, or point me to the relevant Google SDK source code that's responsible for creating the "Pay with credit card" dialog or the source for the com.google.android.finsky.activities.IabActivity class, I'd be very grateful.
Normally you can't instrument Activities outside of your own package.
You'd have to use the UI Automator framework to click the Buy button.
Thanks to Christopher. I managed to use UI Automation to get the effect I want. I had to write a shell script to call my Instrumentation Test first, which brings up the Buy dialog. Then call
adb shell uiautomator runtest to launch the UI automation code to click on the "Buy" button. Not sure how to sync between them so I just use some sleep code to time the click. Here is the UI automation code:
UiDevice dev = getUiDevice();
// wait for buy button to appear
while (true) {
try {
Thread.sleep(2000l);
UiObject okButton = new UiObject(new UiSelector().text("Accept & buy").className("android.widget.Button"));
okButton.click();
break;
} catch (Exception e) {
}
}
dev.waitForIdle();
Using uiautomator, this is the best I got:
device.findObject(new UiSelector().resourceId("com.android.vending:id/continue_button")).click();
Here are suggestion for making Testcase for Button click in android.
You need to make ActivityInstrumentationTestCase2 for your Activity then do following .
Initialize your button in
protected void setUp() throws Exception {
super.setUp();
mainActivity = getActivity();
btnAcceptBuy= (Button) mainActivity.findViewById(R.id.btnaccept_buy);
}
public void testFragmentKeypad(){
AppLog.showLogE("TEST", "Keypad");
TouchUtils.clickView(this, btnAcceptBuy);
}
By this way you can perform click testing of your button in android.
UiAutomation uiAutomation = new UiAutomation(Looper.getMainLooper(), new UiAutomationConnection());
uiAutomation.setOnAccessibilityEventListener(new UiAutomation.OnAccessibilityEventListener() {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == TYPE_WINDOW_STATE_CHANGED) {
if ("com.google.android.finsky".contentEquals(event.getPackageName())) {
if ("com.google.android.finsky.activities.IabActivity".contentEquals(event.getClassName())) {
final List<AccessibilityNodeInfo> accessibilityNodeInfosByViewId = event.getSource().findAccessibilityNodeInfosByViewId("<package name>:id/<control id>"); // find by layout inspector
if (accessibilityNodeInfosByViewId.size() > 0) {
accessibilityNodeInfosByViewId.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
}
}
});
uiAutomation.connect();
//release when exit
uiAutomation.disconnect();