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

Repeatable annotations & HasSessionDetails API #497

Merged
merged 12 commits into from
Oct 31, 2016
Merged

Repeatable annotations & HasSessionDetails API #497

merged 12 commits into from
Oct 31, 2016

Conversation

TikhomirovSergey
Copy link
Contributor

@TikhomirovSergey TikhomirovSergey commented Oct 28, 2016

Change list

Migration to Java 8. Repeatable annotations for page objects:

  • Annotations AndroidFindAll, AndroidFindBys, iOSFindAll, iOSFindBys, SelendroidFindAll,
    SelendroidFindBys became deprecated.
  • Annotations AndroidFindBy, iOSFindBy, SelendroidFindBy became repeatable.
  • The new annotation io.appium.java_client.pagefactory.HowToUseLocators was added to help to define the searching strategy (chain or using all possible locators) correctly.

Also were added:

  • The io.appium.java_client.HasSessionDetails interface. It has methods implemented by default. This interface is implemented by AppiumDriver
  • The refactoring of the io.appium.java_client.AppiumFieldDecorator and related supporting tools. Now it uses session data instead of the class of the given driver for the routing between annotations.

Types of changes

  • 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

#399 #454

The old usecase for the chained searching:

import org.openqa.selenium.remote.RemoteWebElement;
import io.appium.java_client.pagefactory.*;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.FindBy;

@FindBys({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBys({@AndroidFindBy(someStrategy1), @AndroidFindBy(someStrategy2)}) 
@iOSFindBys({@iOSFindBy(someStrategy1), @iOSFindBy(someStrategy2)}) 
RemoteWebElement someElement;

@FindBys({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBys({@AndroidFindBy(someStrategy1), @AndroidFindBy(someStrategy2)}) 
@iOSFindBys({@iOSFindBy(someStrategy1), @iOSFindBy(someStrategy2)}) 
List<RemoteWebElement> someElements;

New usecases for the chained searching:

import org.openqa.selenium.remote.RemoteWebElement;
import io.appium.java_client.pagefactory.*;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.FindBy;

@FindBys({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) 
RemoteWebElement someElement;

@FindBys({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)
List<RemoteWebElement> someElements;

or

import org.openqa.selenium.remote.RemoteWebElement;
import io.appium.java_client.pagefactory.*;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.FindBy;

import static io.appium.java_client.pagefactory.LocatorGroupStrategy.CHAIN;

@HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = CHAIN)
@FindBys({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) 
RemoteWebElement someElement;

@HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = CHAIN)
@FindBys({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)
List<RemoteWebElement> someElements;

The old usecase for the searching by all possible locators:

import org.openqa.selenium.remote.RemoteWebElement;
import io.appium.java_client.pagefactory.*;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindByAll;

@FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindAll({@AndroidFindBy(someStrategy1), @AndroidFindBy(someStrategy2)}) 
@iOSFindAll({@iOSFindBy(someStrategy1), @iOSFindBy(someStrategy2)}) 
RemoteWebElement someElement;

@FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindAll({@AndroidFindBy(someStrategy1), @AndroidFindBy(someStrategy2)}) 
@iOSFindAll({@iOSFindBy(someStrategy1), @iOSFindBy(someStrategy2)}) 
List<RemoteWebElement> someElements;

The new usecase for the searching by all possible locators:

import org.openqa.selenium.remote.RemoteWebElement;
import io.appium.java_client.pagefactory.*;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindByAll;

import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE;

@HowToUseLocators(androidAutomation = ALL_POSSIBLE, iOSAutomation = ALL_POSSIBLE)
@FindAll{@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) 
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) 
RemoteWebElement someElement;

@HowToUseLocators(androidAutomation = ALL_POSSIBLE, iOSAutomation = ALL_POSSIBLE)
@FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)
List<RemoteWebElement> someElements;

Also possible combined variants:

import org.openqa.selenium.remote.RemoteWebElement;
import io.appium.java_client.pagefactory.*;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindByAll;

import static io.appium.java_client.pagefactory.LocatorGroupStrategy.CHAIN;
import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE;

@HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = ALL_POSSIBLE)
@FindAll{@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) 
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) 
RemoteWebElement someElement;

@HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = ALL_POSSIBLE)
@FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)
List<RemoteWebElement> someElements;

or

import org.openqa.selenium.remote.RemoteWebElement;
import io.appium.java_client.pagefactory.*;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindByAll;

import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE;

@HowToUseLocators(iOSAutomation = ALL_POSSIBLE)
@FindAll{@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) //this is the chain 
//by default
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) 
RemoteWebElement someElement;

@HowToUseLocators(iOSAutomation = ALL_POSSIBLE)
@FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)}) 
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) //this is the chain 
//by default
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)
List<RemoteWebElement> someElements;

- deprecated annotations: AndroidFindAll, AndroidFindBys, iOSFindAll, iOSFindBys, SelendroidFindAll, SelendroidFindBys.
- new annotations were added: AndroidFindBySet, iOSFindBySet, SelendroidFindBySet, HowToUseLocators.
- added interface HasSessionDetails which contains methods with default implementation. It is implemented by AppiumDriver and MobileElement
- AndroidDriverTest was modified.
@TikhomirovSergey
Copy link
Contributor Author

@SrinivasanTarget could you review it? :)

