Facing casting issue while working with Automation code shared with Android, iOS and Web platform

Hi everyone,

I’m working on a codebase which will work on all platform(e.g. Android, iOS and The Web, The app has Webview in it).
I’m creating drivers as below

AppiumDriver<MobileElement> appiumDriver = new AndroidDriver<MobileElement>(newURL(""), desiredCapabilities);

AppiumDriver<MobileElement> appiumDriver = new IOSDriver<MobileElement>(newURL(""), desiredCapabilities);

When I reach to a webview page, I switch to the webview context. The issue starts at this point.
There is a Select element , How do find/interact with the element. When I try to cast the element to Select as below


I get “Cannot cast 'io.appium.java_client.android.AndroidElement$$EnhancerByCGLIB$$b598166c' to 'org.openqa.selenium.support.ui.Select'” excetption.

If I change the element to WebView I get “```Can not cast AndroidElement to WebElement”(something like this) and similar issue if I try to Cast AppiumDriver to WebDriver.

I have checked the java client doc and it says here that MobileElement implements the WebElement interface.

Why is this not working and what is the solution for this?

I’m using Appium v1.6.5 and JavaClient v5.0.1.

@SergeyTichomirov @Aleksei @Hassan_Radi @Priyank_Shah @Alex_Bogdanov @wreed

@pr4bh4sh i use:

protected static AppiumDriver driver = null;

driver = new IOSDriver<>(new URL(baseURL + port + minorURL), capabilities);
// or Android
driver = new AndroidDriver<>(new URL(baseURL + port + minorURL), capabilities);

// in page object i have
protected WebDriver driver;

@AndroidFindBy(id = "some_id")
private List<AndroidElement> el;

// or iOS
@iOSXCUITFindBy(id = "some_id")
private List<IOSElement> el;

// or for webviews
@FindBy(name = "some_id")
private List<WebElement> el;

How do you initialize your pages and what version of Java client and Appium Server you are using?
I do this way

PageFactory.initElements(new AppiumFieldDecorator(driver), this);

@pr4bh4sh the same (almost :slight_smile: ):

    public Page(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(new AppiumFieldDecorator(driver, DEFAULT_WAIT_TIME, SECONDS), this);

I tried the way you have suggested. But still getting the casting exception.

@saikrishna321 @SrinivasanSekar any suggestion.

@pr4bh4sh can you add your error text?

@Aleksei This the error I get

java.lang.ClassCastException: io.appium.java_client.android.AndroidElement$$EnhancerByCGLIB$$b598166c cannot be cast to org.openqa.selenium.support.ui.Select

	at pages.PaymentPage.setExpirationMonth(PaymentPage.java:133)
	at com.tw.test.ios.ShoppingTest.test1(ShoppingTest.java:102)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:108)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:661)
	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:869)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1193)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
	at org.testng.TestRunner.privateRun(TestRunner.java:744)
	at org.testng.TestRunner.run(TestRunner.java:602)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:380)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:375)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
	at org.testng.SuiteRunner.run(SuiteRunner.java:289)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1301)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1226)
	at org.testng.TestNG.runSuites(TestNG.java:1144)
	at org.testng.TestNG.run(TestNG.java:1115)
	at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
	at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)

can you check if you are able to cast Mobile element to “Select” element?
let me know if you any other detail.

@pr4bh4sh can you add also problematic code lines?

@pr4bh4sh no matter found it in your fist comment. try:

            ((Select) (WebElement) selectElement).selectByValue("2");

Seems like something is broken from Java Client side, I experimented with these-

  1. Cast Appium Driver to WebDriver
  2. new AndroidDriver(url, caps)

@pr4bh4sh i do not have any problem with your code:

import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.By;

((Select) driver.findElement(By.id("test"))).selectByValue("2");

findElement returns “WebElement”

this code reproduces your error with me:

((Select) ((AndroidElement) driver.findElement(By.id("test")))).selectByValue("2");

now even we try to cast again and no problem now:

((Select)  ((WebElement) ((AndroidElement) driver.findElement(By.id("test"))))).selectByValue("2");

CORRECT your code with (i just misprinted with one “()” in previours example):

((Select) ((WebElement) selectElement)).selectByValue(“2”);

It is Still not working for me, getting the same error. which version of Appium and Java client are you using?
I’ve tried with
JavaClient : tried 5.0.0beta9, 5.0.1, 5.0.2, 5.0.3
Appium sever: 1.6.5

@pr4bh4sh appium does not matter cause problem in code. i am with 5.0.2 now. copy-paster your not working code with error.

Thanks, @Aleksei for all the help.
It seems Something is incorrect in the way I have implemented the framework, but not sure where. I’ll review my code and try to find the issue.