Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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) //it means that the chained searching contains
//the searching by all possible locators as the element of the chain
@iOSFindBy(someStrategy2, priority = 2)
@iOSFindBy(someStrategy3, priority = 3)
RemoteWebElement someElement;


@iOSFindBy(someStrategy1)
@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //it means that the chained searching contains
//the searching by all possible locators as the element of 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)
@iOSFindBys(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //it means that the searching by all possible locators
// contains the searching by chained locator as one of all possible variants
@iOSFindBy(someStrategy2, priority = 2)
@iOSFindBy(someStrategy3, priority = 3)
RemoteWebElement someElement;



@HowToUseLocators(iOSAutomation = ALL_POSSIBLE)
@iOSFindBy(someStrategy1)
@iOSFindBys(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //it means that the searching by all possible locators
// contains the searching by chained locator as one of all possible variants
@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