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

#565 FIX #646

Merged
merged 9 commits into from
May 30, 2017
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 62 additions & 1 deletion docs/Page-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ RemoteWebElement someElement;
List<RemoteWebElement> someElements;
```

## Also possible combined variants:
## Also possible combined variants for target platforms:

```java
import org.openqa.selenium.remote.RemoteWebElement;
Expand Down Expand Up @@ -194,6 +194,67 @@ RemoteWebElement someElement;
List<RemoteWebElement> someElements;
```

## Mixed chain/any locator strategy

Some locator-element could not be defined certainly sometimes. It may be defined as one of possible variants/chained locator.
If the using of _xpath_ is not convenient for some reasons so there are possible use cases

### the chained searching

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

//it is necessary to define priorities at this case. The lower number means the higher priority.
//The default value is 0 (the highest priority)
@iOSFindBy(someStrategy1)
@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //there are some variants for
// this element at the chain
@iOSFindBy(someStrategy2, priority = 2)
@iOSFindBy(someStrategy3, priority = 3)
RemoteWebElement someElement;

Copy link
Member

Choose a reason for hiding this comment

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

CHAINING Contains ALL_POSSIBLE. Awesome👍


@iOSFindBy(someStrategy1)
@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //there are some variants for
// this element at the chain
@iOSFindBy(someStrategy2, priority = 2)
@iOSFindBy(someStrategy3, priority = 3)
List<RemoteWebElement> someElements;
```

### all possible

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

//it is not necessary to define priorities at this case. But it can manage the searching.
//The lower number means the higher priority.
//The default value is 0 (the highest priority)
@HowToUseLocators(iOSAutomation = ALL_POSSIBLE)
@iOSFindBy(someStrategy1)
@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //this possible variant is
// the chain
Copy link
Member

Choose a reason for hiding this comment

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

Can we update this section as below please?

@HowToUseLocators(iOSAutomation = ALL_POSSIBLE)
 @iOSFindBy(someStrategy1)
 @iOSFindBys({
         @iOSBy(parentLocator),
         @iOSBy(childLocator)},
         priority = 1) //this possible variant is the chain
 @iOSFindBy(someStrategy2, priority = 2) 
 @iOSFindBy(someStrategy3, priority = 3) 
 RemoteWebElement someElement;

ALL_POSSIBLE contains CHAIN

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes

@iOSFindBy(someStrategy2, priority = 2)
@iOSFindBy(someStrategy3, priority = 3)
RemoteWebElement someElement;



@HowToUseLocators(iOSAutomation = ALL_POSSIBLE)
@iOSFindBy(someStrategy1)
@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //this possible variant is
// the chain
Copy link
Member

Choose a reason for hiding this comment

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

Same here too.

