All Projects → Xotabu4 → protractor-element-extend

Xotabu4 / protractor-element-extend

Licence: MIT license
Module, that helps you to extend ElementFinder in your own custom fragments

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to protractor-element-extend

OneFramework
Automation for iOS, Android, & Web Apps with one codebase. Like it, Star it & spread the word !!!
Stars: ✭ 46 (+109.09%)
Mutual labels:  pageobject, pageobject-pattern
page-modeller
⚙️ Browser DevTools extension for modelling web pages for automation.
Stars: ✭ 66 (+200%)
Mutual labels:  webdriver, pageobject
Codeceptjs
Supercharged End 2 End Testing Framework for NodeJS
Stars: ✭ 3,592 (+16227.27%)
Mutual labels:  protractor, pageobject
Protractor
E2E test framework for Angular apps
Stars: ✭ 8,792 (+39863.64%)
Mutual labels:  webdriver, protractor
PWAF
Python Webdriver Automation Framework
Stars: ✭ 37 (+68.18%)
Mutual labels:  webdriver, pageobject-pattern
Query Selector Shadow Dom
querySelector that can pierce Shadow DOM roots without knowing the path through nested shadow roots. Useful for automated testing of Web Components. Production use is not advised, this is for test environments/tools such as Web Driver, Playwright, Puppeteer
Stars: ✭ 115 (+422.73%)
Mutual labels:  webdriver, protractor
Verticalslidefragment
vertical slide to switch to the next fragment page, looks like vertical viewpager
Stars: ✭ 1,615 (+7240.91%)
Mutual labels:  fragments
Aboutlibraries
AboutLibraries automatically detects all dependencies of a project and collects their information including the license. Optionally visualising it via the provided ui components.
Stars: ✭ 2,777 (+12522.73%)
Mutual labels:  fragments
Scene
Android Single Activity Applications framework without Fragment.
Stars: ✭ 1,793 (+8050%)
Mutual labels:  fragments
Flownav
Annotation processor that provides better navigation on android multi-modules projects 🛳.
Stars: ✭ 122 (+454.55%)
Mutual labels:  fragments
wdio-intercept-service
🕸 Capture and assert HTTP ajax calls in webdriver.io
Stars: ✭ 101 (+359.09%)
Mutual labels:  webdriver
FragmentDemo
fragment,demo
Stars: ✭ 18 (-18.18%)
Mutual labels:  fragments
Wanandroid
WanAndroid客户端,项目基于 Material Design + MVP +dagger2 + RxJava + Retrofit + Glide + greendao 等架构进行设计实现,极力打造一款 优秀的玩Android https://www.wanandroid.com 客户端,是一个不错的Android应用开发学习参考项目
Stars: ✭ 223 (+913.64%)
Mutual labels:  fragments
Android Cheat Sheet
Cheat Sheet for Android Interviews
Stars: ✭ 1,891 (+8495.45%)
Mutual labels:  fragments
Base
🍁 Base是针对于Android开发封装好一些常用的基类,主要包括通用的Adapter、Activity、Fragment、Dialog等、和一些常用的Util类,只为更简单。
Stars: ✭ 249 (+1031.82%)
Mutual labels:  fragments
Catchup
An app for catching up on things.
Stars: ✭ 1,690 (+7581.82%)
Mutual labels:  fragments
wd.java
Java Client binding for Macaca
Stars: ✭ 30 (+36.36%)
Mutual labels:  webdriver
Flowr
FlowR is a wrapper class around the Fragment Manager.
Stars: ✭ 123 (+459.09%)
Mutual labels:  fragments
Fragmentrigger
💥A powerful library powered by AOP to manage Fragments.(一个基于AOP设计的Fragment管理框架)
Stars: ✭ 2,260 (+10172.73%)
Mutual labels:  fragments
elemental
Elemental makes Selenium automation faster and easier.
Stars: ✭ 36 (+63.64%)
Mutual labels:  webdriver

No Maintenance Intended

This library is deprecated and won't be updated in future, since protractor support is ending as well: angular/protractor#5502

Build Status

Protractor Page Fragments

Simple module, that helps you build your own page fragments, that are inherited from ElementFinder/ElementArrayFinder objects, that brings awesome posibilities to your ProtractorJS tests.

You might heard other names for this pattern: Page Components, Page Composition, HTML Elements, Custom WebElements, WebElement inheritance, Page Elements. This is all about the same.

Installing

As any other NPM package:

npm install protractor-element-extend --save-dev

Importing

JS:

let BaseFragment = require('protractor-element-extend').BaseFragment

let BaseArrayFragment = require('protractor-element-extend').BaseArrayFragment

TS: import {BaseFragment, BaseArrayFragment} from 'protractor-element-extend'

Creating own single fragment

To declare your own fragment, declare your class, extend it from BaseFragment, and pass ElementFinder(WebElement in protractorJS) that represents this fragment to super constructor.

Here is example how Checkbox fragment can be declared:

import {BaseFragment} from 'protractor-element-extend'
import {browser, ExpectedConditions as EC} from 'protractor'

class Checkbox extends BaseFragment {
  constructor(element) {
    super(element) //that's it! now your 'this' reference, is reference to element passed to super constructor
  }
  
