You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Protractor中Promise异步执行顺序不符合预期的问题

问题根因

  • 循环未等待异步任务执行:selectElementAndCheckText是异步函数,你在for循环中调用时没有加await,导致循环会瞬间执行完5次函数调用,不会等前一次点击、页面加载、校验逻辑完成再执行下一次。相当于5次点击请求几乎同时触发,页面还没加载完前一个条目详情,下一次点击就已经生效,最终页面会停在最后一个点击的条目(simulated 100 emails)的详情页,所有后续的断言取到的页面标题都是最后这个条目的值,所以和前几个点击的条目名称匹配失败。
  • 异步函数逻辑设计错误:
    1. selectElementAndCheckText内部混用async/await和.then回调,且没有返回内部的异步任务Promise,就算外层加await也无法等待点击、校验逻辑执行完成。
    2. browser.wait(EC.visibilityOf(email_header_name), 5000)本身返回的是Promise,你直接用if (browser.wait(...))判断的是Promise对象本身的真值(永远为true),根本没有等待页面元素加载的逻辑执行完成,校验会提前触发。

修复方案

调整后代码

it('Test#5.5 - Select top 5 Email Dumps', async () => {
    let testId = 5.5;
    let timeKey = 'Select top 5 Email Dumps';
    console.time(timeKey);
    log.info('\n', 'Selecting top 5 Email Dumps one after one')
    for (let i = 0; i < 5; i++) {
      let email_dump_item = await element.all(by.xpath('//*[contains(@data-selenium,"email_dump_item")]/div/span')).get(i);
      // 加await等待单次操作全流程完成
      await selectElementAndCheckText(email_dump_item, testId + '_' + i)
    }
});

async function selectElementAndCheckText(obj, testId) {
    let email_dump_name = await obj.getText()
    log.info('Clicking on ' + email_dump_name + ' email dump')
    // 统一用await替代.then回调,逻辑更清晰
    await obj.click();
    const email_header_name = element(by.css('div[data-testid="data-dump-page"] > * .MuiToolbar-gutters'));
    // 等待元素加载完成,加await
    const isHeaderVisible = await browser.wait(EC.visibilityOf(email_header_name), 5000);
    if (isHeaderVisible) {
      const headerText = await email_header_name.getText();
      checkText(email_dump_name, headerText, 'Email details shown doesn\'t match with the selected Dump', testId)
      log.info("Pass")
      return true;
    } else {
      log.error('Email dump details not loaded')
      return false;
    }
}

async function checkText(actualText, expectedText, errorMessage, testId) {
    try {
      assert.equal(actualText, expectedText, errorMessage, '\n')
    } catch (error) {
      console.log(error);
      // 如果需要测试用例在断言失败时标记为失败,可以在这里再抛出错误
      // throw error;
    }
}

核心修改点

  1. for循环调用selectElementAndCheckText前加await,保证前一个条目点击、校验完全完成后,才会执行下一个条目的操作
  2. 去掉obj.click().then的回调写法,统一用await处理所有异步操作,逻辑更连贯,也避免了回调嵌套导致的异步时序问题
  3. 对browser.wait加await拿到实际的等待结果,再做判断,保证校验是在页面元素加载完成后才执行

内容的提问来源于stack exchange,提问作者Vin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 04:45:04