灰烬和柏树|集成测试失败可能是由于缺少商店上下文

时间:2018-11-22 00:33:37

标签: ember.js integration-testing cypress

我正在前端使用Ember.js,并使用Cypress.io进行集成测试。我有一个“订单状态”按钮,单击后应该可以使用商店中的数据访问特定的订单并导航到“订单状态”页面。

但是在测试中,从模式中单击后,“订单状态”页面无法加载,我的测试抛出this error

  

TypeError:无法读取null的属性“ _internalModel”

...在控制台中,我认为这可能与该路线的模型没有从存储和装载中找到订单有关。

在赛普拉斯测试中,我创建了必要的路由来传递会话数据,但是努力了解缺少存储数据是否会引发此错误,以及如何解决该错误。需要特别注意的是,整个流程本身可以100%起作用-我只是想获得测试覆盖率。

我将在下面附上相关文件/功能的摘录-如果需要更多信息,请告诉我。我真的怀疑赛普拉斯无法进入Ember商店,但是经过大量研究和试验,我不确定是什么问题。

order-status.js -路线中的模型函数

async model({ order_id: orderId }) {
    let cachedOrder = this.get('store').peekRecord('order', orderId);
    return cachedOrder
      ? cachedOrder
      : await this.get('store').findRecord('order', orderId);
  },

modal.hbs -我们从当前页面导航至订单状态路线

<fieldset>
  <span class="modal-text">See order status</span>
  <div class="inline-button-wrap">
    <button 
      {{action 'decline'}} 
      class="close-btn button-hollow-green">
        Close
    </button>
    <button 
      {{action 'accept'}} 
      class="order-status-btn">
       Order Status
     </button>
  </div>
</fieldset>

test.js -模拟上方点击订单状态按钮的测试

it('order status btn navigates to order status page', () => {
  cy.server();
  cy.route('GET', '/api/session', sessionResponse);
  cy.route('GET', `/api/orders/*`, order);
  cy.visit('/');
  cy.get('.delivery-card .button-cta').click(); //opens modal 
  cy.get('#modal .order-status-btn').click(); //navigates to order-status
});

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

不论是否请求API,Ember的存储与赛普拉斯一起使用时都应表现出预期的效果。提到的错误是主要问题的好线索-未定义的模型。目前尚不清楚在Cypress测试失败并引发错误时您的应用程序是如何工作的,但是应该进行一些更改(某些更改在Ember中,某些更改在Cypress中)。这是解决此问题的细分(根据提供的代码示例进行的一些逆向工程/假设)...

通过打开模式的按钮操作(在交付卡HTML标记中),按顺序id发送:

<button class="button-cta" {{action 'openModal' order.id}}>
  Open Order Status Modal
</button>

在过渡时,openModal动作沿顺序id作为model的参数在随后的mod a l路由上传递。在 delivery-card.js 控制器中:

actions: {
  openModal(id) {
    this.transitionToRoute('modal', id); // <-- id
  }
}

然后,模态的accept动作在转换时也会沿着id传递到订单状态页面。在 modal.js 控制器中:

actions: {
  accept() {
    this.transitionToRoute('order-status', this.get('model.id')); // <-- here
  },

  decline() {
  ...

此外,在 order-status.js 中,传递给模型挂钩的参数可以简化为params

async model(params) { // <-- just use params
  const id = params.id; // <-- id
  const cachedOrder = this.get('store').peekRecord('order', id); // <-- id

  return cachedOrder
    ? cachedOrder
    : await this.get('store').findRecord('order', id); // <-- id
}

最后,对 test.js 进行了一些更改:

it('order status btn navigates to order status page', () => {

  cy.server();
  cy.route('GET', `/api/session`, 'fixture:session.json'); // <-- here
  cy.route('GET', `/api/orders`, 'fixture:orders.json');   // <-- here
  cy.visit('/');
  cy.get('.delivery-card .button-cta').click(); // opens modal
  cy.get('#modal .order-status-btn').click(); // navigates to order-status

  // here, verify that an order status is displayed
  cy.get('.current-status')
    .should(($el) => {
      const statusTextValue = $el[0].innerText;
      expect(statusTextValue).to.not.be.empty;
    });

});

API GET请求是stubbedfixtures一起使用的是标准赛普拉斯约定。

最后,这是赛普拉斯赛跑者的屏幕截图,当显示GET XHR STUB时仅显示最初的orders请求。请注意,order-status.js路由文件中使用的Ember的存储方法peekRecordfindRecord不会再产生任何XHR请求,并且不会引发任何错误。 Ember的商店运作正常。

enter image description here