javascript - Custom browser actions in Protractor -


the problem:

in 1 of our tests have "long click"/"click , hold" functionality solve using:

browser.actions().mousedown(element).perform(); browser.sleep(5000); browser.actions().mouseup(element).perform(); 

which ideally solve in 1 line having sleep() part of action chain:

browser.actions().mousedown(element).sleep(5000).mouseup(element).perform(); 

clearly, not work since there no "sleep" action.

another practical example "human-like typing". instance:

browser.actions().mousemove(element).click()    .sendkeys("t").sleep(50)  // should randomize delays, strictly speaking    .sendkeys("e").sleep(10)    .sendkeys("s").sleep(20)    .sendkeys("t")    .perform(); 

note these examples, question meant generic.

the question:

is possible extend browser.actions() action sequences , introduce custom actions?


yes, can extend actions framework. but, strictly speaking, getting like:

browser.actions().mousedown(element).sleep(5000).mouseup(element).perform(); 

means messing selenium's guts. so, ymmv.

note protractor documentation refers webdriver.webdriver.prototype.actions when explaining actions, take mean not modify or add selenium provides.

the class of object returned webdriver.webdriver.prototype.actions webdriver.actionsequence. method causes sequence webdriver.actionsequence.prototype.perform. in default implementation, function takes commands recorded when called .sendkeys() or .mousedown() , has driver actionsequence associated schedule them in order. adding .sleep method cannot done way:

webdriver.actionsequence.prototype.sleep = function (delay) {     var driver = this.driver_;     driver.sleep(delay);     return this; }; 

otherwise, sleep happen out of order. have record effect want executed later.

now, other thing consider default .perform() expects execute webdriver.command, commands sent browser. sleeping not 1 such command. .perform() has modified handle going record .sleep(). in code below i've opted have .sleep() record function , modified .perform() handle functions in addition webdriver.command.

here whole thing looks like, once put together. i've first given example using stock selenium , added patches , example using modified code.

var webdriver = require('selenium-webdriver'); var = webdriver.by; var until = webdriver.until; var chrome = require('selenium-webdriver/chrome');  // using selenium inherently provides.  var browser = new chrome.driver();  browser.get("http://www.google.com");  browser.findelement(by.name("q")).click(); browser.actions().sendkeys("foo").perform(); browser.sleep(2000); browser.actions().sendkeys("bar").perform(); browser.sleep(2000);  // extended actionsequence.  webdriver.actionsequence.prototype.sleep = function (delay) {     var driver = this.driver_;     // records action in array. this.schedule_ part of     // "stock" code.     this.schedule_("sleep", function () { driver.sleep(delay); });     return this; };  webdriver.actionsequence.prototype.perform = function () {     var actions = this.actions_.slice();     var driver = this.driver_;     return driver.controlflow().execute(function() {         actions.foreach(function(action) {             var command = action.command;             // new test distinguish functions,              // require handling 1 way , usual commands             // require different handling.             if (typeof command === "function")                 // puts command in proper place within                 // control flow created above                 // (driver.controlflow()).                 driver.flow_.execute(command);             else                 driver.schedule(command, action.description);         });     }, 'actionsequence.perform'); };  browser.get("http://www.google.com");  browser.findelement(by.name("q")).click(); browser.actions().sendkeys("foo")     .sleep(2000)     .sendkeys("bar")     .sleep(2000)     .perform(); browser.quit(); 

in implementation of .perform() i've replaced goog... functions selenium's code uses stock javascript.


Comments