DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Emulating the History Command Within a Bash Script
  • Git Bash (Or Git in Bash)?
  • SonarQube Analysis With Ginkgo on Mac
  • JGit Library Examples in Java

Trending

  • Integrating Security as Code: A Necessity for DevSecOps
  • Unlocking the Potential of Apache Iceberg: A Comprehensive Analysis
  • Beyond ChatGPT, AI Reasoning 2.0: Engineering AI Models With Human-Like Reasoning
  • Start Coding With Google Cloud Workstations
  1. DZone
  2. Coding
  3. Languages
  4. Develop ADB Shell Commands Library Appium C#

Develop ADB Shell Commands Library Appium C#

Check out this post on developing ADB Shell commands using Appium and C#.

By 
Anton Angelov user avatar
Anton Angelov
·
Aug. 29, 19 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
8.5K Views

Join the DZone community and get the full member experience.

Join For Free

In the last article from the Appium Series, we looked into a long list of useful ADB commands that you can use to control Android devices through CMD. In this article, we will continue the subject by looking at how you can add additional functionality to Appium Driverif something is not implemented natively.

What Is ADB?

ADB, or Android Debug Bridge, is a command-line utility included with Google's Android SDK. ADB can control your device over USB from a computer, copy files back and forth, install and uninstall apps, run shell commands, and more.

How to Execute ADB Shell Commands Via Appium

I read about this possibility for the first time in this AppiumPro article,which was originally written in Java but I decided to play around with it and try it in C#.

Note: Keep in mind that I found that this functionality is not very stable lately and sometimes is not working at all in the latest version of the C# bindings. I hope that the Appium maintainers will stabilize it soon.

First, you need to start Appium in relax security mode. Since Appium 1.7.2, there is a flag called  --relaxed-security, which you can call while starting the Appium server.

Start Appium Desktop in Relaxed Security

First, you need to start Appium Desktop as Administrator. Next, click on the Advanced tab and check Relaxed Security.

Appium Desktop Relaxed Security

Start Appium Server in Relaxed Security CLI

1. Download and install the Node and NPM tool.

2. InstallAppium through the command line

npm install -g appium

3. StartAppium Server

appium --relaxed-security

Start Appium Server in Relaxed Security C# Code

You can start the Appium Server directly from your C# code. You can use the below snippet.

[TestClass]
public class AppiumTests
{
    private static AndroidDriver<AndroidElement> _driver;
    private static AppiumLocalService _appiumLocalService;
    [ClassInitialize]
    public static void ClassInitialize(TestContext context)
    {
        var args = new OptionCollector()
            .AddArguments(GeneralOptionList.PreLaunch())
            .AddArguments(new KeyValuePair<string, string>("--relaxed-security", string.Empty));
        _appiumLocalService = new AppiumServiceBuilder().WithArguments(args).UsingAnyFreePort().Build();
        _appiumLocalService.Start();
        string testAppPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "ApiDemos-debug.apk");
        var appiumOptions = new AppiumOptions();
        appiumOptions.AddAdditionalCapability(MobileCapabilityType.AutomationName, "UiAutomator2");
        appiumOptions.AddAdditionalCapability(MobileCapabilityType.DeviceName, "android25-test");
        appiumOptions.AddAdditionalCapability(AndroidMobileCapabilityType.AppPackage, "com.example.android.apis");
        appiumOptions.AddAdditionalCapability(MobileCapabilityType.PlatformName, "Android");
        appiumOptions.AddAdditionalCapability(MobileCapabilityType.PlatformVersion, "7.1");
        appiumOptions.AddAdditionalCapability(AndroidMobileCapabilityType.AppActivity, ".ApiDemos");
        appiumOptions.AddAdditionalCapability(MobileCapabilityType.App, testAppPath);
        _driver = new AndroidDriver<AndroidElement>(_appiumLocalService, appiumOptions);
        _driver.CloseApp();
    }
    [TestInitialize]
    public void TestInitialize()
    {
        _driver?.LaunchApp();
        _driver?.StartActivity("com.example.android.apis", ".ApiDemos");
    }
    [TestCleanup]
    public void TestCleanup()
    {
        _driver?.CloseApp();
    }
    [ClassCleanup]
    public static void ClassCleanup()
    {
        _appiumLocalService.Dispose();
    }
    // tests...
}


