Skip to content
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

Refactor Visual Tests stories to more closely control selected story #124

Conversation

tmeasday
Copy link
Member

@tmeasday tmeasday commented Oct 3, 2023

This PR does 2 main things:

  1. Refactor VisualTests so the selectedBuildId is a prop. This allows us to continue to write stories that vary the selectedBuild + lastBuildOnBranch without having weird stuff happen with the selectedBuildId. It also allows us to clearly assert on when the component should change the selectedBuildId in play functions[1].

  2. Refactor the stories to use an args based approach and be very careful about the builds we pass. I'm pretty happy with how the stories end up reading but open to feedback.

[1] This also exposed a bug in how we are doing it right now that I'll fix in a follow up PR (#130)


Old text:

So the behaviour was actually right here, but the story didn't show it.

Let me explain because I think we might want to consider tightening up our testing strategy here.

  • We have a bunch of stories that hard code the returned lastBuildOnBranch and selectedBuild.
  • However, the VisualTests component changes the selectedBuildId variable based on various criteria.
  • This was not reflected in the stories as the selectedBuild was hard-coded.

For the older story Empty Branch Local Build Captured Current Story we fudge around this, because we set the selectedBuild to the lastBuildOnBranch when there is no selectedBuild:

// Before we set the storyInfo, we use the lastBuildOnBranch for story data if it's ready
const selectedBuild = getFragment(
FragmentSelectedBuildFields,
data?.selectedBuild ??
(lastBuildOnBranchCompletedStory ? data?.project?.lastBuildOnBranch : undefined)
);

However, that doesn't help us for the newer, similar story Story Added In Last Build On Branch Not In Selected because the selected build does exist, it just doesn't have this story.

So the fix here is to make the GraphQL mock actually respond to the change in selectedBuildId. My question for y'all is: Should we, to be correct, make that change to all these stories? Or is this whole approach of testing the VisualTests component wrong and we should just write stories at the presentational level and do some other type of testing of "what happens when the selectedStoryId changes?" or "what happens when there's a new lastBuildOnBranch?"

Possibly we drop the quoted lines above too as it's sort of confusing there are two ways the selectedBuild ends up being equal to the lastBuildOnBranch. (Firstly by the short cut above, secondly by setting selectedBuildId, requerying, and re-rendering). Then again the shortcut saves the user waiting for a second query.

Another option would be to extend the logic to make selectedBuild = lastBuildOnBranch if the current story isn't in the actual selected build. Confusing?

📦 Published PR as canary version: 0.0.106--canary.124.6cd88ba.0

✨ Test out this PR locally via:

npm install @chromaui/[email protected]
# or 
yarn add @chromaui/[email protected]

@linear
Copy link

linear bot commented Oct 3, 2023

AP-3703 Auto switch to latest if story is on latest build, but not on selected build

Currently, if a user is on a story that exists on the last build on the branch, but not on the locally selected build, it will still display "new story ui". To refresh it, they need to change out of the story and back.

Instead, if the story is on the latest selected build, we should automatically change to the latest build.

https://www.chromatic.com/review?appId=6480e1b0042842f149cfd74c&number=101&activeElementId=comment-thread-650e6df037c742aeeaf18086

Copy link
Contributor

@weeksling weeksling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for delayed review. This story makes sense to me. I'm not sure about changing every story to have a function but if the change could be handled in the withBuilds method then it makes sense.

Now that I understand them a bit better, I think a high level mock is useful. For edge cases and interactions presentational stories might work well but I think this issue for instance might have been hard to test without a graphql mock that mimics our api even if it required changing.

The story looks good to me. I can comment on the other questions mentioned tomorrow after a night's rest.

@ghengeveld
Copy link
Member

So the fix here is to make the GraphQL mock actually respond to the change in selectedBuildId. My question for y'all is: Should we, to be correct, make that change to all these stories? Or is this whole approach of testing the VisualTests component wrong and we should just write stories at the presentational level and do some other type of testing of "what happens when the selectedStoryId changes?" or "what happens when there's a new lastBuildOnBranch?"

I prefer the "integration test" style of stories over the pure presentational level, because it showcases what Storybook can do rather than copping out, while also providing us with better coverage. So I think the approach taken here is desirable. "some other type of testing" would likely mean E2E which I'd like to avoid if possible.

@tmeasday
Copy link
Member Author

tmeasday commented Oct 6, 2023

Ok, so it sounds like the consensus here is to apply this approach to the other stories in the VisualTests component. I'll take another pass at it.

@tmeasday tmeasday force-pushed the tom/ap-3703-auto-switch-to-latest-if-story-is-on-latest-build-but-not-on branch from 0030d1e to 88957c9 Compare October 10, 2023 00:10
@tmeasday tmeasday requested a review from ghengeveld October 12, 2023 05:26
@tmeasday tmeasday changed the title Ensure story shows we switch to latest build on new story Refactor Visual Tests stories to more closely control selected story Oct 12, 2023
Comment on lines +577 to +600
// NOTE: this does not current work, the story is auto-selected
// play: async ({ canvasElement, args, argsByTarget }) => {
// // We have to wait a moment for the story to render
// const canvas = within(canvasElement);
// await canvas.findAllByText("Latest");

// // Ensure we don't switch to the new build, the user has to opt-in
// mock(args.setSelectedBuildInfo!).mock.calls.forEach(([updater]) => {
// const result = typeof updater === "function" ? updater(args.selectedBuildInfo) : updater;
// expect(result).toEqual(args.selectedBuildInfo); // Unchanged
// });

// // Now opt in
// const viewLatestSnapshot = (await canvas.findAllByText("View latest snapshot"))[0];
// await userEvent.click(viewLatestSnapshot);

// const graphqlArgs = argsByTarget.graphql?.$graphql as typeof args.$graphql; // We need to type argsByTarget
// await waitFor(() => {
// expect(args.setSelectedBuildInfo).toHaveBeenCalledWith({
// buildId: graphqlArgs?.AddonVisualTestsBuild?.lastBuildOnBranch?.id,
// storyId: meta.args.storyId,
// });
// });
// },
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted this play function is disabled here (and in 2 other tests) but fixed in #130

Copy link
Member

@ghengeveld ghengeveld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I like this approach 👍

@tmeasday tmeasday merged commit dff886b into main Oct 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants