I am unable to automate my tests parallelly in an Android platform with multiple mobile devices.
If I connect 2 devices to my system and provide capabilities like mobile device Name and version, It is executing in the device which is recognized first through ADB.
If try to start the appium servers with different ports,
new AppiumServiceBuilder().usingAnyFreePort() I am getting Null pointer Exception.
[36minfo[39m: Appium REST http interface listener started on 0.0.0.0:2583
[36minfo[39m: [debug] Non-default server args: {"port":2583}
1) How to override session with AppiumServiceBuilder()
2) How to Restrict appium to execute on the device which is provided with capabilities, even 2 or more devices are connected.
My Code:
public class ApiumMain {
public static void main(String[] args) {
new Thread( new Device_Thread( "4897bb00", "6.0.1" ) ).start();
// new Thread( new Device_Thread( "TA64301YVY", "5.0.1" ) ).start();
}
}
public class Device_Thread extends ApiumMain implements Runnable {
public String mobileDeviceName;
public String androidVersion;
public Device_Thread( String mobile, String version ) {
mobileDeviceName = mobile;
androidVersion = version;
}
#Override
public void run() {
String hsotMachineIP = "127.0.0.1";
Integer seleniumProt = 4723; /*Default {"port":4723}*/
String nodeJSExecutable = "C:\\Program Files (x86)\\Appium\\node.exe";
String appiumJS = "C:\\Program Files (x86)\\Appium\\node_modules\\appium\\bin\\appium.js";
Integer nodeJSPort = (int)( Math.random() * 8000 ) + 1000;
startAppium(nodeJSExecutable, nodeJSPort, appiumJS, mobileDeviceName, androidVersion, hsotMachineIP, seleniumProt);
}
public void startAppium(String nodeJSExecutable, int nodeJSPort, String appiumJS,
String mobileDeviceName, String androidVersion, String hsotMachineIP, int seleniumProt ) {
RemoteWebDriver driver = null;
String appURL = "http://www.w3schools.com/";
// http://appium.io/slate/en/master/?java#appium-server-capabilities
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("automationName", "Appium" );
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("platformVersion", androidVersion );
capabilities.setCapability("deviceName", mobileDeviceName );
capabilities.setCapability("app", "chrome");
capabilities.setCapability("browserName", "chrome");
capabilities.setCapability("newCommandTimeout", "0");
// ANDROID ONLY
/*capabilities.setCapability("appActivity", "com.android");
capabilities.setCapability("appPackage", ".ApiumMain");
*/
// Appium servers are nothing but the Node.js server
AppiumDriverLocalService service = AppiumDriverLocalService.buildService(
new AppiumServiceBuilder()
.usingDriverExecutable( new File( nodeJSExecutable ) )
.withAppiumJS( new File( appiumJS ) )
);
service.start();
System.out.println( "Device : " + mobileDeviceName );
try {
String url = String.format("http://%s:%d/wd/hub", hsotMachineIP, seleniumProt);
System.out.println(" Server Address : " + url );
driver = new RemoteWebDriver( new URL( url ), capabilities );
driver.get( appURL );
browserActions( driver, appURL );
}catch (MalformedURLException e) {
e.printStackTrace();
} finally {
driver.quit();
service.stop();
}
}
private void browserActions(RemoteWebDriver driver, String appURL) {
try {
WebElement ele = driver.findElementByXPath("//body/div[4]/div[1]/div[1]/a[1]");
ele.click();
WebElement ele2 = driver.findElementByXPath("//*[#id='topnav']/div[1]/div[1]/a[2]");
ele2.click();
System.in.read();
System.in.read();
} catch (ElementNotVisibleException logMsg){
} catch (IOException e) {
}
}
}
Appium setup for Windows:
Installed Android SDK, Appium [Server & java-client], Add ADT pugin to Eclipse IDE and Selenium-server-standalone
set Environment Variables:
AVA_HOME~C:\Program Files (x86)\Java\jdk1.8.0_66
ANDROID_HOME~D:\Android\sdk
Path~D:\Android\sdk;D:\Android\sdk\platform-tools - ADB Debugger
Running multiple Appium sessions with different Server flags for Parallel Android Tests
Appium is an open-source tool for automating native, mobile web, and hybrid applications on IOS and Android platforms.
Appium client libraries wraps around Selenium client libraries with some extra commands added to controlling mobile devices
Client: The machine on which the WebDriver[HTTP Client] API is being used to communicate with server through commands.
Appium Client implements the "Mobile JSONWP" to extend "JSONWP". The Mobile JSONWP is for automation of native and hybrid mobile applications and JSONWP is for automating web-browser applications.
Commands:Each HTTP request with a method and template defined in this specification represents a single command and therefore each command produces a single HTTP response. Client initiates a session with server using desired capabilities via JSON. Based on the browser session ID and Selenium remoteServerAddress the communication takes place through Http Rest API.
Selenium Source of HTTP Client:
HttpClient.Factory httpClientFactory = new ApacheHttpClient.Factory();
HttpClient client = httpClientFactory.createClient(remoteServerAddress);
HttpRequest httpRequest = commandCodec.encode(command);
HttpResponse httpResponse = client.execute(httpRequest, true);
Response response = responseCodec.decode(httpResponse);
Server: Before starting any mobile tests you must start the servers like RemoteWebDriver & Appium|NodeJS.
AppiumServer - REST API written in Node.js
SeleniumRCServer - The Selenium server receives Selenium commands from your test program using HTTP GET/POST requests, interprets and executes those commands, and reports back the results to your program.
Connect couple of android devices to the system and run below adb shell commands
D:\Yash>adb devices
List of devices attached
TA64301YVY device
4897bb00 device
D:\Yash>adb -s TA64301YVY shell getprop ro.build.version.release
5.1
D:\Yash>adb -s TA64301YVY shell getprop > D:\Yash\cmdOUT.txt
+----------------------------+------------+--------------+
|[net.bt.name]: | [Android] | [Android] |
|[ro.boot.serialno]: | [4897bb00] | [TA64301YVY] |
|[ro.product.brand]: | [samsung] | [motorola] |
|[ro.product.model]: | [SM-G900F] | [XT1052] |
|[ro.build.version.release]: | [6.0.1] | [5.1] |
+----------------------------+------------+--------------+
Q1 - Ans: To override a session with AppiumServiceBuilder use this argument "GeneralServerFlag.SESSION_OVERRIDE". presence of an arguments means "true"
Q2 - Ans: If we are not providing UDID (OR) RemoteAddress then Driver will connect to first device which is detected by ADB. If we want to restrict appium to connect specific named physical device in the list of connected devices use UDID-Unique device identifier.
JAVA Parallel Android Tests to automate mobile web apps [java-client-4.1.1.jar]:
nodeJSExec « [C:\Program Files (x86)\Appium\node.exe]
nodeJSArgs « [C:\Program Files (x86)\Appium\node_modules\appium\bin\appium.js, --port, 1750, --address, 127.0.0.1, --log, D:\Yash\MyAppiumConsole_4897bb00.txt, --chromedriver-port, 7115, --bootstrap-port, 7119, --session-override]
public void startAppium(String nodeJSExecutable, int nodeJSPort, String appiumJS, String mobileDeviceName,
String androidVersion, String hsotMachineIP ) {
RemoteWebDriver driver = null;
String appURL = "http://www.w3schools.com/";
File logFile = new File("D:/Yash/MyAppiumConsole_"+mobileDeviceName+".txt");
File javaConsole = new File("D:/Yash/MyJavaConsole_"+mobileDeviceName+".txt");
systemConsole2File( javaConsole );
/*The hub only reads browserName, version, platform and applicationName.
The other capabilities (deviceName, platformVersion, platformName, ...) are Appium capabilities, not used by the hub.*/
// Proxying straight through to Chromedriver
DesiredCapabilities capabilities = DesiredCapabilities.android();
/* Appium - io.appium.java_client.remote */
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "Appium" );
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, androidVersion );
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, mobileDeviceName );
capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "chrome"); // "Browser"
capabilities.setCapability(MobileCapabilityType.UDID, mobileDeviceName);
/* Selenium - org.openqa.selenium.remote */
capabilities.setCapability(CapabilityType.TAKES_SCREENSHOT, "true");
// Appium servers are nothing but the Node.js server
AppiumDriverLocalService service = AppiumDriverLocalService.buildService(
new AppiumServiceBuilder()
.withAppiumJS( new File( appiumJS ) )
.usingDriverExecutable( new File( nodeJSExecutable ) )
.usingPort( nodeJSPort )
.withIPAddress( hsotMachineIP )
.withArgument(GeneralServerFlag.SESSION_OVERRIDE)
.withArgument(AndroidServerFlag.BOOTSTRAP_PORT_NUMBER, nextFreePort().toString())
.withArgument(AndroidServerFlag.CHROME_DRIVER_PORT, nextFreePort().toString())
.withLogFile(logFile)
);
service.start();
System.out.println(" Appium Server Address [Local]: " + service.getUrl() );
driver = new RemoteWebDriver( service.getUrl(), capabilities );
...
}
public static final int HIGHEST_PORT = 65535;
public static final int LEAST_PORT = 1024;
public static Integer nextFreePort() {
Integer port = (int)( Math.random() * 8000 ) + LEAST_PORT;
while (true) {
try ( ServerSocket endpoint = new ServerSocket(port) ) {
System.out.println("Local Port on which this socket is listening :"+port);
return port;
} catch (IOException e) {
port = ThreadLocalRandom.current().nextInt();
}
}
}
public static void systemConsole2File( File logFile ) {
try ( FileOutputStream fos = new FileOutputStream( logFile );
PrintStream system_console = new PrintStream( fos )
) {
System.setOut( system_console ); // output stream.
System.setErr( system_console ); // error output stream.
} catch (IOException e) {
e.printStackTrace();
}
}
Appium log with endpoints from the node where script is executed:
<?-- APPIUM_NODEJS_LISTENING_PORT = 4723 SERVERS <--port, --callback-port 4723>
Mobile « http://127.0.0.1:4723/wd/hub
Desktop « http://localhost:4444/wd/hub
-->
[36minfo[39m: Appium REST http interface listener started on 127.0.0.1:1750
[36minfo[39m: [debug] Non-default server args:
{
"address":"127.0.0.1",
"port":1750,
"bootstrapPort":7119,
"sessionOverride":true,
"log":"D:\\Yash\\MyConsole_TA64301YVY.txt",
"chromeDriverPort":7115
}
<?-- LIST OF CONNECTED DEVICES [UDID]
Unique device identifier of the connected physical device
To connect specific named device in the list of connected devices use UDID
-->
[36minfo[39m: [debug] Trying to find a connected android device
[36minfo[39m: [debug] Getting connected devices...
[36minfo[39m: [debug] executing cmd: D:\Android\sdk\platform-tools\adb.exe devices
[36minfo[39m: [debug] 2 device(s) connected
[36minfo[39m: Found device TA64301YVY
[36minfo[39m: [debug] Setting device id to TA64301YVY
<?--
BOOTSTRAP = 4724 Socket tcp port to use on device to talk to Appium
« Forwarding system:4724 to device:4724 appium bootstrap to device
-->
[36minfo[39m: [debug] Forwarding system:7119 to device:4724
[36minfo[39m: [debug] executing cmd: D:\Android\sdk\platform-tools\adb.exe -s TA64301YVY forward tcp:7119 tcp:4724
[36minfo[39m: [debug] Pushing appium bootstrap to device...
<?--
Chrome debugger server to connect to, in the form of <hostname/ip:port>
CHROME_DRIVER = 9515 Port upon which ChromeDriver will run
-->
[36minfo[39m: Chromedriver: Spawning chromedriver with: C:\Program Files (x86)\Appium\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe --url-base=wd/hub --port=7115
[36minfo[39m: Chromedriver: [STDOUT] Starting ChromeDriver 2.18.343845 (73dd713ba7fbfb73cbb514e62641d8c96a94682a) on port 7115
APPLICATION URL:
[36minfo[39m: JSONWP Proxy: Proxying [POST /wd/hub/session/SESSION-ID/url] to [POST http://127.0.0.1:7115/wd/hub/session/SESSION-ID/url] with body: {"url":"http://www.w3schools.com/"}
[36minfo[39m: JSONWP Proxy: Got response with status 200: {"sessionId":"SESSION-ID","status":0,"value":null}
WEB ELEMENT:
[36minfo[39m: JSONWP Proxy: Proxying [POST /wd/hub/session/SESSION-ID/element] to [POST http://127.0.0.1:7115/wd/hub/session/SESSION-ID/element] with body: {"using":"xpath","value":"//body/div[4]/div[1]/div[1]/a[1]"}
[36minfo[39m: JSONWP Proxy: Got response with status 200: {"sessionId":"SESSION-ID","status":0,"value":{"ELEMENT":"0.39628730167672455-1"}}
WEB ELEMENT & ACTION:
[36minfo[39m: JSONWP Proxy: Proxying [POST /wd/hub/session/SESSION-ID/element/0.39628730167672455-1/click] to [POST http://127.0.0.1:7115/wd/hub/session/SESSION-ID/element/0.39628730167672455-1/click] with body: {"id":"0.39628730167672455-1"}
[36minfo[39m: JSONWP Proxy: Got response with status 200: {"sessionId":"SESSION-ID","status":0,"value":null}
Related
I'm testing a Windows hybrid application, I'm using the codes below to get contexts but I got an UnsupportedCommandException when I launch it.
Here's my code :
public void initialize() throws MalformedURLException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Windows");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "10");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Max");
capabilities.setCapability("app", "D:\\Users\\Max\\Desktop\\TI\\ti.exe");
driver = new AppiumDriver<>(new URL("http://localhost:4723/wd/hub"), capabilities);
Set<String> contextNames = driver.getContextHandles();
for (String contextName : contextNames) {
System.out.println(contextName);
}
driver.context((String) contextNames.toArray()[1]);
}
Here's the output on the Appium Server:
Appium server screen
It says that the command contexts is not recognized.
I'm using :
Appium Desktop v1.20.2
Appium Java client v7.5.1
WinAppDriver v1.2.1
The first of all, you need to get all contexts. More info in official docs
Here how I implemented it in tests.
In some Page Object files I keep Android contexts.
ANDROID_CONTEXTS = {
'webview': 'WEBVIEW_ru.myapp',
'native': 'NATIVE_APP'
}
In some tests I switch context from Native to Webview.
#allure.link(url='https://jira.project.tech/browse/TEST-1', name='TEST-1 - Fill payment form')
#allure.title('Fill payment form')
def test_card_standard_1_month(appdriver):
Paywall(appdriver).press_one_month_button()
PaymentsPage(appdriver).select_card_payment()
PaymentsPage(appdriver).press_payment_button()
appdriver.switch_to.context(ANDROID_CONTEXTS['webview'])
Payform(appdriver).fill_and_submit_payform()
appdriver.switch_to.context(ANDROID_CONTEXTS['native'])
assert SuccessPayment(appdriver).get_successful_payment_title_text() == 'Your subscription is successful!'
You can check all available contexts in your app. More info here -> http://appium.io/docs/en/commands/context/set-context/
I'm working AppiumDriver setup where based on the number of mobile devices/emulators, which during the setup for each driver will setup a appium server for each driver created. However, when a server is created and initialize the AppiumDriver as either Android or IOS, the server generates an error that it can't connect to the device even though it was able to retrieve the device no problem from cmd: "adb devices", and prints the correct udid. Is there something I'm missing or forgot to include?
Here are the details:
The code (3 different programs I've set up):
public class BaseTest {
protected AppiumDriver<MobileElement> driver;
protected WebDriverWait wait;
//Change to default mobile Layout classes for anything on the screen
public PageObject pageObject = null;
public AppiumDriverSetup createDrivers = new AppiumDriverSetup();
#BeforeClass(alwaysRun=true)
public void setupDrivers() throws IOException {
createDrivers.makeList();
for(AppiumDriver<MobileElement> driver : createDrivers.getActiveList()){
this.driver = driver;
TLDriverFactory.setTLDriver(driver);
wait = new WebDriverWait(TLDriverFactory.getTLDriver(), 10);
}
}
#Test
public void testActivation() {
assertTrue(driver != null);
pageObject = new PageObject(TLDriverFactory.getTLDriver());
driver.get("www.google.com");
}
public class AppiumDriverSetup {
enum Devices {
ANDROID, IOS;
}
public static int deviceNum = 0;
public AppiumDriver<MobileElement> driver;
private List<Object> newDevice = new ArrayList<Object>();
private static List<AppiumDriver<MobileElement>> activeList = Collections.synchronizedList(new ArrayList<AppiumDriver<MobileElement>>());
AppOrBrowser determinePlatType = new AppOrBrowser();
ActiveAppiumPorts activePorts = new ActiveAppiumPorts();
public void makeList () throws IOException {
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("adb devices");
BufferedReader output = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line ="";
while ((line = output.readLine()) != null) {
if(StringUtils.isEmpty(line) || line.startsWith("List of devices attached")) {
continue;
}
System.out.println(line);
String [] serialNum = line.replace(" ", "").split("device");
newDevice.add(Devices.ANDROID);
newDevice.add(serialNum[0]);
driver = setCaps((Devices)newDevice.get(0), (String)newDevice.get(1));
activeList.add(driver);
}
//Implement the IOS Process
}
private AppiumDriver<MobileElement> setCaps(Devices d, String udid) throws MalformedURLException{
AppiumDriver<MobileElement> driver = null;
DesiredCapabilities cap = new DesiredCapabilities();
String deviceName = "device"+ ++deviceNum;
cap.setCapability(MobileCapabilityType.DEVICE_NAME, deviceName);
if(d == Devices.ANDROID) {
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
}
if(d == Devices.IOS) {
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "IOS");
}
cap.setCapability(MobileCapabilityType.UDID, udid);
cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, "4000");
cap.setCapability("noReset", false);
//Help setup which browser or to run on an app.
cap = determinePlatType.determinePlat(cap);
//Generate AppiumPorts Class and retrieve generated port number.
activePorts.generateServer();
System.out.println("Argument to driver object : " + activePorts.getAppiumURL());
switch (d) {
case ANDROID:
driver = new AndroidDriver<MobileElement>(new URL(activePorts.getAppiumURL()), cap);
break;
case IOS:
driver = new IOSDriver<MobileElement>(new URL(activePorts.getAppiumURL()), cap);
break;
}
return driver;
}
public List<AppiumDriver<MobileElement>> getActiveList(){
return activeList;
}
public void tearDown() {
driver.quit();
}
}
public class ActiveAppiumPorts {
private int portNum = 0;
private String appiumPort = "500" + portNum;
private String serverIp = "127.0.0.1";
public String getAppiumURL() {
String serverURL = "http://" + serverIp + ":" + appiumPort + "/wd/hub";
portNum++;
return serverURL;
}
public void generateServer() {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("cmd.exe /c start cmd.exe /k \"appium -a " + serverIp + " -p " + appiumPort +
"--session-override -dc \" {\"\"noReset\"\": \"\"false\"\"}\"\"");
Thread.sleep(10000);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException r) {
r.printStackTrace();
}
}
public void stopServer() {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("taskkill /F /IM node.exe");
runtime.exec("taskkill /F /IM cmd.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
}
The Appium Server logs:
[Appium] Welcome to Appium v1.8.1
[Appium] Non-default server args:
[Appium] address: 127.0.0.1
[Appium] port: 5000
[Appium] defaultCapabilities: {
[Appium] noReset: false
[Appium] }
[Appium] Default capabilities, which will be added to each request unless overridden by desired capabilities:
[Appium] noReset: false
[Appium] Appium REST http interface listener started on 127.0.0.1:5000
[HTTP] --> POST /wd/hub/session
[HTTP] {"desiredCapabilities":{"browserName":"Chrome","deviceName":"device1","newCommandTimeout":"4000","noReset":false,"platformName":"Android","udid":"192.168.174.102:5555\t"},"capabilities":{"desiredCapabilities":{"browserName":"Chrome","deviceName":"device1","newCommandTimeout":"4000","noReset":false,"platformName":"Android","udid":"192.168.174.102:5555\t"},"firstMatch":[{"browserName":"Chrome","platformName":"android"}]}}
[debug] [MJSONWP] Calling AppiumDriver.createSession() with args: [{"browserName":"Chrome","deviceName":"device1","newCommandTimeout":"4000","noReset":false,"platformName":"Android","udid":"192.168.174.102:5555\t"},null,{"desiredCapabilities":{"browserName":"Chrome","deviceName":"device1","newCommandTimeout":"4000","noReset":false,"platformName":"Android","udid":"192.168.174.102:5555\t"},"firstMatch":[{"browserName":"Chrome","platformName":"android"}]}]
[debug] [BaseDriver] Event 'newSessionRequested' logged at 1534263446888 (09:17:26 GMT-0700 (Pacific Daylight Time))
[BaseDriver] The capabilities ["noReset"] are not standard capabilities and should have an extension prefix
[BaseDriver] Boolean capability passed in as string. Functionality may be compromised.
[Appium] Could not parse W3C capabilities: 'deviceName' can't be blank. Falling back to JSONWP protocol.
[Appium] The following capabilities were provided in the JSONWP desired capabilities that are missing in W3C capabilities: ["noReset","browserName","deviceName","newCommandTimeout","platformName","udid"]. Falling back to JSONWP protocol.
[Appium] Creating new AndroidDriver (v2.7.0) session
[Appium] Capabilities:
[Appium] noReset: false
[Appium] browserName: Chrome
[Appium] deviceName: device1
[Appium] newCommandTimeout: 4000
[Appium] platformName: Android
[Appium] udid: 192.168.174.102:5555
[debug] [BaseDriver] Creating session with MJSONWP desired capabilities: {"noReset":false,"browserNa...
[BaseDriver] Capability 'newCommandTimeout' changed from string ('4000') to integer (4000). This may cause unexpected behavior
[BaseDriver] Session created with session id: 9beb9dd1-e6c3-4fa2-9cd6-7fb55d4a820b
[debug] [AndroidDriver] Getting Java version
[AndroidDriver] Java version is: 1.8.0_171
[AndroidDriver] We're going to run a Chrome-based session
[AndroidDriver] Chrome-type package and activity are com.android.chrome and com.google.android.apps.chrome.Main
[ADB] Checking whether adb is present
[ADB] Found 3 'build-tools' folders under 'C:\Users\<username>\AppData\Local\Android\Sdk' (newest first):
[ADB] C:/Users/<username>/AppData/Local/Android/Sdk/build-tools/28.0.0-rc1
[ADB] C:/Users/<username>/AppData/Local/Android/Sdk/build-tools/27.0.3
[ADB] C:/Users/<username>/AppData/Local/Android/Sdk/build-tools/26.0.2
[ADB] Using adb.exe from C:\Users\<username>\AppData\Local\Android\Sdk\platform-tools\adb.exe
[AndroidDriver] Retrieving device list
[debug] [ADB] Trying to find a connected android device
[debug] [ADB] Getting connected devices...
[debug] [ADB] 2 device(s) connected
[AndroidDriver] Error: Device 192.168.174.102:5555 was not in the list of connected devices
[AndroidDriver] at Object.wrappedLogger.errorAndThrow (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\appium-support\lib\logging.js:78:13)
[AndroidDriver] at Object.callee$0$0$ (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\appium-android-driver\lib\android-helpers.js:161:16)
[AndroidDriver] at tryCatch (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:67:40)
[AndroidDriver] at GeneratorFunctionPrototype.invoke [as _invoke] (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:315:22)
[AndroidDriver] at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:100:21)
[AndroidDriver] at GeneratorFunctionPrototype.invoke (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:136:37)
[AndroidDriver] at <anonymous>
[debug] [AndroidDriver] Shutting down Android driver
[debug] [AndroidDriver] Called deleteSession but bootstrap wasn't active
[debug] [BaseDriver] Event 'newSessionStarted' logged at 1534263447383 (09:17:27 GMT-0700 (Pacific Daylight Time))
[MJSONWP] Encountered internal error running command: Error: Device 192.168.174.102:5555 was not in the list of connected devices
[MJSONWP] at Object.wrappedLogger.errorAndThrow (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\appium-support\lib\logging.js:78:13)
[MJSONWP] at Object.callee$0$0$ (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\appium-android-driver\lib\android-helpers.js:161:16)
[MJSONWP] at tryCatch (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:67:40)
[MJSONWP] at GeneratorFunctionPrototype.invoke [as _invoke] (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:315:22)
[MJSONWP] at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:100:21)
[MJSONWP] at GeneratorFunctionPrototype.invoke (C:\Users\<username>\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:136:37)
[MJSONWP] at <anonymous>
[HTTP] <-- POST /wd/hub/session 500 619 ms - 207
The Mvn logs:
[INFO] Running TestSuite
192.168.174.102:5555 device
chrome
Argument to driver object : http://127.0.0.1:5000/wd/hub
[ERROR] Tests run: 2, Failures: 1, Errors: 0, Skipped: 1, Time elapsed:
12.489 s <<< FAILURE! - in TestSuite
[ERROR] setupDrivers(BaseTest.BaseTest) Time elapsed: 12.373 s <<<
FAILURE!
org.openqa.selenium.WebDriverException:
An unknown server-side error occurred while processing the command.
Original error: Device 192.168.174.102:5555 was not in the list of
connected devices (WARNING: The server did not provide any stacktrace
information)
Command duration or timeout: 718 milliseconds
Build info: version: '3.11.0', revision: 'e59cfb3', time: '2018-03-
11T20:26:55.152Z'
System info: host: 'LAPTOP-L1BFDSGL', ip: '192.168.174.2', os.name:
'Windows 10', os.arch: 'x86', os.version: '10.0', java.version:
'1.8.0_181'
Driver info: driver.version: AndroidDriver
at BaseTest.BaseTest.setupDrivers(BaseTest.java:34)
TestNG Report:
org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: Device 192.168.174.102:5555 was not in the list of connected devices (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 718 milliseconds
Build info: version: '3.11.0', revision: 'e59cfb3', time: '2018-03-11T20:26:55.152Z'
System info: host: 'LAPTOP-L1BFDSGL', ip: '192.168.174.2', os.name: 'Windows 10', os.arch: 'x86', os.version: '10.0', java.version: '1.8.0_181'
Driver info: driver.version: AndroidDriver
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:214)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:166)
at org.openqa.selenium.remote.JsonWireProtocolResponse.lambda$new$0(JsonWireProtocolResponse.java:53)
at org.openqa.selenium.remote.JsonWireProtocolResponse.lambda$getResponseFunction$2(JsonWireProtocolResponse.java:91)
at org.openqa.selenium.remote.ProtocolHandshake.lambda$createSession$0(ProtocolHandshake.java:123)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)
at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:126)
at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:73)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:136)
at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:129)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:545)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:42)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:209)
at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:132)
at io.appium.java_client.DefaultGenericMobileDriver.<init>(DefaultGenericMobileDriver.java:38)
at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:84)
at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:94)
at io.appium.java_client.android.AndroidDriver.<init>(AndroidDriver.java:80)
at AppiumDriverSetUp_Lib.AppiumDriverSetup.setCaps(AppiumDriverSetup.java:87)
at AppiumDriverSetUp_Lib.AppiumDriverSetup.makeList(AppiumDriverSetup.java:57)
at BaseTest.BaseTest.setupDrivers(BaseTest.java:34)
... Removed 34 stack frames
What was causing the issue was the issue was the empty space that was added when storing the udid in SerialNum[0]. So when the Appium servers were trying to connect to the devices, the extra space was getting in the way. I edited the udid String value using trim() to remove any extra space:
private AppiumDriver<MobileElement> setCaps(Devices d, String udid) throws MalformedURLException{
AppiumDriver<MobileElement> driver = null;
DesiredCapabilities cap = new DesiredCapabilities();
String deviceName = "device"+ ++deviceNum;
cap.setCapability(MobileCapabilityType.DEVICE_NAME, deviceName);
if(d == Devices.ANDROID) {
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
}
if(d == Devices.IOS) {
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "IOS");
}
cap.setCapability(MobileCapabilityType.UDID, udid.trim());
cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, "4000");
cap.setCapability("noReset", false);
Im trying to start Appium server programmatically from Java
(OS: Windows7 x64)
using first method from source: http://www.automationtestinghub.com/3-ways-to-start-appium-server-from-java/
The code that I use for starting Appium sever is:
public void startServer() {
//Set Capabilities
cap = new DesiredCapabilities();
cap.setCapability("noReset", "false");
//Build the Appium service
builder = new AppiumServiceBuilder();
builder.withIPAddress("127.0.0.1");
builder.usingPort(4723);
builder.withCapabilities(cap);
builder.withArgument(GeneralServerFlag.SESSION_OVERRIDE);
builder.withArgument(GeneralServerFlag.LOG_LEVEL, "error");
//added by myself:
builder.usingDriverExecutable(new File("C:/node/node.exe"));
builder.withAppiumJS(new File("C:/Users/[user]/AppData/Roaming/npm/node_modules/appium/lib/appium.js"));
//Start the server with the builder
service = AppiumDriverLocalService.buildService(builder);
service.start();
}
I'm getting an exception:
Exception in thread "main" io.appium.java_client.service.local.AppiumServerHasNotBeenStartedLocallyException: The local appium server has not been started. The given Node.js executable: C:\node\node.exe Arguments: [C:\Users\Dima\AppData\Roaming\npm\node_modules\appium\lib\appium.js, --port, 4723, --address, 127.0.0.1, --log-level, error, --session-override, --default-capabilities, {\"noReset\": \"false\"}]
Process output: C:\Users[user]\AppData\Roaming\npm\node_modules\appium\lib\appium.js:1
(function (exports, require, module, __filename, __dirname) { import _ from 'lodash'; ^^^^^^
SyntaxError: Unexpected token import
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:616:28)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3
I tried every way to start Appium server from the source, but second one causes to the same, but third causes to error
Any ideas? Thanks to all in advance!
Take a look at official documentation:
https://github.com/appium/java-client/blob/master/docs/The-starting-of-an-app-using-Appium-node-server-started-programmatically.md
Make sure your env setup for Appium is correct and that appium service/client versions are compatible.
It did mistake in code. Fixed method is:
public static String runAppiumService(int appiumPort) {
//Build parameters for appium server:
AppiumServiceBuilder appiumServiceBuilder = new AppiumServiceBuilder();
appiumServiceBuilder.usingPort(appiumPort)
.withIPAddress(APPIUM_IP)
.withAppiumJS(new File(getAppiumJsPath()))
.withArgument(GeneralServerFlag.SESSION_OVERRIDE)
.withLogFile(new File(System.getProperty("user.dir") + "/target/resources/appium_server_logs" + Thread.currentThread().getId()));
AppiumDriverLocalService service = AppiumDriverLocalService.buildService(appiumServiceBuilder);
service.start();
}
public class ServerManager {
AppiumDriverLocalService service;
public static void main(String args[]) {
ServerManager sm = new ServerManager();
sm.startServer();
}
public void startServer() {
final DesiredCapabilities cap = new DesiredCapabilities();
//Set Capabilities
cap.setCapability("noReset", "false");
//Build the Appium service
AppiumServiceBuilder builder = new AppiumServiceBuilder();
builder = new AppiumServiceBuilder();
builder.withIPAddress("127.0.0.1");
builder.usingPort(4723);
builder.withCapabilities(cap);
builder.withArgument(GeneralServerFlag.SESSION_OVERRIDE);
builder.withArgument(GeneralServerFlag.LOG_LEVEL,"error");
//Start the server with the builder
service = AppiumDriverLocalService.buildService(builder);
service = AppiumDriverLocalService.buildService(builder);
service.start();
}
public void stopServer() {
service.stop();
}
}
I have been trying to launch the Appium Server programatically and then based on the Process output, would initialize the Android Driver and run some tests. However, everytime the Appium Server is launched from the program, the execution stalls on the initialization of the Android Driver.
Here is my method for Starting the server:
private boolean StartServer(String strCommand)
{
try
{
rtCommand = Runtime.getRuntime();
proc = rtCommand.exec(strCommand);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
//Checking output of Appium Server Initialization
String s = null;
while ((s = stdInput.readLine()) != null)
{
System.out.println(s);
if (s.contains("Console LogLevel: debug"));
return true;
}
}
catch (Exception ex)
{
System.out.println("Error in starting Appium Server. Stack Trace below:");
ex.printStackTrace();
return false;
}
return false;
}
Now, My TestNG annotation #BeforeClass holds the following code:
#BeforeClass
public void setUp() throws MalformedURLException
{
StartServer("cmd /c \"\"C:/Program Files (x86)/nodejs/node.exe\" \"C:/Program Files (x86)/Appium/node_modules/appium/lib/server/main.js\" --address 127.0.0.1 --port 4723 --platform-name Android --platform-version 23 --automation-name Appium --log-no-color --udid 3100aeb26c6a2363\"");
FrameworkDriver objFrameworkDriver = new FrameworkDriver();
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "ec5bee97");
capabilities.setCapability("BROWSER_NAME", Android");
capabilities.setCapability("VERSION", "5.1.1");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("appPackage", "com.XX.AA");
capabilities.setCapability("appActivity", "com.XX.AA.BB");
strProjectDir = "<MyProjectLoc>";
try
{
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
}
catch (Exception ex)
{
ex.printStackTrace();
}
System.out.println();
}
The execution halted here:
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
Try using something like version 5.1.1, instead of platform-version 23 in your start server command line. (The same version as defined in capabilities in your code)
StartServer("cmd /c \"\"C:/Program Files (x86)/nodejs/node.exe\" \"C:/Program Files (x86)/Appium/node_modules/appium/lib/server/main.js\" --address 127.0.0.1 --port 4723 --platform-name Android --version 5.1.1 --automation-name Appium --log-no-color --udid 3100aeb26c6a2363\"");
Appium wants to the OS version of the Android device instead of the API level
Also, ensure that the device name used while defining capabilities is same as that defined in start server command line.
I just create a sample code as below which is used to launch the calculator apk file and perform some task
#BeforeSuite
public static void driverInitalize() throws Exception {
try {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "Android Emulator");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("platformVersion", "4.2.2");
// capabilities.setCapability("browserName", "Chrome");
capabilities.setCapability("appPackage", "com.android.calculator2");
capabilities.setCapability("appActivity", "com.android.calculator2.Calculator");
capabilities
.setCapability("app",
"C:\\Ecare\\Appium\\com.android.calculator2-5.1-1720659-22-minAPI22.apk");
driver = new RemoteWebDriver(
new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
} catch (Exception ex) {
ex.printStackTrace();
}
}
#Test
public static void sampleTest1() throws Exception {
try {
// System.out.println(driver.getTitle());
driver.findElement(By.xpath(".//*[contains(text(),'7')]")).click();
driver.findElement(By.xpath(".//*[contains(text(),'+')]")).click();
driver.findElement(By.xpath(".//*[contains(text(),'3')]")).click();
driver.findElement(By.xpath(".//*[contains(text(),'=')]")).click();
String value = driver.findElement(
By.className("android.widget.EditText")).getText();
System.out.print(value);
} catch (Exception ex) {
ex.printStackTrace();
}
}
#AfterSuite
public static void tearDown() throws Exception {
try {
driver.quit();
} catch (Exception ex) {
ex.printStackTrace();
}
}
Whenever I executed the above code will return following exception in appium server as well as in eclipse IDE. Can somebody tell me how can I overcome this issue. It seems to be the session is progress but I'm not sure how to kill the progress session which is started earlier. I tried to start up the appium server as appium --no-reset, and checked in the override existing session as well but no luck.
Failure [INSTALL_FAILED_OLDER_SDK]
> at C:\Program Files (x86)\Appium\node_modules\appium\node_modules\appium-adb\lib\adb.js:1358:17
> at [object Object].<anonymous> (C:\Program Files (x86)\Appium\node_modules\appium\node_modules\appium-adb\lib\adb.js:180:9)
> at ChildProcess.exithandler (child_process.js:635:7)
> at ChildProcess.EventEmitter.emit (events.js:98:17)
> at maybeClose (child_process.js:743:16)
> at Process.ChildProcess._handle.onexit (child_process.js:810:5)
> info: [debug] Responding to client with error: {"status":33,"value":{"message":"A new session could not be created. (Original error: Remote install failed: pkg: /data/local/tmp/b23beec2f0794d869eb021f75e3791bd.apk\r\r\nFailure [INSTALL_FAILED_OLDER_SDK])","origValue":"Remote install failed: pkg: /data/local/tmp/b23beec2f0794d869eb021f75e3791bd.apk\r\r\nFailure [INSTALL_FAILED_OLDER_SDK]"},"sessionId":null}
> info: <-- POST /wd/hub/session 500 39088.716 ms - 362
Please help me out.
The error you are getting [INSTALL_FAILED_OLDER_SDK] is caused due to the version of android of your avd/device is older than the version being used to compile the code of the app.
Check the target sdk version and the minimum sdk version of the app.
if you have the access to the source code of the app these information will be in the manifest file in the android:minSdkVersion tag.