The most important part is where we supply the KeyValuePair for the relaxed security flag.

var args = new OptionCollector()
.AddArguments(GeneralOptionList.PreLaunch())
.AddArguments(new KeyValuePair<string, string>("--relaxed-security", string.Empty));
_appiumLocalService = new AppiumServiceBuilder().WithArguments(args).UsingAnyFreePort().Build();
_appiumLocalService.Start();


Use ExecuteScript to Run Shell ADB Commands

Appium maintainers created a 'backdoor' for us for running ADB shell commands through the ExecuteScript method. We need to run it with a first argument equal to mobile: shell and the second one in JSON format, which contains the information about the actual shell ADB command.

If we want to execute the following command: adb shell dumpsys battery reset (which resets the state of the battery), we need to provide a JSON in the following format: {"command": "dumpsys", "args": ["battery", "reset"]}. So, we need to provide the actual command, and the rest of the parameters are passed as the JSON array args.

[TestMethod]
public void PerformRandomShellCommandAsJson()
{
string result = _driver.ExecuteScript("mobile: shell", "{"command": "dumpsys", "args": ["battery", "reset"]}").ToString();
Debug.WriteLine(result);
}


Develop ADB Android Appium Driver Library

Using pure JSON in C# is pretty unreadable. We are smart and can use the .NET serialization libraries to make our code prettier. For the job, first, we create a new class called AdbCommand.

public class AdbCommand {
 public AdbCommand(string command) {
  Command = command;
  Args = new List < string > ();
 }
 public AdbCommand(string command, params string[] args) {
   Command = command;
   Args = new List < string > (args);
  }
  [JsonProperty("command")]
 public string Command {
  get;
  set;
 }
 [JsonProperty("args")]
 public List < string > Args {
  get;
  set;
 }
 public override string ToString() {
  return JsonConvert.SerializeObject(this);
 }
}


Also, I installed an additional C# library called Newtonsoft.Json, which simplifies the JSON serialization and deserialization. We use the JsonProperty attributes to tell the library how to name these properties in the result JSON. Also, we override the ToString method, and there, we return the whole object as JSON through Newtonsoft.Json SerializeObject method.

Here is how looks the same code through the usage of the new class.

[TestMethod]
public void PerformRandomShellCommand()
{
string result = _driver.ExecuteScript("mobile: shell", new AdbCommand("dumpsys", "battery", "reset").ToString()).ToString();
Debug.WriteLine(result);
}


Create Appium Driver ADB Extension Methods

To reuse some code and make the usage of the new methods much easier, we can create extension methods to the AndroidDriver.

public static class AppiumDriverAbdExtensionMethods {
 public static string GetLogs(this AndroidDriver < AndroidElement > androidDriver) {
  return ExecuteShellAdbCommand(androidDriver, "logcat");;
 }
 public static void ChangeBatteryLevel(this AndroidDriver < AndroidElement > androidDriver, int level) {
  ExecuteShellAdbCommand(androidDriver, $ "dumpsys battery set level {level}");
 }
 public static void ChangeBatteryReset(this AndroidDriver < AndroidElement > androidDriver) {
  ExecuteShellAdbCommand(androidDriver, "adb shell dumpsys battery reset");
 }
 public static string GetBatteryStatus(this AndroidDriver < AndroidElement > androidDriver) {
  return ExecuteShellAdbCommand(androidDriver, "adb shell dumpsys battery");;
 }
 private static string ExecuteShellAdbCommand(AndroidDriver < AndroidElement > androidDriver, string command, params string[] args) {
  return androidDriver.ExecuteScript("mobile: shell", new AdbCommand(command, args).ToString()).ToString();
 }
}


Here is how we use the new API.

[TestMethod]
public void PerformShellCommandViaExtensionMethod()
{
    _driver.ResetBattery();
}


Command (computing) shell csharp Library

Published at DZone with permission of Anton Angelov, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Emulating the History Command Within a Bash Script
  • Git Bash (Or Git in Bash)?
  • SonarQube Analysis With Ginkgo on Mac
  • JGit Library Examples in Java

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!