Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS/Android driver compatibility issue on a cross-platform testing #405

Closed
sbjymc opened this issue Jun 7, 2016 · 18 comments
Closed

iOS/Android driver compatibility issue on a cross-platform testing #405

sbjymc opened this issue Jun 7, 2016 · 18 comments

Comments

@sbjymc
Copy link

sbjymc commented Jun 7, 2016

Description

I'm using java-client 2.10 in my appium test framework, it's working good on my environment both for ios and android native application testing, I can reuse almost all the basic method like below:

public static AppiumDriver driver;

public static void setUp() {
if (PLATFORM_NAME.equals("ios")){
driver = new IOSDriver(new URL(DRIVER_AGENT),capabilities);
}
if (PLATFORM_NAME.equals("android")){
driver = new AndroidDriver(new URL(DRIVER_AGENT),capabilities);
}
}

Then I can create some common method likes 'click a object name' for both ios and android

public static void clickObjectByName(final String ObjectName) {
driver.findElementByName(ObjectName).click();
}

However, the driver is not working when I upgraded Java-client to 3.4.0
it request to create separately 'AndDriver' and 'iOSDRIVER' instance, it means that the common methods which I setup in above example could not be reuse again, and I need to setup 2 different test framework for ios and android.

So I think current Java-Client is not friendly for the cross-platform compatibility. can we make some updates?

And I found several people have the same query, here is the link:
https://discuss.appium.io/t/ios-android-driver-casting-on-a-shared-test-code-base/1095

@SrinivasanTarget
Copy link
Member

@sbjymc I see above link is broken. I recommend to go through our Release log (both client and server) and sync up with the releases every time we update.Since you are using old version of java-client doesn't mean java-client is not user friendly for cross platform compatibility.There are lot more wonderful features/fixes we released there after.

Try to go through our wiki and the change logs.Incase of any questions please raise in discuss.appium.io. Please do raise issues incase if any along with server logs inform of gist to look further.Happy to help if the issue template is followed properly.

@TikhomirovSergey
Copy link
Contributor

There a lot of changes have been added since 2.1.0. It is possible that new releases are not compatible with code that uses very old versions.

Please follow the @SrinivasanTarget's advice.

@TikhomirovSergey
Copy link
Contributor

TikhomirovSergey commented Jun 7, 2016

But we can solve each one separated problem. You can open an issue for each one problem that you face and a bug is suspected.

@sbjymc
Copy link
Author

sbjymc commented Jun 8, 2016

@SrinivasanTarget @TikhomirovSergey
Thanks for your comments, I agree that there are a lot of changes have been added after 2.1.0, and these changes have a lot of wonderful features for ios and android. So I try to upgrade my Java client.

However, We could not share test code(librarys) between iOS and Android using one driver and this seems to make our framework more complex. we have to setup 2 projects for ios and android since we need to initialize 2 different driver for them.
I searched the solutions on appium discuss forum, but there is nothing...
And It would be great if Java-client developer could share a sample code for cross-platform in one framework which could shard the method using the iOS/android driver.

PS: the link I paste could be opened by copy/paste directly in browser.

Thanks for your kindly help.

@rompic
Copy link
Contributor

rompic commented Jun 8, 2016

i think you should look into
#267

to get the most out of the cross platform capabilities
also look into #240 to start the appium server programmatically

@rompic
Copy link
Contributor

rompic commented Jun 8, 2016

I use something like:

AppiumServiceBuilder serviceBuilder = new AppiumServiceBuilder().usingAnyFreePort();
service=AppiumDriverLocalService.buildService(serviceBuilder);
service.start();
driver = (isTargetAndroid()) ? getAndroidDriver(service.getUrl(), false, false) : getIOSDriver(service.getUrl(), false, false);

where isTargetAndroid() is a private method in my code which returns whether the script was started with android or ios as target.
the getAndroidDriver and getIOSDriver start the relevant driver.

    public static AppiumDriver getAndroidDriver(URL appiumUrl, boolean fullReset, boolean noReset) {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "**TBD**");
        capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "**TBD**");
        capabilities.setCapability(MobileCapabilityType.APP, appUrl);
        capabilities.setCapability(AndroidMobileCapabilityType.NO_SIGN,true); 
        capabilities.setCapability(AndroidMobileCapabilityType.UNICODE_KEYBOARD,true); //set unicodekeyboard in order to support umlauts 
        capabilities.setCapability(AndroidMobileCapabilityType.RESET_KEYBOARD,true); //reset keyboard after tests
        capabilities.setCapability(AndroidMobileCapabilityType.IGNORE_UNIMPORTANT_VIEWS,true); //speeds up tests, as views that are not important i.e. for accessiblity are not shown on android. Is disabled on demand in tests using driver.ignoreunimporantViews


        //note that setting appPackage and appActivity is not necessary starting from API level 19 (i.e. 4.4) as it is automatically detected
        //should not be necessary anymore, but detected default is omg.abc.SplashActivity which is never shown on certain flavours of the app
        capabilities.setCapability(AndroidMobileCapabilityType.APP_WAIT_ACTIVITY, "omg.abc.android.bdf.MainActivity"); 

        //only on simulator;
        if(simOrEmulator) {
            capabilities.setCapability("language", language);
        }

        if (fullReset) {
            capabilities.setCapability("fullReset", fullReset);
        }
        if (noReset) {
            capabilities.setCapability("noReset", noReset);
        }

        return new AndroidDriver(appiumUrl,capabilities);
    }

    public static AppiumDriver getIOSDriver(URL appiumUrl, boolean fullReset, boolean noReset) {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "9.3");
        capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 6");
        capabilities.setCapability(MobileCapabilityType.APP, appUrl);
        capabilities.setCapability("bundleId", "**TBD**"); //todo set from script

        //only on simulator;
        if(simOrEmulator) {
            capabilities.setCapability("language", language);
        }

        capabilities.setCapability("locationServicesAuthorized", true);
        capabilities.setCapability("locationServicesEnabled", true);
        capabilities.setCapability("autoAcceptAlerts", true);

        if (fullReset) {
            capabilities.setCapability("fullReset", fullReset);
        }
        if (noReset) {
            capabilities.setCapability("noReset", noReset);
        }
        return new IOSDriver(appiumUrl,capabilities);
    }

I then use the driver in all of my tests.

@rompic
Copy link
Contributor

rompic commented Jun 8, 2016

I also think that the find by name locator strategy has been removed lately.

@sbjymc
Copy link
Author

sbjymc commented Jun 8, 2016

@rompic thanks for you kindly help. I have a question in your code:

driver = (isTargetAndroid()) ? getAndroidDriver(service.getUrl(), false, false) : getIOSDriver(service.getUrl(), false, false);

The object 'driver' is created by 'AppiumDriver' or 'IOSDriver' or 'AndroidDriver' ?

@rompic
Copy link
Contributor

rompic commented Jun 8, 2016

driver is a static class variable of the AppiumDriver type

@rompic
Copy link
Contributor

rompic commented Jun 8, 2016

And the instance is created by the relevant method

@sbjymc
Copy link
Author

sbjymc commented Jun 8, 2016

thanks @rompic, I will try it on my codes.

@sbjymc
Copy link
Author

sbjymc commented Jun 8, 2016

hi @rompic
Since the instance is created dynamically by the relevant method, In your code, it still could not get the full features for iOS driver or Android driver, it just inherits the methods from AppiumDriver<MobileElement>, but not AppiumDriver<IOSElement> or AppiumDriver<AndroidElement>
am I right?

@sbjymc
Copy link
Author

sbjymc commented Jun 8, 2016

Update my last comments since some code could not be recognized by web scripts

@rompic
Copy link
Contributor

rompic commented Jun 8, 2016

What do you mean exactly?
The correct findby strategies are automatically selected using the page object pattern.please provide an example that doesn't work. Btw. Discuss.appium.io would be a better place for this discussion...

@rompic
Copy link
Contributor

rompic commented Jun 11, 2016

@sbjymc i guess I see your point now concerning the features of iOS and Android drivers

I have a generic AppiumDriver and create an instance of Android or IOSDriver depending on a system property. Now I cannot access driver.toggleLocationServices() which is only available for android.

@TikhomirovSergey what is the best way to handle this?

@rompic
Copy link
Contributor

rompic commented Jun 12, 2016

    if(driver instanceof AndroidDriver) {
        ((AndroidDriver) driver).toggleLocationServices();
    }

seems to do the trick

@email2vimalraj
Copy link
Contributor

@rompic : We follow the same approach as you suggested. At run time we get an instance of driver and check whether it belongs to AndroidDriver or iOSDriver. If user access any methods specific to iOS while automating on android, we throw an UnsupportedOperationException.

@sbjymc
Copy link
Author

sbjymc commented Jun 15, 2016

Got it, thanks @rompic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants