Sì, è possibile estendere il framework azioni. Ma, a rigor di termini, ottenendo qualcosa di simile:
browser.actions().mouseDown(element).sleep(5000).mouseUp(element).perform();
significa scherzi con le budella di selenio. Quindi, YMMV.
Si noti che lo Protractor documentation si riferisce a webdriver.WebDriver.prototype.actions
quando si spiegano le azioni, che io intendo per significare che non modifica o aggiunge a ciò che il Selenium fornisce.
La classe dell'oggetto restituita da webdriver.WebDriver.prototype.actions
è webdriver.ActionSequence
. Il metodo che effettivamente causa la sequenza per fare qualsiasi cosa è webdriver.ActionSequence.prototype.perform
. Nell'implementazione predefinita, questa funzione accetta i comandi che sono stati registrati quando è stato chiamato .sendKeys()
o .mouseDown()
e il driver a cui è associato lo ActionSequence
li pianifica in ordine. Così l'aggiunta di un metodo .sleep
non può essere fatto in questo modo:
webdriver.ActionSequence.prototype.sleep = function (delay) {
var driver = this.driver_;
driver.sleep(delay);
return this;
};
In caso contrario, il sonno sarebbe successo fuori uso. Quello che devi fare è record l'effetto desiderato in modo che venga eseguito in seguito.
Ora, l'altra cosa da considerare è che il valore predefinito .perform()
prevede solo l'esecuzione di webdriver.Command
, che sono comandi da inviare al browser. Dormire non è uno di questi comandi. Quindi .perform()
deve essere modificato per gestire quello che registreremo con .sleep()
. Nel codice seguente ho deciso di fare in modo che .sleep()
registri una funzione e modificato .perform()
per gestire le funzioni oltre a webdriver.Command
.
Ecco come appare l'insieme, una volta messo insieme. Per prima cosa ho dato un esempio usando Selenium di serie e poi aggiunto le patch e un esempio usando il codice modificato.
var webdriver = require('selenium-webdriver');
var By = webdriver.By;
var until = webdriver.until;
var chrome = require('selenium-webdriver/chrome');
// Do it using what 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);
// Do it with an extended ActionSequence.
webdriver.ActionSequence.prototype.sleep = function (delay) {
var driver = this.driver_;
// This just records the action in an array. this.schedule_ is part of
// the "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;
// This is a new test to distinguish functions, which
// require handling one way and the usual commands which
// require a different handling.
if (typeof command === "function")
// This puts the command in its proper place within
// the control flow that was 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();
Nella mia implementazione di .perform()
Ho sostituito le goog...
funzioni che il codice di selenio usa con magazzino JavaScript.
Scavando in fonti di selenio, per quanto ho capito che non sarebbe stato possibile estendere in realtà le azioni, vorrei prendere in considerazione la creazione di una sorta di involucro come @ John Stennett ha suggerito. Se sei interessato, potrei dare una spiegazione del perché non potrebbe essere fatto (dal mio punto di vista, forse è possibile). –
@MichaelRadionov si, ho avuto paura di avvolgerlo è l'unica opzione (non c'è niente di sbagliato comunque). Apprezzerei la tua intuizione, le tue risposte sono sempre dettagliate e utili. Inoltre, spero che l'argomento possa aiutare non solo me a risolvere il mio problema attuale, ma anche altri con richieste simili. Grazie! – alecxe