Skip to content

implement driver options #1319

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

Closed
wants to merge 22 commits into from

Conversation

titusfortner
Copy link
Contributor

@titusfortner titusfortner commented Mar 29, 2020

Change list

  • Added IOSMobileOptions and AndroidMobileOptions for easier capability generation

Types of changes

What types of changes are you proposing/introducing to Java client?

  • No changes in production code.
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Details

This is to follow the same approach that Selenium Java bindings have taken with their Browser Options classes. Since DesiredCapabilities will soon be deprecated, users will either need to update to MutableCapabilities or otherwise use an Options class like this. An Options class has the advantage of encapsulating specific behaviors to IOS and Android.

Note that this is a draft to get feedback before I implement all of the IOS & Android specific capabilities.

Honestly, this would be a lot less time consuming if we do some reflection magic with Java 9, but I don't think Appium is at the point where it is willing to require > 8?

@titusfortner
Copy link
Contributor Author

So overall this approach is good?

I'm ok to go through & add docstrings to MobileOptions and setters/getters/tests/docstrings for AndroidMobileOptions & IOSMobileOptions and the PR will be accepted?

@mykola-mokhnach
Copy link
Contributor

So overall this approach is good?

Like I said I'm more into immutable data structures, but if Selenium is already doing it this way then there is no point for us not to follow it and provide different experience to users.

@SrinivasanTarget Please share your thoughts on the feature

@SrinivasanTarget
Copy link
Member

Approach looks fine to me in terms of giving same experience as of Selenium.

@titusfortner titusfortner force-pushed the options_classes branch 3 times, most recently from 0661be1 to 5e8de63 Compare March 30, 2020 16:41
@titusfortner
Copy link
Contributor Author

All the tests are passing finally. Once I figure out what this is actually supposed to be: appium/appium#14133 I'll do a rebase to tidy up the commits.

