我正在尝试测试一个角度组件的输出。
我有一个checkbox组件,它使用EventEmitter输出值。checkbox组件封装在一个故事故事中,用于演示和测试:
export const basic = () => ({
moduleMetadata: {
imports: [InputCheckboxModule],
},
template: `
<div style="color: orange">
<checkbox (changeValue)="changeValue($event)" [selected]="checked" label="Awesome">
</checkbox>
</div>`,
props: {
checked: boolean('checked', true),
changeValue: action('Value Changed'),
},
});
我正在使用一个操作来捕获值更改并将其记录到屏幕上。
然而,在为这个组件编写cypress e2e时,我只使用了iFrame,而不是整个故事书应用程序。
我想找到一种方法来测试输出是否正常工作。我尝试在iFrame中对postMessage方法使用间谍程序,但不起作用。
beforeEach(() => {
cy.visit('/iframe.html?id=inputcheckboxcomponent--basic', {
onBeforeLoad(win) {
cy.spy(window, 'postMessage').as('postMessage');
},
});
});
然后,断言将是:
cy.get('@postMessage').should('be.called');
有没有其他方法可以让我断言(changeValue)="changeValue($event)"
已经启动?
发布于 2021-03-22 20:23:16
方法1:模板
我们可以将最后发出的值绑定到模板并对其进行检查。
{
moduleMetadata: { imports: [InputCheckboxModule] },
template: `
<checkbox (changeValue)="value = $event" [selected]="checked" label="Awesome">
</checkbox>
<div id="changeValue">{{ value }}</div> <!-- ❗️ -->
`,
}
it("emits `changeValue`", () => {
// ...
cy.get("#changeValue").contains("true"); // ❗️
});
方法2:窗口
我们可以将最后发出的值分配给全局window
对象,在Cypress中检索它并验证该值。
export default {
title: "InputCheckbox",
component: InputCheckboxComponent,
argTypes: {
selected: { type: "boolean", defaultValue: false },
label: { type: "string", defaultValue: "Default label" },
},
} as Meta;
const Template: Story<InputCheckboxComponent> = (
args: InputCheckboxComponent
) =>
({
moduleMetadata: { imports: [InputCheckboxModule] },
component: InputCheckboxComponent,
props: args,
} as StoryFnAngularReturnType);
export const E2E = Template.bind({});
E2E.args = {
label: 'E2e label',
selected: true,
changeValue: value => (window.changeValue = value), // ❗️
};
it("emits `changeValue`", () => {
// ...
cy.window().its("changeValue").should("equal", true); // ❗️
});
方法3: Angular
我们可以使用存储在ng
下的全局名称空间中的Angular's functions,以便获得对Angular组件的引用并监视输出。
⚠️注意事项:
只有当Angular在开发模式下运行时,
ng.getComponent()
才可用。也就是说,没有调用enableProdMode()
。.storybook/main.js
中设置process.env.NODE_ENV = "development";
,以防止Storybook在prod模式下构建Angular (参见source).export const E2E = Template.bind({});
E2E.args = {
label: 'E2e label',
selected: true,
// Story stays unchanged
};
describe("InputCheckbox", () => {
beforeEach(() => {
cy.visit(
"/iframe.html?id=inputcheckboxcomponent--e-2-e",
registerComponentOutputs("checkbox") // ❗️
);
});
it("emits `changeValue`", () => {
// ...
cy.get("@changeValue").should("be.calledWith", true); // ❗️
});
});
function registerComponentOutputs(
componentSelector: string
): Partial<Cypress.VisitOptions> {
return {
// https://docs.cypress.io/api/commands/visit.html#Provide-an-onLoad-callback-function
onLoad(win) {
const componentElement: HTMLElement = win.document.querySelector(
componentSelector
);
// https://angular.io/api/core/global/ngGetComponent
const component = win.ng.getComponent(componentElement);
// Spy on all `EventEmitters` (i.e. `emit()`) and create equally named alias
Object.keys(component)
.filter(key => !!component[key].emit)
.forEach(key => cy.spy(component[key], "emit").as(key)); // ❗️
},
};
}
摘要
,
@Output
添加。此外,它使用全局window
,以便"communicate".cy.visit()
(它很可能已经被使用了),以便能够执行检查。因此,如果我们想通过Storybook的iframe
测试更多的组件,它感觉是一个可扩展的解决方案。最后但并非最不重要的一点是,我们检索一个对Angular组件的引用。这样,我们还可以直接在组件本身上调用方法或设置属性。这与ng.applyChanges
结合似乎为额外的测试用例打开了一些大门。发布于 2020-08-18 18:49:58
您正在监视window.postMessage()
,这是一种在窗口对象(弹出窗口、页面、iframes等)之间实现跨域通信的方法。
Storybook中的iFrame不会将任何消息传递给另一个窗口对象,但您可以在应用程序上安装Kuker或其他外部web调试器来监视两者之间的消息,从而使Cypress spy方法工作。
如果您选择在您的angular应用程序上安装Kuker,以下是如何执行此操作:
npm install -S kuker-emitters
添加Kuker Chrome扩展以使其正常工作。
发布于 2021-07-29 22:17:20
如果你正在使用cypress-storybook包和@storybook/addon-actions,有一种方法可以用于这个用例,在我看来,它提供了最简单的解决方案。
使用Storybook-actions插件,您可以像这样声明@Output事件
export default {
title: 'Components/YourComponent',
component: YourComponent,
decorators: [
moduleMetadata({
imports: [YourModule]
})
]
} as Meta;
const Template: Story<YourStory> = (args: YourComponent) => ({
props: args
});
export const default = Template.bind({});
default.args = {
// ...
changeValue: action('Value Changed'), // action from @storybook/addon-actions
};
在您的cypress测试中,您现在可以调用cy.storyAction()
方法并对其应用expect语句。
it('should execute event', () => {
// ...
cy.storyAction('Value Changed').should('have.been.calledWith', 'value');
})
https://stackoverflow.com/questions/63462886
复制相似问题