如何解决Protractor中Promise异步执行顺序不符合预期的问题
问题根因
- 循环未等待异步任务执行:
selectElementAndCheckText是异步函数,你在for循环中调用时没有加await,导致循环会瞬间执行完5次函数调用,不会等前一次点击、页面加载、校验逻辑完成再执行下一次。相当于5次点击请求几乎同时触发,页面还没加载完前一个条目详情,下一次点击就已经生效,最终页面会停在最后一个点击的条目(simulated 100 emails)的详情页,所有后续的断言取到的页面标题都是最后这个条目的值,所以和前几个点击的条目名称匹配失败。 - 异步函数逻辑设计错误:
selectElementAndCheckText内部混用async/await和.then回调,且没有返回内部的异步任务Promise,就算外层加await也无法等待点击、校验逻辑执行完成。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; } }
核心修改点
- for循环调用
selectElementAndCheckText前加await,保证前一个条目点击、校验完全完成后,才会执行下一个条目的操作 - 去掉
obj.click().then的回调写法,统一用await处理所有异步操作,逻辑更连贯,也避免了回调嵌套导致的异步时序问题 - 对
browser.wait加await拿到实际的等待结果,再做判断,保证校验是在页面元素加载完成后才执行
内容的提问来源于stack exchange,提问作者Vin
相关产品推荐
相关产品推荐

