-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test: Enhance the context with canvas when the test package is used #28368
Conversation
☁️ Nx Cloud ReportCI is running/has finished running commands for commit e9910ce. As they complete they will appear below. Click to see the status, the terminal output, and the build insights. 📂 See all runs for this CI Pipeline Execution ✅ Successfully ran 1 targetSent with 💌 from NxCloud. |
# Conflicts: # code/lib/preview-api/src/modules/preview-web/render/StoryRender.ts
code/lib/test/src/index.ts
Outdated
interface StoryContext { | ||
userEvent: ReturnType<typeof userEvent.setup>; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to add canvas
here as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Canvas is a special type in CSF, that gets augmented here:
storybook/code/lib/test/src/index.ts
Lines 19 to 26 in b9f4f04
declare module '@storybook/csf' { | |
interface Canvas extends Queries {} | |
interface StoryContext { | |
// TODO enable this in a later PR, once we have time to QA this properly | |
// userEvent: ReturnType<typeof userEvent.setup>; | |
} | |
} |
And therefore the StoryContext changes as well:
export interface StoryContext<TRenderer extends Renderer = Renderer, TArgs = Args>
extends StoryContextForEnhancers<TRenderer, TArgs>,
Required<StoryContextUpdate<TArgs>> {
loaded: Record<string, any>;
abortSignal: AbortSignal;
canvasElement: TRenderer['canvasElement'];
hooks: unknown;
originalStoryFn: StoryFn<TRenderer>;
viewMode: ViewMode;
step: StepFunction<TRenderer, TArgs>;
context: this;
canvas: Canvas;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think canvas
should be part of the CSF spec, to be honest. That makes CSF dependent on Testing Library which I don't think is desirable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, i agree, but it is not coupled, because canvas is empty interface in CSF, that can be implemented by addons such as @storybook/test
.
@@ -187,8 +187,8 @@ export class StoryRender<TRenderer extends Renderer> implements Render<TRenderer | |||
loaded: {}, | |||
step: (label, play) => runStep(label, play, context), | |||
context: null!, | |||
canvas: {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't it make more sense to set these to null
initially? Or perhaps a getter which throws an error when canvas isn't available because @storybook/test
isn't installed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make module augmentation work, I needed to implement it as an empty interface in CSF. Therefore according to typescript, it can not be null.
|
||
export default meta; | ||
|
||
export const canvas_is_equal_to_within_canvas_element = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not camelCase?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because iFindCamelCaseHarderToReadForLongerSentences
// TODO enable this in a later PR, once we have time to QA this properly | ||
// export const context_user_event_is_equal_to_user_event_setup = { | ||
// async play({ userEvent }) { | ||
// await expect(userEvent satisfies typeof globalUserEvent).toEqual(globalUserEvent.setup()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect this won't be equal, as setup()
supposedly creates a new instance of UserEvent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but toEqual
doesn't check for reference. Structurally it was equal.
Co-authored-by: Gert Hengeveld <info@ghengeveld.nl>
What I did
The CSF pull request is here:
ComponentDriven/csf#99
Following up on #28353
Now the context is always the same reference throughout loaders and the play function, we can enhance the context in the
@storybook/test
package:storybook/code/lib/test/src/index.ts
Lines 101 to 107 in b9f4f04
We are adding
canvas
as just a shortcut forwithin(canvasElement)
.In a later PR we will add
userEvent
as a shortcut foruserEvent.setup()
which is a best practice in userEvent, see this issue:#17988
We use module augmentation to enhance the types when the test package is used:
storybook/code/lib/test/src/index.ts
Lines 20 to 26 in b9f4f04
I needed unbundle the
@storybook/csf
package to get module augmentation to work.We won't document this feature until 9.0, but we will use this feature as part of the mount context property. As
await mount()
will returncontext.canvas
whenever the test package is used. This return type will contain all the queries of testing library.Testing
The changes in this PR are covered in the following automated tests:
Manual testing
This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!
Documentation
MIGRATION.MD
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal
,ci:merged
orci:daily
GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli/src/sandbox-templates.ts
Make sure this PR contains one of the labels below:
Available labels
bug
: Internal changes that fixes incorrect behavior.maintenance
: User-facing maintenance tasks.dependencies
: Upgrading (sometimes downgrading) dependencies.build
: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup
: Minor cleanup style change. Will not show up in release changelog.documentation
: Documentation only changes. Will not show up in release changelog.feature request
: Introducing a new feature.BREAKING CHANGE
: Changes that break compatibility in some way with current major version.other
: Changes that don't fit in the above categories.🦋 Canary release
This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the
@storybookjs/core
team here.core team members can create a canary release here or locally with
gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>