问题:
在我们的一项测试中,我们具有“长按”/“单击并按住”功能,可以使用以下方法解决:
browser.actions().mouseDown(element).perform(); browser.sleep(5000); browser.actions().mouseUp(element).perform();
我们希望通过sleep()包含动作链的一部分来理想地解决这一问题:
sleep()
browser.actions().mouseDown(element).sleep(5000).mouseUp(element).perform();
显然,这是行不通的,因为没有“睡眠”操作。
另一个实际的例子可能是“类人打字”。例如:
browser.actions().mouseMove(element).click() .sendKeys("t").sleep(50) // we should randomize the delays, strictly speaking .sendKeys("e").sleep(10) .sendKeys("s").sleep(20) .sendKeys("t") .perform();
注意,这些只是示例,这个问题是通用的。
是否可以扩展browser.actions()动作序列并引入自定义动作?
browser.actions()
是的,您可以扩展操作框架。 但是,严格来说,得到的是:
意味着弄乱硒的胆量。因此,YMMV。
请注意,量角器文档是webdriver.WebDriver.prototype.actions在解释操作时引用的,我的意思是指它没有修改或添加到Selenium提供的内容中。
webdriver.WebDriver.prototype.actions
传回的物件类别webdriver.WebDriver.prototype.actions为webdriver.ActionSequence。实际导致序列执行任何操作的方法是webdriver.ActionSequence.prototype.perform。在默认实现中,此函数采用调用.sendKeys()或时记录的命令,.mouseDown()并具有ActionSequence与之关联的驱动程序的顺序安排它们。因此, 无法通过这种方式* 添加.sleep方法: *
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。
.perform()
webdriver.Command
.sleep()
放在一起后,这就是整个外观。我先给出了一个使用库存硒的示例,然后添加了补丁和使用修改后的代码的示例。
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...JavaScript 替换了Selenium代码使用的功能。
goog...