Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_schnell
Active Contributor
Business processes are not longer realized exclusively in the SAP GUI for Windows only. More and more, steps are also being taken on other UIs on other devices. In this blog post I describe the possibility how to control native apps and web apps on a virtual Android device with ABAP via PowerShell.

To realize this scenario I use the same approach which I described e.g. here and here. The bridge between the SAP system and the virtual device builds a chain of libraries and applications. It starts with SAPIENs ActiveXPoshV3 library to connect PowerShell from SAP. The PowerShell script, which contains the procedure, is stored as include development object on the SAP backend system. An ABAP report loads this script and executes it. The script uses the Appium client libraries to connect an Appium server which connects a virtual device from Android Studio.

Preparation



Code Preparation


Here a PowerShell script to control the Android calculator app. Store it as include in your SAP system. It is very easy to understand. It loads the client libraries, sets the necessary capabilities like device name, app etc. and do some activities. It adds 6 to 9, multiplies 166 with 9 and writes the result to the screen.
#-Begin-----------------------------------------------------------------

#-Includes------------------------------------------------------------
$Path = "C:\Program Files\Appium"

[Void][System.Reflection.Assembly]::LoadFrom($Path + "\appium-dotnet-driver.dll")
[Void][System.Reflection.Assembly]::LoadFrom($Path + "\Castle.Core.dll")
[Void][System.Reflection.Assembly]::LoadFrom($Path + "\Newtonsoft.Json.dll")
[Void][System.Reflection.Assembly]::LoadFrom($Path + "\WebDriver.dll")
[Void][System.Reflection.Assembly]::LoadFrom($Path + "\WebDriver.Support.dll")


#-Sub Main------------------------------------------------------------
Function Main() {

[OpenQA.Selenium.Remote.DesiredCapabilities]$Capabilities = `
[OpenQA.Selenium.Remote.DesiredCapabilities]::new();
$Capabilities.SetCapability([OpenQA.Selenium.Appium.Enums.MobileCapabilityType]::`
DeviceName, "emulator-5554");
$Capabilities.SetCapability([OpenQA.Selenium.Appium.Enums.MobileCapabilityType]::`
PlatformVersion, "8.1.0");
$Capabilities.SetCapability([OpenQA.Selenium.Appium.Enums.MobileCapabilityType]::`
PlatformName, "Android");
$Capabilities.SetCapability([OpenQA.Selenium.Appium.Enums.AndroidMobileCapabilityType]::`
AppPackage, "com.android.calculator2");
$Capabilities.SetCapability([OpenQA.Selenium.Appium.Enums.AndroidMobileCapabilityType]::`
AppActivity, "com.android.calculator2.Calculator");

[System.Uri]$Uri = [System.Uri]::new("http://127.0.0.1:4723/wd/hub");

$Driver = `
[OpenQA.Selenium.Appium.Android.AndroidDriver[OpenQA.Selenium.Appium.AppiumWebElement]]::`
new($Uri, $Capabilities);
If ($Driver -eq $null) {
Return;
}

$Driver.FindElementById("com.android.calculator2:id/digit_9").Click();
$Driver.FindElementById("com.android.calculator2:id/op_add").Click();
$Driver.FindElementById("com.android.calculator2:id/digit_6").Click();
$Driver.FindElementById("com.android.calculator2:id/eq").Click();
$Result = $Driver.FindElementById("com.android.calculator2:id/result").Text;
Write-Host "Das Ergebnis ist " $Result;

$Driver.FindElementByAccessibilityId("clear").Click();

$Driver.FindElementById("com.android.calculator2:id/digit_1").Click();
$Driver.FindElementById("com.android.calculator2:id/digit_6").Click();
$Driver.FindElementById("com.android.calculator2:id/digit_6").Click();
$Driver.FindElementByAccessibilityId("multiply").Click();
$Driver.FindElementById("com.android.calculator2:id/digit_9").Click();
$Driver.FindElementByAccessibilityId("equals").Click();
$Result = $Driver.FindElementById("com.android.calculator2:id/result").Text;
Write-Host "Das Ergebnis ist " $Result;

$Driver.CloseApp();
$Driver.Quit();
}

