Sending AndroidDriver commands when using Selenium Grid

Hi,

I am trying to remotely test native Android app using Jenkins and can successfully run other steps using RemoteWebDriver but unable to send AndroidDriver specific commands like

1.driver.findElementByAndroidUIAutomator(“text(“Quick tests”)”).click();
2.driver.pullFolder("/storage/sdcard0/Quick_tests");

I see error on Eclipse which says - The method "The method findElementByAndroidUIAutomator(string) is undefined for the type RemoteWebDriver

Can someone suggest a fix for this please?

Thanks,
Pardha

Hello @pardha ,

The methods that you are trying to use aren’t available for RemoteWebDriver, but in the AndroidDriver one.
Therefore you should cast the calls that you are doing.

RemoteWebDriver driver=new AndroidDriver(url, caps);
((AndroidDriver)driver).findElementByAndroidUIAutomator(“text(“Quick tests”)”).click();

I suggest this way otherwise with each usage of driver instance u need to cast it which may look tedious…

RemoteWebDriver driver=new AndroidDriver(url, caps);
_driver=((AndroidDriver)driver);
_driver.findElementByAndroidUIAutomator(“text(“Quick tests”)”).click();

Hi @sam_viz @amitjaincoer191

Thanks for the responses, i tried changing my script to the below

public class TTS_Test_Test1 {
private RemoteWebDriver driver;
@BeforeTest
public void beforeTest() throws IOException {
FileWriter fileOut = new FileWriter(“C:\Users\parper01\Documents\Appium\logs.txt”);
File appDir = new File(“C:\apk”);
File app = new File(appDir,“TTS(7).apk”);
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME, “”); //Name of mobile web browser to automate. Should be an empty string if automating an app instead.
capabilities.setCapability(“platformName”, “Android”);
capabilities.setCapability(“platformVersion”, “5.0.1”);
//capabilities.setCapability(“deviceName”, “41008e5ce42f81fd”);
capabilities.setCapability(“deviceName”, “41006289e4b2a179”);
capabilities.setCapability(“app”, app.getAbsolutePath());
capabilities.setCapability(“appPackage”, “com.trustonic.tbase.tests.runner”);
capabilities.setCapability(“appActivity”, “com.trustonic.tbase.tests.runner.SplashscreenActivity”);
driver = new RemoteWebDriver(new URL(“http://127.0.0.1:4723/wd/hub”),capabilities);
//driver = (AndroidDriver) new RemoteWebDriver(new URL(“http://127.0.0.1:4723/wd/hub”),capabilities);
}
@Test
public void QuiclTests() throws InterruptedException, MalformedURLException {
Thread.sleep(10000);
WebElement ViewMorebutton = driver.findElementByName(“View More”);
ViewMorebutton.click();
List buttons = driver.findElements(By.className(“android.widget.ImageButton”));
buttons.get(0).click();
Thread.sleep(1000);
DesiredCapabilities capabilities = new DesiredCapabilities();
RemoteWebDriver driver = new AndroidDriver(new URL(“http://127.0.0.1:4723/wd/hub”),capabilities);
((AndroidDriver) driver).findElementByAndroidUIAutomator(“text(“Quick tests”)”).click();
//driver.findElement(By.xpath("//android.widget.TextView[@text=‘Quick tests’]")).click();
WebElement RunTests = driver.findElementByName(“Run All”);
RunTests.click();
Thread.sleep(2000);
Assert.assertEquals((driver.findElementById(“textview_status”)).getText(),“Test Results”);
((AndroidDriver) driver).pullFolder("/storage/sdcard0/trustonic_tests");

}
}

But get the below error on Eclipse

FAILED: QuiclTests
org.openqa.selenium.SessionNotCreatedException: A new session could not be created. (Original error: Requested a new session but one was in progress) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 15 milliseconds

Same error can be seen if i remove below lines from @Test and put them in @BeforeTest

DesiredCapabilities capabilities = new DesiredCapabilities();
RemoteWebDriver driver = new AndroidDriver(new URL(“http://127.0.0.1:4723/wd/hub”),capabilities);

Am i missing something here please?

org.openqa.selenium.SessionNotCreatedException: A new session could not be created. (Original error: Requested a new session but one was in progress) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 15 milliseconds

This error usually comes when already existing appium server session is running to execute commands and it encounter statement like

Any driver = new AndroidDriver(new URL(“http://127.0.0.1:4723/wd/hub”),capabilities);

Same thing happens with u created new duplicate session again in u r @Test method

Solution

1 . Remove these lines from @Test Method.

DesiredCapabilities capabilities = new DesiredCapabilities();
RemoteWebDriver driver = new AndroidDriver(new URL(“http://127.0.0.1:4723/wd/hub”),capabilities);

  1. Add this line in @BeforeTest
    driver = new RemoteWebDriver(new URL(“http://127.0.0.1:4723/wd/hub”),capabilities);
    AndroidDriver _driver=(AndroidDriver)driver;
    in place of
    driver = new RemoteWebDriver(new URL(“http://127.0.0.1:4723/wd/hub”),capabilities);

It should work. Now you have both Handles u can use any…

@amitjaincoer191

Hi Amit, now i see below errors when i make the above suggested changes

FAILED CONFIGURATION: @BeforeTest beforeTest
java.lang.ClassCastException: org.openqa.selenium.remote.RemoteWebDriver cannot be cast to io.appium.java_client.android.AndroidDriver
at TTS_Test.TTS_Test_Remote.beforeTest(TTS_Test_Remote.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:510)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:211)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
at org.testng.TestRunner.beforeRun(TestRunner.java:647)
at org.testng.TestRunner.run(TestRunner.java:615)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:359)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312)
at org.testng.SuiteRunner.run(SuiteRunner.java:261)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1185)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1110)
at org.testng.TestNG.run(TestNG.java:1018)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:112)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:205)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:176)

Hello @pardha,

It’s normal it’s not working, u cannot cast from an RemoteWebDriver object to an AndroidDriver one :wink:

It should be like this:
driver = new AndroidDriver(new URL(“http://127.0.0.1:4723/wd/hub”),capabilities);

This might be a bug at javaclient end or they may take it as a suggestion to improve for allowing the casting.
It’s better to raise it at java client repo.
@pardha What java client version u r using ?
When you say remote does it mean u r device is connected to some remote machine where you want to execute u r script ?

@amitjaincoer191

Below are the version details on my windows

java version "1.8.0_51"
Java™ SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot™ 64-Bit Server VM (build 25.51-b03, mixed mode)

My intention is to trigger the tests periodically without manual interaction and integrating with Jenkins is the option i am going ahead with.So guess i have to use RemoteWebDriver and AndroidDriver at the same time for sending Android specific commands.