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

RFC: SSR testing for @fluentui/react-components #22788

Merged
merged 1 commit into from
Jun 8, 2022

Conversation

layershifter
Copy link
Member

@layershifter layershifter commented May 3, 2022

We are targeting first class support for SSR in @fluentui/react-components, #17893. The missing piece is automated testing to prevent our components from breaking due changes.

This RFC is focused on the implementation proposal for such test.


Rendered preview

@layershifter layershifter added the Type: RFC Request for Feedback label May 3, 2022
@codesandbox-ci
Copy link

codesandbox-ci bot commented May 3, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 7cb877f:

Sandbox Source
@fluentui/react 8 starter Configuration
@fluentui/react-components 9 starter Configuration

@fabricteam
Copy link
Collaborator

fabricteam commented May 3, 2022

📊 Bundle size report

🤖 This report was generated against 79bbe380acd510fc68cfbca260853c5ca635368b

@size-auditor
Copy link

size-auditor bot commented May 3, 2022

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: 2af65fc29bde3dfac8177db7acef39075e28b264 (build)

@layershifter layershifter marked this pull request as ready for review May 4, 2022 07:52
@layershifter layershifter requested review from Hotell and a team May 4, 2022 07:53
- Start Chrome (via `puppeteer`)
- **Note**: the latest version of Puppeteer will be used to get latest Chrome. Existing version in our repo does not support even `:focus-visible` (that creates false positive errors)
- Open a page (`index.html` file)
- **Note**: Webserver will not be used, a file will be opened via `file://`
Copy link
Member

Choose a reason for hiding this comment

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

will file:// support all OS ?

Copy link
Contributor

Choose a reason for hiding this comment

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

For the purposes of this test, is the behavior of a page loaded from file:// any different from one served by a webserver?

Copy link
Member Author

Choose a reason for hiding this comment

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

will file:// support all OS ?

It should work on every major platform (I tested Mac & Windows), https://en.wikipedia.org/wiki/File_URI_scheme

For the purposes of this test, is the behavior of a page loaded from file:// any different from one served by a webserver?

No.

Copy link
Contributor

@spmonahan spmonahan left a comment

Choose a reason for hiding this comment

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

Really like this proposal -- especially that it reuses all the existing Storybook stories.

- A page will have configured interceptors to avoid loading resources (images) from CDN
- Ensure that there are no errors, otherwise test fails
- **Note**: For this reason the test app will run with `process.NODE_ENV = 'development'`
- **Note**: _Probably_ there is sense to restrict the test to catch only SSR related errors (in prototype it fails also on missing React keys, for example)
Copy link
Contributor

Choose a reason for hiding this comment

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

I see why we might want to restrict to only SSR errors but it might be better to start by casting a wider net and fail on any error. Sure, the React keys example doesn't have anything to do with SSR but the fact that our story triggered the warning means the story wasn't demonstrating best practices so, imo, it's good that it failed even though that's not the explicit point of this test suite.

If we see lots of errors unrelated to SSR failing this test suite then I'd be in favor or restricting our failure modes.

Copy link
Contributor

Choose a reason for hiding this comment

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

but the fact that our story triggered the warning means the story wasn't demonstrating best practices so,

If our stories produce those kind of warnings that should be handled by logic that triggers production builds of those stories -> public-docsite-v9. Also these can/should be covered by lint.

Copy link
Member Author

Choose a reason for hiding this comment

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

I see why we might want to restrict to only SSR errors but it might be better to start by casting a wider net and fail on any error. Sure, the React keys example doesn't have anything to do with SSR but the fact that our story triggered the warning means the story wasn't demonstrating best practices so, imo, it's good that it failed even though that's not the explicit point of this test suite.

While I agree with this, I don't see that it's a goal of this test. As @Hotell it should be covered by a different tooling.

- Start Chrome (via `puppeteer`)
- **Note**: the latest version of Puppeteer will be used to get latest Chrome. Existing version in our repo does not support even `:focus-visible` (that creates false positive errors)
- Open a page (`index.html` file)
- **Note**: Webserver will not be used, a file will be opened via `file://`
Copy link
Contributor

Choose a reason for hiding this comment

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

For the purposes of this test, is the behavior of a page loaded from file:// any different from one served by a webserver?

export const Stories = () => (
<SSRProvider>
<FluentProvider theme={teamsLightTheme}>
<TextTruncate />
Copy link
Contributor

Choose a reason for hiding this comment

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

What is a report for an SSR test going to look like?

In the example all the stories for a component are in a single test but it's possible that only one story triggers an SSR failure. If all the stories are grouped into a single test it could be frustrating to debug a failure.

Copy link
Contributor

Choose a reason for hiding this comment

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

thats good point. IMO we can provide a solution afterwards. the main point of this is that we are living in the dark in terms if things work or not. I'd rather have this in our pipelines ASAP and tweak detail later if it makes sense.

Copy link
Member Author

Choose a reason for hiding this comment

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

In the example all the stories for a component are in a single test but it's possible that only one story triggers an SSR failure. If all the stories are grouped into a single test it could be frustrating to debug a failure.

Reporting problems is a good point. I would agree with @Hotell that it's important to have gates first.

From the errors that I have seen React usually shows which component in a tree caused a failure. I will make this test runnable locally for sure, so it will be possible to check/debug issues locally without CI.

## Pros and Cons

- 👍 It's fast (3 seconds to run the whole test)
- 👍 We will reuse existing stories
Copy link
Contributor

Choose a reason for hiding this comment

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

Really like this part!


## Pros and Cons

- 👍 It's fast (3 seconds to run the whole test)
Copy link
Contributor

Choose a reason for hiding this comment

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

Will it be possible to run this test suite locally while working on a component?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see reason why it would not be possible? puppeter will be already installed on your machine. it will also download proper chrome binary when executing so everything should work as intended. What would be nice for local development would be ability to execute that ssr solely for component you're working on. but ATM taking into consideration the speed of running it for everything in one shot is making that a low prio.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will it be possible to run this test suite locally while working on a component?

Yes, it will be something like yarn build && yarn test in that package. So no hot reload or something like, but it should be a fast loop.

but ATM taking into consideration the speed of running it for everything in one shot is making that a low prio.

Yeah, that's why I ignored scoping part 🐱

Copy link
Contributor

@Hotell Hotell left a comment

Choose a reason for hiding this comment

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

🚀

rfcs/shared/build-system/ssr-testing.md Show resolved Hide resolved
export const Stories = () => (
<SSRProvider>
<FluentProvider theme={teamsLightTheme}>
<TextTruncate />
Copy link
Contributor

Choose a reason for hiding this comment

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

thats good point. IMO we can provide a solution afterwards. the main point of this is that we are living in the dark in terms if things work or not. I'd rather have this in our pipelines ASAP and tweak detail later if it makes sense.


We will need to get both CommonJS & ESM bundles:

- CommonJS is needed to avoid evaluation with `ts-node` or `babel-register`
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure I completely understand the need of commonjs ? it is because that main.utils or there is some other reason. If that 's the only reason we can extract that to separate lib so it's reusable and can be loaded via path aliases as is.

Copy link
Member Author

Choose a reason for hiding this comment

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

To clarify, we are going to perform SSR of existing stories to get HTML page.

For that we need to have stories evaluated in Node environment, they contain JSX and ESM code that cannot be directly executed by Node. It's what Next.js and other frameworks also do: bundle ESM to send on a client & bundle CJS to get executed in Node.

- A page will have configured interceptors to avoid loading resources (images) from CDN
- Ensure that there are no errors, otherwise test fails
- **Note**: For this reason the test app will run with `process.NODE_ENV = 'development'`
- **Note**: _Probably_ there is sense to restrict the test to catch only SSR related errors (in prototype it fails also on missing React keys, for example)
Copy link
Contributor

Choose a reason for hiding this comment

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

but the fact that our story triggered the warning means the story wasn't demonstrating best practices so,

If our stories produce those kind of warnings that should be handled by logic that triggers production builds of those stories -> public-docsite-v9. Also these can/should be covered by lint.


## Pros and Cons

- 👍 It's fast (3 seconds to run the whole test)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see reason why it would not be possible? puppeter will be already installed on your machine. it will also download proper chrome binary when executing so everything should work as intended. What would be nice for local development would be ability to execute that ssr solely for component you're working on. but ATM taking into consideration the speed of running it for everything in one shot is making that a low prio.

@layershifter
Copy link
Member Author

FYI: I worked on the actual implementation and found a real problem 💥 See #23371.

@layershifter layershifter merged commit b6f9445 into microsoft:master Jun 8, 2022
@layershifter layershifter deleted the rfc/ssr-testing branch June 8, 2022 11:09
marwan38 pushed a commit to marwan38/fluentui that referenced this pull request Jun 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: RFC Request for Feedback
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants