【问题标题】:How to wait for URL to load after button click in protractor?在量角器中单击按钮后如何等待 URL 加载?
【发布时间】:2017-11-09 19:27:49
【问题描述】:

我正在使用量角器对 Angular 2 项目进行端到端测试,并且需要测试登录操作。这里的问题是,当单击登录按钮时,expect 语句仍然会获取登录页面的 URL,因为它应该是主页。如果我等待,那么测试成功。我在文档中的某处读到量角器等待进程自动完成,所以,

  1. 是什么导致了这个错误?
  2. 如何在不显式使用wait() 方法的情况下正确执行操作?
  3. 量角器是否有类似于fakeAsyncasync 或至少whenStable 之类的单位 测试?

这是我的测试用例

it("User successfully login",()=>{
    browser.get(browser.baseUrl + '/account/login').then(() => {
        return expect(browser.getCurrentUrl()).toBe(browser.baseUrl +  "/account/login")
    }).then(()=>{
        element(by.tagName('input[type=text]')).sendKeys('username');
        element(by.tagName('input[type=password]')).sendKeys('password');
        element(by.css('button[type=submit]')).click().then(()=>{
            return expect(browser.getCurrentUrl()).toBe(browser.baseUrl + "/home");
        });

    });
});

注意:

  1. 我有指示避免使用browser.wait() 方法。
  2. 登录按钮通过 API 向后端发送 http 请求。

变通解决方案[基于 Ernst 的解决方案]:

我解决了这个问题。我不知道它是否适用于其他场景,或者它是否是正确的方法。我加了

browser.wait(EC.urlContains(browser.baseUrl + "/account/login"), 10000);
browser.waitForAngularEnabled(false);
browser.wait(EC.urlContains(browser.baseUrl + "/home");

就在 click() 事件之后,它现在似乎可以工作。

【问题讨论】:

    标签: angular typescript protractor end-to-end


    【解决方案1】:

    导致错误的原因:

    click() 返回一个承诺,量角器等待解决。当登录请求被发送到服务器而不是加载主页时,它可能已经解决了。因此,在页面加载之前就开始执行下一步。

    为什么不wait()

    我不确定,你得到不使用browser.wait() 的指令的依据是什么。很可能您不应该使用browser.sleep()(因为该命令总是过时的),但如果您不想使用browser.wait(),您的开发人员可能不会离开最初打开的Angular Page。

    fakeAsyncwhenStable 等:

    Protractor 在browser.waitForAngular() 中默认使用whenStable,它总是在promise 之后调用,只要你没有关闭browser.waitForAngularEnabled(false)...你只需要关闭非角度页面或者如果您的开发人员使用即持久的宏任务,这将导致超时。

    此外,由于 Selenium 控制流可能会在 2018 年 11 月被弃用 (read about here),因此有 async/await 可用。 Read this important guide here 还有一些further infos from protractor about it here

    现在是你的情况:

    您不需要在您的情况下使用then()s,因为您不需要立即解决承诺。 expect() 会自动解决你的承诺,所以那里不需要then()

    事实上,Protractor 逐行执行所有命令,就好像它们都被包裹在then()s 中一样,所以它会自动保持你的执行同步(只要你不使用then() 启动异步任务)代码。

    所以这是我对您的代码的建议:

    it("User successfully login",()=>{
        var EC = protractor.ExpectedConditions;  //or within onPrepare() of conf.js put global.EC = protractor.ExpectedConditions ... to make it everywhere available.
        browser.get(browser.baseUrl + '/account/login');
        //next line lets protractor wait max 5 seconds for your url to become, what you want.
        browser.wait(EC.urlContains(browser.baseUrl +  "/account/login"), 5000);
        //additionally after the URL appeared, use this command to wait until the page is fully loaded.
        browser.waitForAngular();
        expect(browser.getCurrentUrl()).toBe(browser.baseUrl +  "/account/login");
        element(by.tagName('input[type=text]')).sendKeys('username');
        element(by.tagName('input[type=password]')).sendKeys('password');
        element(by.css('button[type=submit]')).click();
        //next line lets protractor wait max 5 seconds for your url to become, what you want.
        //as here a new page is loaded and the click()-promise is resolved before, use this:
        browser.wait(EC.urlContains(browser.baseUrl +  "/account/login"), 5000);
        //additionally after the URL appeared, use this command to wait until the page is fully loaded.
        browser.waitForAngular();
        expect(browser.getCurrentUrl()).toBe(browser.baseUrl + "/home");
    });
    

    如果您现在超时,那么这是一个单独的调试问题。 查看this Protractor site for infos about timeoutsthis SO-Answer here 了解如何调试超时。

    【讨论】:

    • 结果仍然不一致...有时成功或失败。我试图增加等待间隔。但结果是一样的
    • 在这种情况下,请同时使用两个等待。首先等待 URL 正确,然后让 Protractor 等待,直到所有的 Promise 都解决。所以使用两条线browser.wait(EC.urlContains(browser.baseUrl + "/account/login"), 5000); browser.waitForAngular(); ... evtl。在两个browser.get() 命令之后
    • 现在测试继续等待。它不会停止。
    • 因为browser.waitForAngular() 只是使用whenStable,这意味着页面还不稳定。原因可能是持续轮询$timeout,或者如果使用 Angular(不是 AngularJS),它可能是宏任务。我添加了链接以查找有关超时以及如何调试它们的信息。
    • 更正:.then() 是多余的,但不是问题。执行仍然是同步的,因为 WebDriver 有一个与控制流集成的修改过的承诺管理器。请参阅selenium-webdriver promise docu中的“ManagedPromise 集成”部分
    猜你喜欢
    • 2014-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-06
    • 1970-01-01
    相关资源
    最近更新 更多