vitaliiSmokov / jpagefactory

JPageFactory is a set of Selenium Java FindBy annotations that eases the usage of Selenium page factory pattern for automating Angular based web application. It is based on JProtractor project which is a Java wrapper of Protractor framework.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

jPageFactory

Summary:

JPageFactory_ is a set of Selenium Java FindBy annotations that eases the usage of Selenium page factory pattern for automating Angular based web application.

JPageFactory is implemented on top of JProtractor and provides extended set of web elements locators annotations with a syntax following the core Selenium FindBy:

  • Core Selenum

    • ID
    • Name
    • XPath
    • CSS
    • Class Name
    • Tag Name
    • Link Text
    • Partial Link Text
  • Protractor

    • Binding
    • Input
    • Model
    • Repeater
    • Button Text
    • Partial Button Text
    • Options
    • Selected Options
    • Repeater Selected Options
    • CssContainingText
    • RepeaterColumn
    • RepeaterRow
    • RepeaterElement

JPageFactory also supports defining different locators of the same web element for both desktop web and mobile web applications (Angular applications running in mobile browsers).

Initializing page object

Using the following page factory APIs to initializing the page object:

JPageFactory.initElements(SearchContext searchContext, Channel channel, Object page);

JPageFactory.initWebElements(SearchContext searchContext, Object page);

JPageFacotry.initMobileElements(SearchContext searchContext, Object page);

Locator Usage:

Here are examples of using locators from Protractor:

- Find element by Angular binding

html:

<h2>{{latest}}</h2>

annotation example:

@FindBy(how = How.BINDING, using = "latest")
private WebElement latestResult;

- Find input element with Angular ng-model

html:

<input ng-model="first" type="text" class="input-small"/>

annotation example:

@FindBy(how = How.INPUT, using = "first")
private WebElement firstNumber;

- Find Angular directive by ng-model

html:

<am-multiselect class="input-lg" ng-model="selectedCar" ms-header="Select Some Cars">

annotation example:

@FindBy(how = How.MODEL, using = "selectedCar")
private WebElement _directive;

- Find elements of Angular ng-repeater

html:

<tr ng-repeat="result in memory">
    <td>
        {{result.timestamp | date:'mediumTime'}}
    </td>
    <td>
        <span>{{result.first}}</span>
        <span>{{result.operator}}</span>
        <span>{{result.second}}</span>
    </td>
    <td>{{result.value}}</td>
    </tr>

annotation example:

@FindAll({
    @FindBy(how = How.REPEATER, using = "result in memory")
})
private List<WebElement> history;

- Find element in the repeater, binding by Angular repeater column

html:

 <table>
    <tr ng-repeat="row in rows | filter : search">
      <td>{{$index+1}}</td>
      <td>{{name}}</td>
    </tr>
  </table>

annotation example:

@FindAll({ @FindBy(how = How.REPEATER_COLUMN, using = "row in rows", column = "name") })
private List<WebElement> friendNames;

- Find element with button text

html:

<button ng-click="doAddition()" id="gobutton" class="btn">Go!</button>

annotation example:

@FindBy(how = How.BUTTON_TEXT, using = "Go!")
private WebElement goButton;

- Find Angular directive by partial button text

html:

<am-multiselect class="input-lg" multiple="true" ms-selected ="There are {{selectedCar.length}} car(s) selected" ng-model="selectedCar" ms-header="Select Some Cars">

annotation example:

@FindBy(how = How.PARTIAL_BUTTON_TEXT, using = "Select Some Cars")
private WebElement _multiselect;

- Find all select options elements

html:

<select ng-model="operator" class="span1"
    ng-options="value for (key, value) in operators">
</select>

annotation example:

@FindBy(how = How.MODEL, using = "operator")
private WebElement operatorSelect;

@FindAll({
    @FindBy(how = How.OPTIONS, using = "value for (key, value) in operators")
})
private List<WebElement> operationSelectorOptions;

