我正在前端使用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
});
非常感谢您的帮助。
答案 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
请求是stubbed与fixtures一起使用的是标准赛普拉斯约定。
最后,这是赛普拉斯赛跑者的屏幕截图,当显示GET XHR STUB
时仅显示最初的orders
请求。请注意,order-status.js路由文件中使用的Ember的存储方法peekRecord
和findRecord
不会再产生任何XHR请求,并且不会引发任何错误。 Ember的商店运作正常。