@iOSFindBy(someStrategy2, priority = 2)
@iOSFindBy(someStrategy3, priority = 3)
List<RemoteWebElement> someElements;
```

# Appium Java client is integrated with Selenium PageFactory by AppiumFieldDecorator.

Object fields are populated as below:
Expand Down
2 changes: 1 addition & 1 deletion google-style.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
value="Package name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="TypeName">
<property name="format" value="^([iOSFindBys]||[iOSFindBy]||[iOSFindAll])||([A-Z][a-zA-Z0-9])*$"/>
<property name="format" value="^([*iOSFindBy*]||[*iOSXCUITFind*])||([A-Z][a-zA-Z0-9])*$"/>
<message key="name.invalidPattern"
value="Type name ''{0}'' must match pattern ''{1}''."/>
</module>
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/appium/java_client/ScreenshotState.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package io.appium.java_client;

import static nu.pattern.OpenCV.loadShared;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
Expand All @@ -32,8 +34,6 @@
import java.util.function.Function;
import java.util.function.Supplier;

import static nu.pattern.OpenCV.loadShared;

public class ScreenshotState {
private static final Duration DEFAULT_INTERVAL_MS = Duration.ofMillis(500);

Expand Down
61 changes: 61 additions & 0 deletions src/main/java/io/appium/java_client/pagefactory/AndroidBy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.appium.java_client.pagefactory;

/**
* Used to build a complex android automator locator.
*/
public @interface AndroidBy {
/**
* It is an is Android UIAutomator string.
* Read http://developer.android.com/intl/ru/tools/testing-support-library/
* index.html#uia-apis
*/
String uiAutomator() default "";

/**
* It an UI automation accessibility Id which is a convenient to Android.
* About Android accessibility
* https://developer.android.com/intl/ru/training/accessibility/accessible-app.html
*/
String accessibility() default "";

/**
* It is an id of the target element.
*/
String id() default "";

/**
* It is a className of the target element.
*/
String className() default "";

/**
* It is a desired element tag.
*/
String tagName() default "";

/**
* It is a xpath to the target element.
*/
String xpath() default "";

/**
* @return priority of the searching. Higher number means lower priority.
*/
int priority() default 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,31 @@

package io.appium.java_client.pagefactory;

import java.lang.annotation.ElementType;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Used to mark a field on a Page/Screen Object to indicate that lookup should use a
* series of {@link io.appium.java_client.pagefactory.AndroidFindBy} tags
* series of {@link io.appium.java_client.pagefactory.AndroidBy} tags
* It will then search for all elements that match any criteria. Note that elements
* are not guaranteed to be in document order.
* It is deprecated. Set of {@link io.appium.java_client.pagefactory.AndroidFindBy}
* can be defined without this annotation. To define the correct way how to use
* the defined set please take a look at {@link HowToUseLocators}. The article.
* https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html.
*/
@Deprecated
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RUNTIME) @Target({FIELD, TYPE})
@Repeatable(AndroidFindByAllSet.class)
public @interface AndroidFindAll {
/**
* It is a set of {@link io.appium.java_client.pagefactory.AndroidFindBy} strategies which may
* It is a set of {@link io.appium.java_client.pagefactory.AndroidBy} strategies which may
* be used to find the target element.
*/
AndroidFindBy[] value();
AndroidBy[] value();

/**
* @return priority of the searching. Higher number means lower priority.
*/
int priority() default 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@

package io.appium.java_client.pagefactory;

import java.lang.annotation.ElementType;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


Expand All @@ -30,7 +32,7 @@
* this allows users to quickly and easily create PageObjects.
* using Android UI selectors, accessibility, id, name, class name, tag and xpath
*/
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RUNTIME) @Target({FIELD, TYPE})
@Repeatable(AndroidFindBySet.class)
public @interface AndroidFindBy {
/**
Expand Down Expand Up @@ -66,4 +68,9 @@
* It is a xpath to the target element.
*/
String xpath() default "";

/**
* @return priority of the searching. Higher number means lower priority.
*/
int priority() default 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.appium.java_client.pagefactory;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Defines set of chained/possible locators. Each one locator
* should be defined with {@link AndroidFindAll}
*/
@Target(value = {TYPE, FIELD})
@Retention(value = RUNTIME)
public @interface AndroidFindByAllSet {
/**
* @return an array of {@link AndroidFindAll} which builds a sequence of
* the chained searching for elements or a set of possible locators
*/
AndroidFindAll[] value();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.appium.java_client.pagefactory;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Defines set of chained/possible locators. Each one locator
* should be defined with {@link io.appium.java_client.pagefactory.AndroidFindBys}
*/
@Target(value = {TYPE, FIELD})
@Retention(value = RUNTIME)
public @interface AndroidFindByChainSet {
/**
* @return an array of {@link io.appium.java_client.pagefactory.AndroidFindBys} which builds a sequence of
* the chained searching for elements or a set of possible locators
*/
AndroidFindBys[] value();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@

package io.appium.java_client.pagefactory;

import java.lang.annotation.ElementType;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Defines set of chained/possible locators. Each one locator
* should be defined with {@link io.appium.java_client.pagefactory.AndroidFindBy}
*/
@Target(value = {ElementType.TYPE, ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {TYPE, FIELD})
@Retention(value = RUNTIME)
public @interface AndroidFindBySet {
/**
* @return an array of {@link io.appium.java_client.pagefactory.AndroidFindBy} which builds a sequence of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,29 @@

package io.appium.java_client.pagefactory;

import java.lang.annotation.ElementType;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Used to mark a field on a Page Object to indicate that lookup should use
* a series of {@link io.appium.java_client.pagefactory.AndroidFindBy} tags.
* It is deprecated. Set of {@link io.appium.java_client.pagefactory.AndroidFindBy}
* can be defined without this annotation. To define the correct way how to use
* the defined set please take a look at {@link HowToUseLocators}. The article.
* https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html.
* a series of {@link io.appium.java_client.pagefactory.AndroidBy} tags.
*/
@Deprecated
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RUNTIME) @Target({FIELD, TYPE})
@Repeatable(AndroidFindByChainSet.class)
public @interface AndroidFindBys {
/**
* It is a set of {@link io.appium.java_client.pagefactory.AndroidFindBy} strategies which build
* It is a set of {@link io.appium.java_client.pagefactory.AndroidBy} strategies which build
* the chain of the searching for the target element.
*/
AndroidFindBy[] value();
AndroidBy[] value();

/**
* @return priority of the searching. Higher number means lower priority.
*/
int priority() default 0;
}
Loading