Open mmorris8 opened 1 month ago
Disclaimer This information might be inaccurate, due to it being generated automatically
To verify that a component is emitting an event in Storybook for Angular, you can use the args
parameter in the play
function to listen for the event. Here's how you can modify your story to check if clickCount
was incremented:
import { Meta, StoryObj, moduleMetadata } from '@storybook/angular';
import { ButtonComponent } from './button.component';
import { userEvent, within } from '@storybook/testing-library';
const meta: Meta<ButtonComponent> = {
title: 'Button Test',
component: ButtonComponent,
tags: ['autodocs'],
decorators: [
moduleMetadata({
imports: []
})
]
};
export default meta;
type Story = StoryObj<ButtonComponent>;
export const Primary: Story = {
args: {},
play: async ({ canvasElement, args }) => {
const element = within(canvasElement);
const clickCountSpy = jest.fn();
args.clickCount = { emit: clickCountSpy };
userEvent.click(element.getByText('Click Me'));
expect(clickCountSpy).toHaveBeenCalledWith(1);
}
};
This code uses Jest to create a spy function that listens for the clickCount
event and verifies that it was called with the expected value.
/code/addons/docs/angular /code/frameworks/angular/src/client/docs/testfixtures/doc-button/argtypes.snapshot /code/frameworks/angular/template/stories/others/issues/12009-unknown-component.stories.ts /code/lib/cli/src/automigrate/fixes/angular-builders.ts /test-storybooks/ember-cli/ember-output/storybook-docgen /code/frameworks/ember/src/client/preview/docs /code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/reference-type-events /code/frameworks/angular/src/builders/build-storybook/index.spec.ts /.github/DISCUSSION_TEMPLATE/ideas.yml /code/frameworks/angular/template/stories/others/issues /code/core/src/manager-api/tests/stories.test.ts /code/frameworks/angular/src/builders/start-storybook/index.spec.ts /docs/_snippets/storybook-preview-with-angular-polyfills.md /code/lib/cli/src/automigrate/fixes/angular-builders.test.ts /docs/_snippets/storybook-interactions-step-function.md /docs/_snippets/custom-build-script-production.md /code/lib/cli/src/automigrate/fixes/angular-builders-multiproject.ts /.github/DISCUSSION_TEMPLATE/help.yml /docs/_snippets/button-story-hypothetical-example.md /docs/_snippets/checkbox-story-grouped.md /code/frameworks/angular/template/stories/basics/component-with-ng-content /code/lib/cli/src/automigrate/fixes/angular-builders-multiproject.test.ts /code/frameworks/angular/src/client/docs/testfixtures/doc-button/properties.snapshot /code/addons/docs/template/stories/docspage/override.stories.ts /docs/_snippets/my-component-story-mandatory-export.md
Ok, that wasn't entirely correct, but it pointed me in the correct direction to solve it.
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'cv-button',
standalone: true,
template: `
<button (click)="onClick()">Click Me</button>
`,
imports: [],
})
export class ButtonComponent {
private count = 0
@Output() clickCount = new EventEmitter<number>
onClick() {
this.count++
this.clickCount.emit(this.count)
}
}
import { Meta, StoryObj, moduleMetadata } from '@storybook/angular';
import { ButtonComponent } from './button.component';
import { userEvent, within, expect, fn } from '@storybook/test';
const meta:Meta<ButtonComponent> = {
title: 'Button Test',
component: ButtonComponent,
tags: ['autodocs'],
args: {
clickCount: fn()
},
decorators: [
moduleMetadata({
imports: []
})
]
}
export default meta
type Story = StoryObj<ButtonComponent>
export const Primary: Story = {
args: {},
play: async ({canvasElement, args}) => {
const element = within(canvasElement)
await userEvent.click(element.getByText('Click Me'))
expect(args.clickCount).toHaveBeenCalledWith(1)
await userEvent.click(element.getByText('Click Me'))
expect(args.clickCount).toHaveBeenCalledWith(2)
}
}
This example needs to be incorporated into the main documentation somewhere.
I've worked on this further (this is my personal github account, the thread was started from my work account). The above details on how to write stories that test angular event emitters, and have went beyond this to finally figure out how to build Reactive Form components and test them fully in Storybook. This weekend I would like to take that knowledge and put it up into a tutorial, probably using a github to demo the code.
Integrating Reactive Forms with Storybook tests has been a sore point, and I'd like to do what I can to make it less painful.
Got the first three chapters in place - https://github.com/michael-lloyd-morris/storybook-angular-reactive-forms/tree/main
Ok, now I have the first three chapters :\ I goofed yesterday and was counting branches - the main branch being the table of contents.
Describe the problem
I've looked for 10 hours. There is no documentation on how to verify that a component is emitting an event. Since this feature is intimate to how Angular works, particularly as part of two-way binding, it's absence is entirely unacceptable.
Given this component:
I can test the click with this story.
But there's no page on this site or anywhere on the net I've been able to find that clearly states how to check if the clickCount was incremented. I know it has to be possible - Storybook shows it is going up in the Actions inspector. But that inspector is entirely useless for an automated test.
Someone please help. This has been incredibly frustrating and has me on the verge of giving up using Storybook altogether with Angular, as being unable to test if components are actually emitting the values they are supposed to be emitting renders the whole exercise pointless.
Additional context
No response