#-Main----------------------------------------------------------------
Main

#-End-------------------------------------------------------------------



 

Here a script to control the Chrome browser on Android. Store it as include in your SAP system too. It is also very easy to understand. It does the same as the script above but here we control the browser. We call Google search, type the word Selenium into the field and press enter.
#-Begin-----------------------------------------------------------------

#-Includes------------------------------------------------------------
$Path = "C:\Program Files\Appium"

[Void][System.Reflection.Assembly]::LoadFrom($Path + "\appium-dotnet-driver.dll")
[Void][System.Reflection.Assembly]::LoadFrom($Path + "\Castle.Core.dll")
[Void][System.Reflection.Assembly]::LoadFrom($Path + "\Newtonsoft.Json.dll")
[Void][System.Reflection.Assembly]::LoadFrom($Path + "\WebDriver.dll")
[Void][System.Reflection.Assembly]::LoadFrom($Path + "\WebDriver.Support.dll")


#-Sub Main------------------------------------------------------------
Function Main() {

[OpenQA.Selenium.Remote.DesiredCapabilities]$Capabilities = `
[OpenQA.Selenium.Remote.DesiredCapabilities]::new();
$Capabilities.SetCapability("deviceName", "emulator-5554");
$Capabilities.SetCapability("platformVersion", "8.1.0");
$Capabilities.SetCapability("browserName", "Chrome")
$Capabilities.SetCapability("platformName", "Android");

[System.Uri]$Uri = [System.Uri]::new("http://127.0.0.1:4723/wd/hub");

$Driver = `
[OpenQA.Selenium.Appium.Android.AndroidDriver[OpenQA.Selenium.Appium.AppiumWebElement]]::`
new($Uri, $Capabilities);

If ($Driver -eq $null) {
Return;
}

$Driver.Navigate().GoToUrl("https://www.google.de");
$Driver.FindElementByName("q").SendKeys("Selenium");
$Driver.FindElementByName("q").SendKeys([OpenQA.Selenium.Keys]::Enter);

Start-Sleep -Seconds 5

$Driver.CloseApp();
$Driver.Quit();

}

#-Main----------------------------------------------------------------
Main

#-End-------------------------------------------------------------------


ABAP Code Preparation and Execution


To execute these scripts with the following report you need the class zActiveXPoshV3 from here in your SAP system.This report loads an include z_posh_appium_app, the first script from above and executes it. But before start your Android Studio with a new empty project and a virtual device. And then start your Appium server.



If your infrastructure runs you can execute this report.
"-Begin-----------------------------------------------------------------
REPORT Z_APPIUM.

DATA:
lo_posh TYPE REF TO zactivexposhv3,
lv_pscode TYPE string,
lv_result TYPE string,
lt_result TYPE STANDARD TABLE OF string
.

CREATE OBJECT lo_posh.
CHECK lo_posh->load_lib( ) = lo_posh->mc_true.
CHECK lo_posh->get_is_powershell_installed( ) = lo_posh->mc_true.
CHECK lo_posh->init( iv_load_profiles = lo_posh->mc_false ) = 0.

lo_posh->set_outputmode( lo_posh->mc_outputbuffer ).
lo_posh->set_outputwidth( 132 ).
lo_posh->clear_output( ).

lv_pscode = lo_posh->read_incl_as_string( iv_incl_name = 'Z_POSH_APPIUM_APP' ).

lo_posh->execute( lv_pscode ).
lv_result = lo_posh->get_outputstring( ).
lo_posh->clear_output( ).

lt_result = lo_posh->outputstring_to_table( iv_outputstring = lv_result ).
LOOP AT lt_result INTO lv_result.
WRITE: / lv_result.
ENDLOOP.

lo_posh->free_lib( ).

"-End-------------------------------------------------------------------

 

Here an image of the running report with the script as include in the SE80.



The result is as expected.


Conclusion


As you can see it is possible to control Android devices from SAP. You can do it synchronously and with direct bidirectional communication between the script and the ABAP report, function module or method. So you can use this approach inside test processes e.g. in the context of eCATT. This opens the gate wide for very interesting integration scenarios.
3 Comments