量角器按钮单击并在新选项卡中打开页面

Protractor Button Click and open page in new tab

我对 Protractor 还很陌生。 我正在尝试自动化一个场景,我点击一个按钮并在新选项卡中打开一个页面,然后我们需要在新页面中填充表单并提交。

问题:当我点击按钮打开新页面时。我的测试不会等待新页面加载并显示测试完成和成功消息。

我正在使用该按钮的简单点击事件来点击该按钮。

element(by.id("newPlan")).click()

我是不是漏掉了什么?我是否需要做一些事情以便我的测试等待新页面加载然后我可以执行一些功能?

您需要使用回调等待页面打开。从这个意义上尝试一下:

    element(by.id("newPlan")).click().then(function () {
        browser.getAllWindowHandles().then(function (handles) {
            newWindowHandle = handles[1]; // this is your new window
            browser.switchTo().window(newWindowHandle).then(function () {
                // fill in the form here
                expect(browser.getCurrentUrl()).toMatch(/\/url/);
            });
        });
    });

还有一个更方便的方法。只需使用 browser 对象上的函数。

element(by.id("newPlan")).click();
browser.sleep(10000);
browser.waitForAngular();
expect(browser.getCurrentUrl()).toMatch(/\/url/)

"确保新页面也是 AngularJS 页面" 老实说,这对我来说意义不大 :)

无论浏览器重定向到 page/app 的类型如何,测试都应该有效,不是吗?

如果您在非 angular 页面上访问新标签页 URL 时遇到问题,请尝试

browser.driver.getCurrentUrl();

而不是

browser.getCurrentUrl();

这是对我有用的解决方案,但我添加了一个 browser.sleep(500),以避免上述错误(UnknownError: unknown error: 'name' must be a nonempty细绳)。 问题是新句柄还没有。 单击后稍等片刻,即可打开新选项卡并使其处理程序可用。 是的,它增加了难看的睡眠,但睡眠时间很短...

element(by.id("newPlan")).click().then(function () {
        browser.sleep(500);
        browser.getAllWindowHandles().then(function (handles) {
            newWindowHandle = handles[1]; // this is your new window
            browser.switchTo().window(newWindowHandle).then(function () {
                // fill in the form here
                expect(browser.getCurrentUrl()).toMatch(/\/url/);
            });
        });
    });

这里是不使用 browser.sleep() 方法的实现。 函数 waitForNewWindow() 是使用 async and underscorejs 创建的。 其中async.until()方法用于同步调用getAllWindowHandles()

element(by.id("newPlan")).click()
    .then(function () {
        return waitForNewWindow();
    })
    .then(function (newWindowHandle) {
        browser.switchTo().window(newWindowHandle).then(function () {
            expect(browser.getCurrentUrl()).toMatch(/\/url/);
        });
    });

 /**
 * Wait for new window is opened
 *
 * @param {Object} [params]
 * @param {number} [params.runs] - number of tries
 * @param {number} [params.interval] - interval for launching getAllWindowHandles()
 *
 * @returns {webdriver.promise.Promise}
 */
function waitForNewWindow(params) {
    var currentHandles = [];
    var deferred = protractor.promise.defer();
    var finish;
    var newHandle;
    var numberOfRuns = 0;

    params = params ? params : {};
    params.runs = params.runs || 10;
    params.interval = params.interval || 1000;

    browser.driver.getAllWindowHandles()
        .then(function (handles) {
            currentHandles = handles;
        })
        .then(function () {
            async.until(
                // function that tests condition
                function () {
                    return newHandle || finish;
                },
                // function that is executed until test condition is true
                function (callback) {
                    browser.driver.getAllWindowHandles()
                        .then(function (newHandles) {
                            numberOfRuns++;

                            if (numberOfRuns > params.runs) {
                                finish = true;

                                return callback(null, newHandle);
                            }

                            if (currentHandles.length < newHandles.length) {
                                newHandle = _.difference(newHandles, currentHandles);

                                return callback(null, newHandle);
                            }

                            setTimeout(function () {
                                callback(null, newHandle);
                            }, params.interval);
                        });
                },
                // callback when test condition is true
                function (error, result) {
                    if (!result) {
                        return deferred.reject('New browser window hasn\'t been opened');
                    }

                    if (result.length > 1) {
                        return deferred.reject('More than one new browser window were opened');
                    }

                    deferred.fulfill(result.toString());
                }
            );
        });

    return deferred.promise;
};