*/
public Duration getAdbExecTimeout() {
Object duration = getCapability(AndroidMobileCapabilityType.ADB_EXEC_TIMEOUT);
if (duration.getClass().isAssignableFrom(Long.class)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return Duration.ofMillis(Long.valueOf("" + duration));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same below.
Also, this could be extracted to a helper method to avoid unnecessary duplication

* @see AndroidMobileCapabilityType#ALLOW_TEST_PACKAGES
*/
public boolean doesAllowTestPackages() {
return (boolean) getCapability(AndroidMobileCapabilityType.ALLOW_TEST_PACKAGES);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above we return Integer (object type) for a number value, but here we do boolean (primitive type). I assume we should follow the common pattern everywhere and return either all primitive (in such case NPE will be thrown if the corresponding value is null) or object types

* @return this MobileOptions, for chaining.
* @see AndroidMobileCapabilityType#ANDROID_DEVICE_READY_TIMEOUT
*/
public AndroidMobileOptions setAndroidDeviceReadyTimeout(Duration duration) {
Copy link
Contributor

@mykola-mokhnach mykola-mokhnach Apr 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this cap is not used anywhere in appium code: https://github.com/search?q=org%3Aappium+androidDeviceReadyTimeout&type=Code

* @return this MobileOptions, for chaining.
* @see AndroidMobileCapabilityType#ADB_PORT
*/
public AndroidMobileOptions setAdbPort(Integer port) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int port. It makes no sense to allow setting it to null

* @see AndroidMobileCapabilityType#ANDROID_DEVICE_READY_TIMEOUT
*/
public Duration getAndroidDeviceReadyTimeout() {
Object duration = getCapability(AndroidMobileCapabilityType.ANDROID_DEVICE_READY_TIMEOUT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

* @return this MobileOptions, for chaining.
* @see AndroidMobileCapabilityType#ANDROID_INSTALL_PATH
*/
public AndroidMobileOptions setAndroidInstallPath(String path) {
Copy link
Contributor

@mykola-mokhnach mykola-mokhnach Apr 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* @return this MobileOptions, for chaining.
* @see AndroidMobileCapabilityType#ANDROID_NATURAL_ORIENTATION
*/
public AndroidMobileOptions setAndroidNaturalOrientation() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this capability only works for the obsolete UIAutomator1 automation backend

* @return this MobileOptions, for chaining.
* @see AndroidMobileCapabilityType#ANDROID_SCREENSHOT_PATH
*/
public AndroidMobileOptions setAndroidScreenshotPath(String path) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this capability only works for the obsolete UIAutomator1 automation backend

* @return this MobileOptions, for chaining.
* @see AndroidMobileCapabilityType#APP_ACTIVITY
*/
public AndroidMobileOptions setAppActivity(String activity) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to add a link to the documentation, because users quite often have difficulties understanding what activity name concept is: https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/android/activity-startup.md

* @return this MobileOptions, for chaining.
* @see AndroidMobileCapabilityType#APP_PACKAGE
*/
public AndroidMobileOptions setAppPackage(String pkg) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️ same as for activity name

* @return this MobileOptions, for chaining.
* @see AndroidMobileCapabilityType#APP_WAIT_ACTIVITY
*/
public AndroidMobileOptions setAppWaitActivity(String activity) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

* @return this MobileOptions, for chaining.
* @see AndroidMobileCapabilityType#APP_WAIT_DURATION
*/
public AndroidMobileOptions setAppWaitDuration(Duration duration) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

* @see AndroidMobileCapabilityType#APP_WAIT_DURATION
*/
public Duration getAppWaitDuration() {
Object duration = getCapability(AndroidMobileCapabilityType.APP_WAIT_DURATION);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

/**
* Set the Timeout used to wait for the appWaitActivity to launch.
*
* @param duration is the number of milliseconds to wait for the appWaitActivity to launch.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be unit-agnostic now

* @see AndroidMobileCapabilityType#AUTO_WEBVIEW_TIMEOUT
*/
public Duration getAutoWebviewTimeout() {
Object duration = getCapability(AndroidMobileCapabilityType.AUTO_WEBVIEW_TIMEOUT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

* @see AndroidMobileCapabilityType#AVD_LAUNCH_TIMEOUT
*/
public Duration getAvdLaunchTimeout() {
Object duration = getCapability(AndroidMobileCapabilityType.AVD_LAUNCH_TIMEOUT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

/**
* Set the wait time for an avd to finish its boot animations.
*
* @param duration is the number of milliseconds to wait for an avd to finish its boot animations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

* @see AndroidMobileCapabilityType#AVD_READY_TIMEOUT
*/
public Duration getAvdReadyTimeout() {
Object duration = getCapability(AndroidMobileCapabilityType.AVD_READY_TIMEOUT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

}

/**
* Get the path to webdriver executable.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


/**
* Set the directory to look for Chromedriver executables in, for automatic discovery of compatible Chromedrivers.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

* @return ChromeOptions set for use with ChromeDriver.
* @see AndroidMobileCapabilityType#CHROME_OPTIONS
*/
public Object getChromeOptions() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why Object?

/**
* Set the timeout for device to become ready.
*
* @param duration is the number of seconds to wait for the device to become ready.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

* @see AndroidMobileCapabilityType#DEVICE_READY_TIMEOUT
*/
public Duration getDeviceReadyTimeout() {
Object duration = getCapability(AndroidMobileCapabilityType.DEVICE_READY_TIMEOUT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️

@mykola-mokhnach
Copy link
Contributor

@titusfortner I think it makes sense to split this PR into smaller parts, for example:

  • basic classes implementation without concrete caps
  • android caps
  • ios caps
    ...

Then it would be much easier to review it

@titusfortner
Copy link
Contributor Author

@mykola-mokhnach thanks for your painstaking reviews of this; closing to open a new PR.

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

Successfully merging this pull request may close these issues.

3 participants