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

Jasmine fit步骤方法执行顺序异常及异步逻辑问题排查

问题根源:异步代码未正确等待导致执行顺序混乱

你遇到的问题核心是Protractor(基于WebDriverJS)的异步特性没有被正确处理。所有和浏览器交互的操作(比如wait、isPresent、click)都是异步的,返回Promise对象,但你的代码没有等待这些异步操作完成就继续执行后续逻辑,同时依赖全局变量finalResult传递状态,这就导致takeDecision在housingLoanWithoutCoApplicant里的异步操作还没完成时就执行了。

分步修复方案

1. 重构getDecision:返回Promise传递状态,移除全局变量依赖

把嵌套的then改成链式调用,让每个异步步骤都返回Promise,最终将决策状态通过Promise resolve传递出来,不再依赖全局变量:

getDecision: function() { 
  // 等待页面可见后,开始判断状态
  return browser.wait(protractor.ExpectedConditions.visibilityOf(decisionPage), 60000)
    .then(() => {
      // 先判断是否被拒绝
      return element(by.xpath(rejectImage)).isPresent();
    })
    .then((isRejected) => {
      if (isRejected) { 
        console.log('Application is rejected'); 
        return 'Rejected'; 
      } 
      // 未拒绝则判断是否进入队列
      return element(by.xpath(queueImage)).isPresent();
    })
    .then((isInQueue) => {
      if (isInQueue) { 
        console.log('Application is sent to underwriter for review'); 
        return 'Queue'; 
      } 
      // 既未拒绝也未进队列,就是批准状态
      console.log('Application is approved'); 
      return 'Approved'; 
    });
}

2. 修改returnDecision:返回Promise而非直接读取全局变量

现在returnDecision需要调用getDecision并返回它的Promise,确保拿到的是已经完成异步判断后的状态:

returnDecision: function() { 
  return this.getDecision().then((result) => {
    console.log('Result is::' + result); 
    return result;
  });
},

3. 重构takeDecision:用async/await等待异步操作完成

Protractor支持ES6的async/await语法,能让异步代码看起来像同步代码,避免嵌套地狱,同时确保每一步操作完成后再执行下一步:

takeDecision: async function(testData) { 
  // 等待决策状态返回
  const decisionStatus = await this.returnDecision();
  
  if (decisionStatus === 'Queue') { 
    if (testData.croDecision.apprvDecision === "Approve") { 
      await utils.sleep(2); 
      const approveButton = await browser.driver.findElement(By.css(croApproveButton)); 
      await approveButton.click(); 
    } else { 
      const declineButton = await browser.driver.findElement(By.css(croDeclineButton)); 
      await declineButton.click(); 
      await utils.sleep(2); 
      await browser.driver.findElement(By.xpath(remarkDecline)).sendKeys('for testing purpose'); 
    } 
    await utils.sleep(2); 
    await browser.driver.findElement(By.linkText("Submit")).click(); 
    await utils.sleep(2); 
    const successMsgElement = await browser.driver.findElement(By.xpath(decisionSuccessMessage));
    expect(await successMsgElement.isDisplayed()).toBe(true); 
  } else { 
    console.log("Case is rejected, no further action"); 
  } 
},

4. 修改Spec文件:确保housingLoanWithoutCoApplicant完成后再调用takeDecision

假设housingLoanWithoutCoApplicant内部也包含异步操作,需要让它返回Promise(或改成async函数),然后在测试用例里用await等待它执行完成:

fit('test', async function() { 
  testData.loan.existingloan = 'No'; 
  // 等待房贷申请流程完全完成
  await this.actionwords.housingLoanWithoutCoApplicant(testData); 
  // 再执行决策操作
  await this.actionwords.takeDecision(testData); 
});

核心思路总结

  • 永远不要用全局变量传递异步操作的结果,要用Promise的返回值来传递
  • 所有涉及浏览器交互的操作必须等待完成(用then链或async/await)
  • 确保每个业务函数都返回Promise,这样调用者可以明确等待它执行完毕

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:55:03