Get appPackage information during the execution

Hi Guys,

The app that I have started working on is having different appPackage name for different environments (QA, staging, prod etc). I want to fetch that information from the apk file (during the execution) and then use the respective appPackage name in all my find element calls (URLs).

Could you please shed some light on how can I achieve it.

Thanks in advance.

Try the getCapabilities() method available in Appium’s drivers. You can then check if the returned Capabilities object contains an “appPackage” key.

1 Like

Thanks for response but for me this returns “null” for appPackage as well as appActivity. Though I am able to get platformName using same approach. Here is what I am trying:

Capabilities cap = driver.getCapabilities();
Map<String, ?> desired = (Map<String, ?>) cap.getCapability(“desired”);
System.out.println(desired.get(“appPackage”));

I think I see two problems here – if I’m wrong, please forgive my misinterpretation

  1. You need to set the appPackage capability when you start Appium. From the description above, you may not be setting that capability – that would describe the return of “null” from capabilities

  2. Get the appPackage for whatever is running on the device at that moment.

In both cases, You can do this with aapt:

% aapt dump badging |grep package:
package: name=’<app_package>’ versionCode=’’ versionName=’<version_name>’

Alternatively, if you just want to get the app package name of a running application, you can do this with calls to adb. You can try using appium-adb (https://github.com/appium/appium-adb), but I found it difficult to use. We created our own adb interface which works because we are only testing locally and not against selenium grids or the like.

To get the app package, you need to run the command ‘adb shell dumpsys window windows’ We specifically look for the two lines which contain either ‘mCurrentFocus’ or ‘mFocusedApp’ because the don’t always agree. Some heuristics are required to decide which one is correct.

I think my question is little confusing (Sorry about that) but I do not want to set the appPackage in the capablities. That was the whole point; I want to fetch that information from the APK file while executing my scripts and then use it in my find element calls as prefix for resource ID.
Actually I was assuming that we can get that information from the APK file but it looks like I can only fetch the capability which I define initially under appium capabilities.

I am aware about |grep package command but that is also a manual task unless I create a bash file (I am on mac) to execute it and then somehow fetch the information from there.

I hope I am more clear now in my question.

Ok, that makes more sense.

Is there a reason you can’t execute a system call to aapt? I’m assuming you know which apk file is being used. Given your description, there’s no reason to fetch this info from the capabilities.

Modify your code for retrieving the appPackage like so:

Capabilities cap = driver.getCapabilities();
Object packageCap = cap.getCapability("appPackage");
String package = packageCap.toString();
System.out.println(package);

Be sure to add null checks as needed (e.g. check packageCap. I wanted to get the point across without making the code too messy)

There is no intermediate “desired” map capability (or at least there shouldn’t be). You can verify this by using a debugger to set a breakpoint right after retrieving the driver’s capabilities, and exploring the values stored in the Capabilities object (or, simply iterate through the available keys in caps and just print out the values).

@afwang

I am trying your code and getting followin error for getCapability:
“The method getCapability(String) is undefined for the type AndroidDriver”

Sorry, that’s a mistake in my sample. You want to replace this:

Object packageCap = driver.getCapability("appPackage");

with this:

Object packageCap = cap.getCapability("appPackage");

I am not familier with aapt (or Android develovpment overall), so if you can provide some steps I would really like to try

Tried it and now getting null pointer. As I thought it works fine for predefined capabilities (in my case platformName)