Xotabu4 Xotabu4 - 6 months ago 79
AngularJS Question

How to extend ElementFinder object in ProtractorJS?

Durring some experiments with protractorJS i noticed that there is no easy way to extend (inherit) ElementFinder object from protractor to add own functions.

For example, i want to create object Checkbox, that would have additional method - check() - should switch checkbox depending on result of isSelected().

I come up with the code -

var ElementFinder = require('protractor/lib/element.js').ElementFinder;
var ElementArrayFinder = require('protractor/lib/element.js').ElementArrayFinder;

class CheckBox extends ElementFinder {
constructor(loc) {
var getWebElements = function () {
var ptor = browser;
var locator = loc;
return ptor.waitForAngular().then(function() {
if (locator.findElementsOverride) {
return locator.findElementsOverride(ptor.driver, null, ptor.rootEl);
} else {
return ptor.driver.findElements(locator);
}
});
}
var ArrayFinderFull = new ElementArrayFinder(browser, getWebElements, loc);
super(browser, ArrayFinderFull);
}

check() {
return this.isSelected().then(selected => selected? this.click() : null)
}
}


But getWebElements is copy-paste from protractor/element.js -
https://github.com/angular/protractor/blob/3.1.0/lib/element.js#L131

This copy-paste flustrating me. I think there should be more proper way to extend ElementFinder.

Does anyone inherited ElementFinder in protractorJS?

Answer

So answering my own question I played a little, and found pretty cool idea, but implementation might have lacks -

class Dropdown {
    constructor(element) {
        var obj = this;
        while(Object.getPrototypeOf(obj) instanceof Object) {
            obj = Object.getPrototypeOf(obj)
        }
        Object.setPrototypeOf(obj, element);
    }

    check() {
        return this.isSelected().then(selected => selected && this.click())
    }
}

new Dropdown($('locator_for_your_dropdown')).check();

So i overriding prototype of my element, but not the direct one, the deepest prototype in chain, so all inheritance structure is saved, and then i get all features of ElementFinder or ArrayElementFinder by calling 'this'

Any suggestions, and additions are welcome

Comments