- Find selected option element

html:

<select ng-model="operator" class="span1"
    ng-options="value for (key, value) in operators">
</select>

annotation example:

@FindBy(how = How.SELECTED_OPTION, using = "operator")
private WebElement selectedOption;

- Find element for CSS Selector and text

html

http://dalelotts.github.io/angular-bootstrap-datetimepicker/

<span class="hour" data-ng-repeat="dateObject in data.dates"
data-ng-click="changeView(data.nextView, dateObject, $event)">10:00 AM</span>

annotation example:

String timeOfDay = "10:00 AM";
WebElement ng_hour = ng_element.findElements(
    NgBy.cssContainingText("span.hour", timeOfDay)).get(0);

html

http://jaykanakiya.com/demos/angular-js-todolist/

<ul ng-repeat="todos in model track by $index">
  <li class="todoTask ng-scope" ng-repeat="todo in todos.list | filter:showFn | filter :todoSearch ">
    <span class="todoName ng-binding" ng-bind="value">Create an Angular-js TodoList</span>
    <button type="button" ng-click="deleteTodo(todo)">&#xD7;</button>
  </li>
  <li class="todoTask ng-scope" ng-repeat="todo in todos.list | filter:showFn | filter :todoSearch ">
    <span class="todoName ng-binding" ng-bind="value">Understanding Angular-js Directives</span>
    <button type="button" class="close pull-right" aria-hidden="true" ng-click="deleteTodo(todo)">&#xD7;</button>
  </li>
</ul>

annotation example:

@FindAll({
	@FindBy(how = How.CSS_CONTAINING_TEXT, using = "span.todoName", 
    text = "Angular-js") })
	private List<WebElement> _rows;

Use annotation for both desktop and mobile web applications:

JPageFactory annotations work for both desktop and mobile web applications. When defining the annotation using how and using fields, the same locator will be used for both channels.

One can define the annotation in the follow way to use different locators for desktop and mobile channels:

@FindBy(howWeb = How.INPUT, usingWeb = "second", howMobile = How.XPATH, usingMobile = "//input[@ng-model='second']")

In the above example, JPageFactory will find the input element by its ng-model attribute for desktop channel, and use XPath locator to find the same input element when running on mobile devices.

When initializing the page object, one must specify the channel argument, so that it will use the corresponding locators:

Channel channel = Channel.WEB;
if (isMobile) {
    channel = Channel.MOBILE;
}
JPageFactory.initElements(ngDriver, channel, superCalculatorPage);

If one element only appears on certain channel, the howXXX and usingXXX fields for that channel can be skipped when defining the annotation.

Code example

Some code examples are provided in the JUnit test cases in the project. One can get it from the downloaded source code. One example automates the Super Calculator demo application from official Protractor tutorial. Other use Angular Todo List, qualityshepherd Protractor example and Angular Multi-Select

In order to run the example tests, Google Chrome browser is required.

Copy the jprotractor-1.2-SNAPSHOT.jar jar into src/main/resources.

Make sure to import:

import org.henrrich.jpagefactory.How;
import org.henrrich.jpagefactory.annotations.FindAll;
import org.henrrich.jpagefactory.annotations.FindBy;

import com.jprotractor.NgWebDriver;
import com.jprotractor.NgWebElement;
import com.jprotractor.NgBy;

Note that Eclipse organize imports command would remove the unresolved jprotractor lines.

To check how JPageFactory work on mobile channel, run example tests on Google Chrome emulator by setting the following flag to true:

// change this boolean flag to true to run on chrome emulator
private boolean isMobile = false;

Authors

About

JPageFactory is a set of Selenium Java FindBy annotations that eases the usage of Selenium page factory pattern for automating Angular based web application. It is based on JProtractor project which is a Java wrapper of Protractor framework.

License:MIT License


Languages

Language:Java 100.0%