Ответ 1
Да, вы можете расширить рамки действий. Но, строго говоря, получилось что-то вроде:
browser.actions().mouseDown(element).sleep(5000).mouseUp(element).perform();
означает возиться с селенскими кишками. Итак, YMMV.
Обратите внимание, что Документация по транспортировке относится к webdriver.WebDriver.prototype.actions
при объяснении действий, которые я подразумеваю, что она не изменяет и не добавляет к тому, что Селен обеспечивает.
Класс объекта, возвращаемый webdriver.WebDriver.prototype.actions
, равен webdriver.ActionSequence
. Метод, который фактически вызывает последовательность, делает что-либо: webdriver.ActionSequence.prototype.perform
. В реализации по умолчанию эта функция принимает команды, которые были записаны при вызове .sendKeys()
или .mouseDown()
, и имеет драйвер, к которому привязано ActionSequence
, упорядочить их по порядку. Поэтому добавление метода .sleep
НЕ МОЖЕТ быть сделано таким образом:
webdriver.ActionSequence.prototype.sleep = function (delay) {
var driver = this.driver_;
driver.sleep(delay);
return this;
};
В противном случае сон будет выходить из строя. Что вам нужно сделать, так это записать эффект, который вы хотите, чтобы он был выполнен позже.
Теперь, еще одна вещь, которую следует учитывать, заключается в том, что по умолчанию .perform()
ожидает только выполнение webdriver.Command
, которые являются командами, которые должны быть отправлены в браузер. Сон - это не одна такая команда. Поэтому .perform()
необходимо изменить для обработки того, что мы будем записывать с помощью .sleep()
. В приведенном ниже коде я решил иметь .sleep()
записать функцию и изменить .perform()
для обработки функций в дополнение к webdriver.Command
.
Вот как все выглядит, как только собрано. Сначала я привел пример, используя запас Selenium, а затем добавил патчи и пример с использованием модифицированного кода.
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();
В моей реализации .perform()
я заменил функции goog...
, которые использует код Selenium с использованием JavaScript.