javascript - Protractor 中的自定义浏览器操作

标签 javascript selenium selenium-webdriver protractor

问题:

在我们的一个测试中,我们有一个 "long click"/"click and hold" functionality我们通过使用解决:

browser.actions().mouseDown(element).perform();
browser.sleep(5000);
browser.actions().mouseUp(element).perform();

我们希望通过让 sleep() 成为 Action 链的一部分来理想地在一行中解决这个问题:

browser.actions().mouseDown(element).sleep(5000).mouseUp(element).perform();

显然,这行不通,因为有 no "sleep" action .

另一个实际例子可能是“类人打字”。例如:

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() Action 序列并引入自定义 Action ?


最佳答案

是的,您可以扩展操作框架。但是,严格来说,得到如下内容:

browser.actions().mouseDown(element).sleep(5000).mouseUp(element).perform();

意味着打乱 Selenium 的胆量。所以,YMMV。

请注意 Protractor documentation在解释操作时引用 webdriver.WebDriver.prototype.actions,我认为这意味着它不会修改或添加到 Selenium 提供的内容。

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;
};

否则, sleep 会乱序。您要做的是记录您想要的效果,以便稍后执行。

现在,要考虑的另一件事是默认的 .perform() 只期望执行 webdriver.Command,这是要发送到浏览器的命令。 sleep 不是这样的命令。因此必须修改 .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() 实现中,我用普通 JavaScript 替换了 Selenium 代码使用的 goog... 函数。

关于javascript - Protractor 中的自定义浏览器操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32789460/

相关文章:

javascript - D3.js多个GeoJSON对象

javascript 验证文本输入框中字母和数字的可变序列

java - 如何通过 Xpath 查询 Selenium 中的 HTML 元素?

python - 如何使用 Python 和 Selenium WebDriver 获取 localStorage

java - 如何处理登录页面中单击时 Selenium 报告为 "NOT visible"的 Web 元素

c# - Selenium 告诉我 ID 不存在

python - 用selenium python模拟一个onclick

javascript - 2页之间实时同步

python - 如何使用 Selenium 和 Python 将文本发送到电子邮件字段

javascript - "array is not a function"错误