  //You can extend it with any methods that you what, and use internal reference to your element
  select() {
    this.isSelected().then(selected => {
      if(!selected) {
        this.click()
        // Notice that because your element is valid ElementFinder - you can pass it as parameter to ExpectedConditions.
        browser.wait(EC.elementToBeSelected(this), 5000, `Checkbox ${this.locator()} must became selected after click, but it wasn't`)
      } else {
          console.warn(`Checkbox ${this.locator()} was already selected, skipping select`)
      }
    })
  }
  
  unselect() {
    this.isSelected().then(selected => {
      if(selected) {
        this.click()
        // Notice that because your element is valid ElementFinder - you can pass it as parameter to ExpectedConditions!
        browser.wait(EC.not(EC.elementToBeSelected(this)), 5000, `Checkbox ${this.locator()} must became unselected after click, but it wasn't`)
      } else {
          console.warn(`Checkbox ${this.locator()} was already unselected, skipping unselect`)
      }
    })
  }

}

Creating own collection of custom fragments

Often needed to work with own custom collection of own fragments, not only single fragment. For this purpose BaseArrayFragment is added. This object extends ElementArrayFragment, and overrides methods that return single elements, to return your custom fragments. .map() .filter() .reduce() .each() and other will receive your custom fragment as parameter as well.

Here is example how SearchResultsCollection fragment can be declared:

import { BaseArrayFragment, BaseFragment } from 'protractor-element-extend'
import { browser, ExpectedConditions as EC, $$ } from 'protractor'

// Describing single search result on our page. Notice that constructor declaration could be skipped, in this case constructor from BaseFragment will be used
class SearchResult extends BaseFragment {
    name() {
      return $('.name').getText()
    }

    isDiscounted() {
        return this.$('.discount-label').isDisplayed()
    }

    open() {
        this.$('button.open').click()
    }
}

// Generics - <SearchResults> are needs to be defined to provide typings support.
class SearchResultsCollection extends BaseArrayFragment<SearchResult> {
    constructor(elementsToExtend: ElementArrayFinder) {
        // You should pass ElementArrayFinder into super constructor, and constructor(class) that will be used to wrap each element in your collection
        super(elementsToExtend, SearchResult);
    }

    findResultsWithDiscount() {
        // This will return new SearchResults object with only those SearchResult objects that has isDiscounted == true
        return this.filter(searchRes => searchRes.isDiscounted())
    }
}

// Initializing is the same as BaseFragment, but you need to pass ElementArrayFinder now.
let searchResults = new SearchResultsCollection($$('.search-result'))
// Awesome readability for your tests
searchResults.findResultsWithDiscount().first().open()

BaseArrayFragment also supports additional array methods that does not exist in ElementArrayFinder in ProtractorJS: .every() .some() .find()

More tricks

You can wrap any ElementFinder into your fragment:

let checkbox = new Checkbox($$('.checkbox').last())

You can use your fragments everywhere where ElementFinder is expected. For example - inside browser.wait

browser.wait(EC.elementToBeClickable(checkbox), 5000, 'Checkbox should be clickable')

Or inside executeScript:

let checkbox = new Checkbox($('div.checkbox'))
var tag = browser.executeScript('return arguments[0].tagName', checkbox);
expect(tag).toEqual('div');

You can override ElementFinder or ElementArrayFinder methods, to get even more powerful functionality

...
import {promise} from 'protractor'

class Checkbox extends BaseFragment {
  ...
  // Ovveriding isDisplayed function that is used in ExpectedCondition.visibilityOf()
  isDisplayed() {
    let fragmentDisplayed = super.isDisplayed()
    let loaderDisplayed = $('.loader').isDispayed()
    // This will return promise, that will be resolved to true, if element is displayed, but loader is not displayed.
    return promise.all(fragmentDisplayed, loaderDisplayed).then(displArray=> displArray[0] && !displArray[1])
  }
}

...
let checkbox = new Checkbox($('.checkbox'))
browser.wait(EC.visibilityOf(checkbox), 3000, 'Checkbox should be visible, but loader should not be visible')

Try to use fragments by placing fragments one into another:

class LoginForm extends BaseFragment {
    loginField:TextField
    passwordField:TextField
    rememberMe:Checkbox

    constructor() {
        super($('.loginform'))
        // Notice that we are searching only inside 'this' element, this brings additional stability to tests
        this.loginField = new TextField(this.$('.loginfield'))
        this.passwordField = new TextField(this.$('.passwordfield'))
        this.rememberMe = new Checkbox(this.$('.rememberme'))
    }

    login(username='test', password='test', rememberme=true) {
        this.loginField.type(username)
        this.passwordField.type(password)
        rememberme && this.rememberMe.select()
        this.$('button.login').click()
    }
}

Supported versions

Currently tested on NodeJS:

  • 6
  • 7
  • 8
  • 9
  • 10

ProtractorJS:

  • 5.x

This lib should work on protractor 4.x without modifications (but this is untested). Protractor 3.x will require browser_ reference rename. PRs are welcome!

Typings for TypeScript are included.

Future

  • Better logging for fragments. Provide possibility to set name attribute, and if it is not set - try to generate best we can with locator()
  • Want some feature? Feel free to create issue!

Something to read

Source code for ElementFinder and ElementArrayFinder -

https://github.com/angular/protractor/blob/master/lib/element.ts

Generics in TypeScript -

https://www.typescriptlang.org/docs/handbook/generics.html

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].