@TikhomirovSergey TikhomirovSergey added this to the 5.0.0 milestone Oct 28, 2016
@TikhomirovSergey TikhomirovSergey changed the title Repeatable annotations Repeatable annotations & HasSessionDetails API Oct 28, 2016
Copy link
Member

@SrinivasanTarget SrinivasanTarget left a comment

Choose a reason for hiding this comment

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

…epeatable_annotations

# Conflicts:
#	src/main/java/io/appium/java_client/AppiumDriver.java
…epeatable_annotations

# Conflicts:
#	src/main/java/io/appium/java_client/AppiumDriver.java
@TikhomirovSergey
Copy link
Contributor Author

@SrinivasanTarget The issue which you pointed has got fixed.

@SrinivasanTarget
Copy link
Member

@TikhomirovSergey I like this PR. Gonna be a big change. Code LGTM 👍 Haven't run through the tests, will run through it soon.

@saikrishna321
Copy link
Member

@TikhomirovSergey i'm finding hard to understand the use-of @HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = ALL_POSSIBLE) can you please throw some light on this ?

@SrinivasanTarget
Copy link
Member

SrinivasanTarget commented Oct 30, 2016

@saikrishna321 Please find the simple use case below,

@HowToUseLocators(androidAutomation = CHAIN,iOSAutomation = ALL_POSSIBLE)
@AndroidFindBy(some UISelector()) @AndroidFindBy(Some view or text inside it) 
@iOSFindBy(xpath1) @iOSFindBy(xpath2)
List<RemoteWebElement> someElements;

Based on above code snippet,

CHAIN finds all the elements that matches some view or text inside it (second @AndroidFindBy) that appears under element that matches some UISelector (first @AndroidFindBy)

ALL_POSSIBLE finds all possible iOS elements that matches either xpath1 or xpath2

Incase if we didn't mention any of HowToUseLocators by default it is CHAIN

@saikrishna321
Copy link
Member

@SrinivasanTarget yah i get this... but what does CHAIN and ALL_POSSIBLE do ?

@SrinivasanTarget
Copy link
Member

@saikrishna321 Have updated the comments above. Let me know if it is not clear.

@SrinivasanTarget
Copy link
Member

SrinivasanTarget commented Oct 31, 2016

@TikhomirovSergey Have run through android tests and everything LGTM.Also @codacy is Green.

@TikhomirovSergey
Copy link
Contributor Author

TikhomirovSergey commented Oct 31, 2016

@saikrishna321

yah i get this... but what does CHAIN and ALL_POSSIBLE do ?

That means that each one platform-specific locator can be a part of the chaing of the searching or it is one of possible variants to find the desired element/the desired list of elements as well.

Before we have been using such annotations as @AndroidFindBys({@AndroidFindBy(1),@AndroidFindBy(2)})/@iOSFindBys({@iOSFindBy(1), @iOSFindBy(2)}) to define the searching chain and @AndroidFindAll({@AndroidFindBy(1),@AndroidFindBy(2)})/@iOSFindAll({@iOSFindBy(1), @iOSFindBy(2)}) to define possible locators for the searching.

Now we are migrating to Java 8. It provides repeatable annotations: http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html

So I think that some annotations above are redundant now. We could define the chain like:
@AndroidFindBy(1) @AndroidFindBy(2)/@iOSFindBy(1) @iOSFindBy(2)
But it is still possible that end user needs to define these locators as the set of possible variants to find an element.

So

@HowToUseLocators(iOSAutomation = ALL_POSSIBLE, androidAutomation = ALL_POSSIBLE)
@AndroidFindBy(1) @AndroidFindBy(2)
@iOSFindBy(1) @iOSFindBy(2)

If the end user needs for combined strategy for each target platform then

@HowToUseLocators(iOSAutomation = CHAIN, androidAutomation = ALL_POSSIBLE)
@AndroidFindBy(1) @AndroidFindBy(2) //each one locator is the 
//possible variant to find elements
@iOSFindBy(1) @iOSFindBy(2) //it is for the chained searching

or

@HowToUseLocators(androidAutomation = ALL_POSSIBLE)
@AndroidFindBy(1) @AndroidFindBy(2) //each one locator is the 
//possible variant to find elements
@iOSFindBy(1) @iOSFindBy(2) //it is for the chained searching by default

@TikhomirovSergey
Copy link
Contributor Author

@SrinivasanTarget
How does iOS feels?

@SrinivasanTarget
Copy link
Member

SrinivasanTarget commented Oct 31, 2016

@TikhomirovSergey

How does iOS feels?

Have upgraded my xcode to 8 so i cant run through existing tests on XCUITest Mode. But test code for iOS looks good to me.

@saikrishna321
Copy link
Member

saikrishna321 commented Oct 31, 2016

@SrinivasanTarget @TikhomirovSergey I'm still on xcode 7, any help needed to run the iOS test ?

@saikrishna321
Copy link
Member

@TikhomirovSergey well explained, i had a chat with @SrinivasanTarget on @CacheLookup will take a look on it ..

@SrinivasanTarget
Copy link
Member

SrinivasanTarget commented Oct 31, 2016

I'm still on xcode 7, any help needed to run the iOS test ?

@saikrishna321 May be you can help us with IOSPageFactoryTest.

@saikrishna321
Copy link
Member

@TikhomirovSergey @SrinivasanTarget all tests passed( Tested on iPhone 9.3 Simulator, xcode 7) 👍

@TikhomirovSergey TikhomirovSergey merged commit e2dafc7 into appium:master Oct 31, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants