@samitouri / QOS-React / commits / e0e6b9c036

Add regression test for #19269 (#19282)

Dan Abramov committed Jul 8, 2020 at 20:48 UTC e0e6b9c036abde428d3130738604fd5abb67aa8f
1 file changed +83
packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+83
@@ -2897,6 +2897,89 @@ describe('ReactDOMServerPartialHydration', () => {
2897 expect(ref.current).not.toBe(null);
2898 });
2899
2900 + // @gate experimental
2901 + it('regression test: does not overfire non-bubbling browser events', async () => {
2902 + let suspend = false;
2903 + let resolve;
2904 + const promise = new Promise(resolvePromise => (resolve = resolvePromise));
2905 +
2906 + function Sibling({text}) {
2907 + if (suspend) {
2908 + throw promise;
2909 + } else {
2910 + return 'Hello';
2911 + }
2912 + }
2913 +
2914 + let submits = 0;
2915 +
2916 + function Form() {
2917 + const [submitted, setSubmitted] = React.useState(false);
2918 + if (submitted) {
2919 + return null;
2920 + }
2921 + return (
2922 + <form
2923 + onSubmit={() => {
2924 + setSubmitted(true);
2925 + submits++;
2926 + }}>
2927 + Click me
2928 + </form>
2929 + );
2930 + }
2931 +
2932 + function App() {
2933 + return (
2934 + <div>
2935 + <Suspense fallback="Loading...">
2936 + <Form />
2937 + <Sibling />
2938 + </Suspense>
2939 + </div>
2940 + );
2941 + }
2942 +
2943 + suspend = false;
2944 + const finalHTML = ReactDOMServer.renderToString(<App />);
2945 + const container = document.createElement('div');
2946 + container.innerHTML = finalHTML;
2947 +
2948 + // We need this to be in the document since we'll dispatch events on it.
2949 + document.body.appendChild(container);
2950 +
2951 + const form = container.getElementsByTagName('form')[0];
2952 +
2953 + // On the client we don't have all data yet but we want to start
2954 + // hydrating anyway.
2955 + suspend = true;
2956 + const root = ReactDOM.createRoot(container, {hydrate: true});
2957 + root.render(<App />);
2958 + Scheduler.unstable_flushAll();
2959 + jest.runAllTimers();
2960 +
2961 + expect(container.textContent).toBe('Click meHello');
2962 +
2963 + // We're now partially hydrated.
2964 + form.dispatchEvent(
2965 + new Event('submit', {
2966 + bubbles: true,
2967 + }),
2968 + );
2969 + expect(submits).toBe(0);
2970 +
2971 + // Resolving the promise so that rendering can complete.
2972 + suspend = false;
2973 + resolve();
2974 + await promise;
2975 +
2976 + Scheduler.unstable_flushAll();
2977 + jest.runAllTimers();
2978 + expect(submits).toBe(1);
2979 + expect(container.textContent).toBe('Hello');
2980 + document.body.removeChild(container);
2981 + });
2982 +
2983 // This test fails, in both forks. Without a boundary, the deferred tree won't
2984 // re-enter hydration mode. It doesn't come up in practice because there's
2985 // always a parent Suspense boundary. But it's still a bug. Leaving for a