Best JavaScript code snippet using playwright-internal
ReactDOMTracing-test.internal.js
Source:ReactDOMTracing-test.internal.js  
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @emails react-core8 */9'use strict';10let React;11let ReactDOM;12let ReactDOMServer;13let ReactFeatureFlags;14let Scheduler;15let SchedulerTracing;16let TestUtils;17let onInteractionScheduledWorkCompleted;18let onInteractionTraced;19let onWorkCanceled;20let onWorkScheduled;21let onWorkStarted;22let onWorkStopped;23function loadModules() {24  ReactFeatureFlags = require('shared/ReactFeatureFlags');25  ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;26  ReactFeatureFlags.enableProfilerTimer = true;27  ReactFeatureFlags.enableSchedulerTracing = true;28  ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;29  React = require('react');30  ReactDOM = require('react-dom');31  ReactDOMServer = require('react-dom/server');32  Scheduler = require('scheduler');33  SchedulerTracing = require('scheduler/tracing');34  TestUtils = require('react-dom/test-utils');35  onInteractionScheduledWorkCompleted = jest.fn();36  onInteractionTraced = jest.fn();37  onWorkCanceled = jest.fn();38  onWorkScheduled = jest.fn();39  onWorkStarted = jest.fn();40  onWorkStopped = jest.fn();41  // Verify interaction subscriber methods are called as expected.42  SchedulerTracing.unstable_subscribe({43    onInteractionScheduledWorkCompleted,44    onInteractionTraced,45    onWorkCanceled,46    onWorkScheduled,47    onWorkStarted,48    onWorkStopped,49  });50}51describe('ReactDOMTracing', () => {52  beforeEach(() => {53    jest.resetModules();54    loadModules();55  });56  if (!__EXPERIMENTAL__) {57    it("empty test so Jest doesn't complain", () => {});58    return;59  }60  describe('interaction tracing', () => {61    describe('hidden', () => {62      it('traces interaction through hidden subtree', () => {63        const Child = () => {64          const [didMount, setDidMount] = React.useState(false);65          Scheduler.unstable_yieldValue('Child');66          React.useEffect(() => {67            if (didMount) {68              Scheduler.unstable_yieldValue('Child:update');69            } else {70              Scheduler.unstable_yieldValue('Child:mount');71              setDidMount(true);72            }73          }, [didMount]);74          return <div />;75        };76        const App = () => {77          Scheduler.unstable_yieldValue('App');78          React.useEffect(() => {79            Scheduler.unstable_yieldValue('App:mount');80          }, []);81          return (82            <div hidden={true}>83              <Child />84            </div>85          );86        };87        let interaction;88        const onRender = jest.fn();89        const container = document.createElement('div');90        const root = ReactDOM.createRoot(container);91        SchedulerTracing.unstable_trace('initialization', 0, () => {92          interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];93          TestUtils.act(() => {94            root.render(95              <React.Profiler id="test" onRender={onRender}>96                <App />97              </React.Profiler>,98            );99            expect(onInteractionTraced).toHaveBeenCalledTimes(1);100            expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(101              interaction,102            );103            expect(Scheduler).toFlushAndYieldThrough(['App', 'App:mount']);104            expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();105            expect(onRender).toHaveBeenCalledTimes(1);106            expect(onRender).toHaveLastRenderedWithInteractions(107              new Set([interaction]),108            );109            expect(Scheduler).toFlushAndYieldThrough(['Child', 'Child:mount']);110            expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();111            expect(onRender).toHaveBeenCalledTimes(2);112            expect(onRender).toHaveLastRenderedWithInteractions(113              new Set([interaction]),114            );115            expect(Scheduler).toFlushAndYield(['Child', 'Child:update']);116          });117        });118        expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);119        expect(120          onInteractionScheduledWorkCompleted,121        ).toHaveBeenLastNotifiedOfInteraction(interaction);122        // TODO: This is 4 instead of 3 because this update was scheduled at123        // idle priority, and idle updates are slightly higher priority than124        // offscreen work. So it takes two render passes to finish it. Profiler125        // calls `onRender` for the first render even though everything126        // bails out.127        expect(onRender).toHaveBeenCalledTimes(4);128        expect(onRender).toHaveLastRenderedWithInteractions(129          new Set([interaction]),130        );131      });132      it('traces interaction through hidden subtree when there is other pending traced work', () => {133        const Child = () => {134          Scheduler.unstable_yieldValue('Child');135          return <div />;136        };137        let wrapped = null;138        const App = () => {139          Scheduler.unstable_yieldValue('App');140          React.useEffect(() => {141            wrapped = SchedulerTracing.unstable_wrap(() => {});142            Scheduler.unstable_yieldValue('App:mount');143          }, []);144          return (145            <div hidden={true}>146              <Child />147            </div>148          );149        };150        let interaction;151        const onRender = jest.fn();152        const container = document.createElement('div');153        const root = ReactDOM.createRoot(container);154        SchedulerTracing.unstable_trace('initialization', 0, () => {155          interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];156          TestUtils.act(() => {157            root.render(158              <React.Profiler id="test" onRender={onRender}>159                <App />160              </React.Profiler>,161            );162            expect(onInteractionTraced).toHaveBeenCalledTimes(1);163            expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(164              interaction,165            );166            expect(Scheduler).toFlushAndYieldThrough(['App', 'App:mount']);167            expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();168            expect(onRender).toHaveBeenCalledTimes(1);169            expect(onRender).toHaveLastRenderedWithInteractions(170              new Set([interaction]),171            );172            expect(wrapped).not.toBeNull();173            expect(Scheduler).toFlushAndYield(['Child']);174            expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();175            expect(onRender).toHaveBeenCalledTimes(2);176            expect(onRender).toHaveLastRenderedWithInteractions(177              new Set([interaction]),178            );179          });180        });181        wrapped();182        expect(onInteractionTraced).toHaveBeenCalledTimes(1);183        expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);184        expect(185          onInteractionScheduledWorkCompleted,186        ).toHaveBeenLastNotifiedOfInteraction(interaction);187      });188      it('traces interaction through hidden subtree that schedules more idle/never work', () => {189        const Child = () => {190          const [didMount, setDidMount] = React.useState(false);191          Scheduler.unstable_yieldValue('Child');192          React.useLayoutEffect(() => {193            if (didMount) {194              Scheduler.unstable_yieldValue('Child:update');195            } else {196              Scheduler.unstable_yieldValue('Child:mount');197              Scheduler.unstable_runWithPriority(198                Scheduler.unstable_IdlePriority,199                () => setDidMount(true),200              );201            }202          }, [didMount]);203          return <div />;204        };205        const App = () => {206          Scheduler.unstable_yieldValue('App');207          React.useEffect(() => {208            Scheduler.unstable_yieldValue('App:mount');209          }, []);210          return (211            <div hidden={true}>212              <Child />213            </div>214          );215        };216        let interaction;217        const onRender = jest.fn();218        const container = document.createElement('div');219        const root = ReactDOM.createRoot(container);220        SchedulerTracing.unstable_trace('initialization', 0, () => {221          interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];222          TestUtils.act(() => {223            root.render(224              <React.Profiler id="test" onRender={onRender}>225                <App />226              </React.Profiler>,227            );228            expect(onInteractionTraced).toHaveBeenCalledTimes(1);229            expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(230              interaction,231            );232            expect(Scheduler).toFlushAndYieldThrough(['App', 'App:mount']);233            expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();234            expect(onRender).toHaveBeenCalledTimes(1);235            expect(onRender).toHaveLastRenderedWithInteractions(236              new Set([interaction]),237            );238            expect(Scheduler).toFlushAndYieldThrough(['Child', 'Child:mount']);239            expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();240            expect(onRender).toHaveBeenCalledTimes(2);241            expect(onRender).toHaveLastRenderedWithInteractions(242              new Set([interaction]),243            );244            expect(Scheduler).toFlushAndYield(['Child', 'Child:update']);245          });246        });247        expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);248        expect(249          onInteractionScheduledWorkCompleted,250        ).toHaveBeenLastNotifiedOfInteraction(interaction);251        // TODO: This is 4 instead of 3 because this update was scheduled at252        // idle priority, and idle updates are slightly higher priority than253        // offscreen work. So it takes two render passes to finish it. Profiler254        // calls `onRender` for the first render even though everything255        // bails out.256        expect(onRender).toHaveBeenCalledTimes(4);257        expect(onRender).toHaveLastRenderedWithInteractions(258          new Set([interaction]),259        );260      });261      it('does not continue interactions across pre-existing idle work', () => {262        const Child = () => {263          Scheduler.unstable_yieldValue('Child');264          return <div />;265        };266        let update = null;267        const WithHiddenWork = () => {268          Scheduler.unstable_yieldValue('WithHiddenWork');269          return (270            <div hidden={true}>271              <Child />272            </div>273          );274        };275        const Updater = () => {276          Scheduler.unstable_yieldValue('Updater');277          React.useEffect(() => {278            Scheduler.unstable_yieldValue('Updater:effect');279          });280          const setCount = React.useState(0)[1];281          update = () => {282            setCount(current => current + 1);283          };284          return <div />;285        };286        const App = () => {287          Scheduler.unstable_yieldValue('App');288          React.useEffect(() => {289            Scheduler.unstable_yieldValue('App:effect');290          });291          return (292            <>293              <WithHiddenWork />294              <Updater />295            </>296          );297        };298        const onRender = jest.fn();299        const container = document.createElement('div');300        const root = ReactDOM.createRoot(container);301        // Schedule some idle work without any interactions.302        TestUtils.act(() => {303          root.render(304            <React.Profiler id="test" onRender={onRender}>305              <App />306            </React.Profiler>,307          );308          expect(Scheduler).toFlushAndYieldThrough([309            'App',310            'WithHiddenWork',311            'Updater',312            'Updater:effect',313            'App:effect',314          ]);315          expect(update).not.toBeNull();316          // Trace a higher-priority update.317          let interaction = null;318          SchedulerTracing.unstable_trace('update', 0, () => {319            interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];320            update();321          });322          expect(interaction).not.toBeNull();323          expect(onRender).toHaveBeenCalledTimes(1);324          expect(onInteractionTraced).toHaveBeenCalledTimes(1);325          expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(326            interaction,327          );328          // Ensure the traced interaction completes without being attributed to the pre-existing idle work.329          expect(Scheduler).toFlushAndYieldThrough([330            'Updater',331            'Updater:effect',332          ]);333          expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);334          expect(335            onInteractionScheduledWorkCompleted,336          ).toHaveBeenLastNotifiedOfInteraction(interaction);337          expect(onRender).toHaveBeenCalledTimes(2);338          expect(onRender).toHaveLastRenderedWithInteractions(339            new Set([interaction]),340          );341          // Complete low-priority work and ensure no lingering interaction.342          expect(Scheduler).toFlushAndYield(['Child']);343          expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);344          expect(onRender).toHaveBeenCalledTimes(3);345          expect(onRender).toHaveLastRenderedWithInteractions(new Set([]));346        });347      });348      it('should properly trace interactions when there is work of interleaved priorities', () => {349        const Child = () => {350          Scheduler.unstable_yieldValue('Child');351          return <div />;352        };353        let scheduleUpdate = null;354        let scheduleUpdateWithHidden = null;355        const MaybeHiddenWork = () => {356          const [flag, setFlag] = React.useState(false);357          scheduleUpdateWithHidden = () => setFlag(true);358          Scheduler.unstable_yieldValue('MaybeHiddenWork');359          React.useEffect(() => {360            Scheduler.unstable_yieldValue('MaybeHiddenWork:effect');361          });362          return flag ? (363            <div hidden={true}>364              <Child />365            </div>366          ) : null;367        };368        const Updater = () => {369          Scheduler.unstable_yieldValue('Updater');370          React.useEffect(() => {371            Scheduler.unstable_yieldValue('Updater:effect');372          });373          const setCount = React.useState(0)[1];374          scheduleUpdate = () => setCount(current => current + 1);375          return <div />;376        };377        const App = () => {378          Scheduler.unstable_yieldValue('App');379          React.useEffect(() => {380            Scheduler.unstable_yieldValue('App:effect');381          });382          return (383            <>384              <MaybeHiddenWork />385              <Updater />386            </>387          );388        };389        const onRender = jest.fn();390        const container = document.createElement('div');391        const root = ReactDOM.createRoot(container);392        TestUtils.act(() => {393          root.render(394            <React.Profiler id="test" onRender={onRender}>395              <App />396            </React.Profiler>,397          );398          expect(Scheduler).toFlushAndYield([399            'App',400            'MaybeHiddenWork',401            'Updater',402            'MaybeHiddenWork:effect',403            'Updater:effect',404            'App:effect',405          ]);406          expect(scheduleUpdate).not.toBeNull();407          expect(scheduleUpdateWithHidden).not.toBeNull();408          expect(onRender).toHaveBeenCalledTimes(1);409          // schedule traced high-pri update and a (non-traced) low-pri update.410          let interaction = null;411          SchedulerTracing.unstable_trace('update', 0, () => {412            interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];413            Scheduler.unstable_runWithPriority(414              Scheduler.unstable_UserBlockingPriority,415              () => scheduleUpdateWithHidden(),416            );417          });418          scheduleUpdate();419          expect(interaction).not.toBeNull();420          expect(onRender).toHaveBeenCalledTimes(1);421          expect(onInteractionTraced).toHaveBeenCalledTimes(1);422          expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(423            interaction,424          );425          // high-pri update should leave behind idle work and should not complete the interaction426          expect(Scheduler).toFlushAndYieldThrough([427            'MaybeHiddenWork',428            'MaybeHiddenWork:effect',429          ]);430          expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();431          expect(onRender).toHaveBeenCalledTimes(2);432          expect(onRender).toHaveLastRenderedWithInteractions(433            new Set([interaction]),434          );435          // low-pri update should not have the interaction436          expect(Scheduler).toFlushAndYieldThrough([437            'Updater',438            'Updater:effect',439          ]);440          expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();441          expect(onRender).toHaveBeenCalledTimes(3);442          expect(onRender).toHaveLastRenderedWithInteractions(new Set([]));443          // idle work should complete the interaction444          expect(Scheduler).toFlushAndYield(['Child']);445          expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);446          expect(447            onInteractionScheduledWorkCompleted,448          ).toHaveBeenLastNotifiedOfInteraction(interaction);449          expect(onRender).toHaveBeenCalledTimes(4);450          expect(onRender).toHaveLastRenderedWithInteractions(451            new Set([interaction]),452          );453        });454      });455      it('should properly trace interactions through a multi-pass SuspenseList render', () => {456        const SuspenseList = React.SuspenseList;457        const Suspense = React.Suspense;458        function Text({text}) {459          Scheduler.unstable_yieldValue(text);460          React.useEffect(() => {461            Scheduler.unstable_yieldValue('Commit ' + text);462          });463          return <span>{text}</span>;464        }465        function App() {466          return (467            <SuspenseList revealOrder="forwards">468              <Suspense fallback={<Text text="Loading A" />}>469                <Text text="A" />470              </Suspense>471              <Suspense fallback={<Text text="Loading B" />}>472                <Text text="B" />473              </Suspense>474              <Suspense fallback={<Text text="Loading C" />}>475                <Text text="C" />476              </Suspense>477            </SuspenseList>478          );479        }480        const container = document.createElement('div');481        const root = ReactDOM.createRoot(container);482        let interaction;483        TestUtils.act(() => {484          SchedulerTracing.unstable_trace('initialization', 0, () => {485            interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];486            // This render is only CPU bound. Nothing suspends.487            root.render(<App />);488          });489          expect(Scheduler).toFlushAndYieldThrough(['A']);490          Scheduler.unstable_advanceTime(200);491          jest.advanceTimersByTime(200);492          expect(Scheduler).toFlushAndYieldThrough(['B']);493          Scheduler.unstable_advanceTime(300);494          jest.advanceTimersByTime(300);495          // Time has now elapsed for so long that we're just going to give up496          // rendering the rest of the content. So that we can at least show497          // something.498          expect(Scheduler).toFlushAndYieldThrough([499            'Loading C',500            'Commit A',501            'Commit B',502            'Commit Loading C',503          ]);504          // Schedule an unrelated low priority update that shouldn't be included505          // in the previous interaction. This is meant to ensure that we don't506          // rely on the whole tree completing to cover up bugs.507          Scheduler.unstable_runWithPriority(508            Scheduler.unstable_IdlePriority,509            () => root.render(<App />),510          );511          expect(onInteractionTraced).toHaveBeenCalledTimes(1);512          expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(513            interaction,514          );515          expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();516          // Then we do a second pass to commit the last item.517          expect(Scheduler).toFlushAndYieldThrough(['C', 'Commit C']);518          expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);519          expect(520            onInteractionScheduledWorkCompleted,521          ).toHaveBeenLastNotifiedOfInteraction(interaction);522        });523      });524    });525    describe('hydration', () => {526      it('traces interaction across hydration', async done => {527        let ref = React.createRef();528        function Child() {529          return 'Hello';530        }531        function App() {532          return (533            <div>534              <span ref={ref}>535                <Child />536              </span>537            </div>538          );539        }540        // Render the final HTML.541        const finalHTML = ReactDOMServer.renderToString(<App />);542        const container = document.createElement('div');543        container.innerHTML = finalHTML;544        let interaction;545        const root = ReactDOM.createRoot(container, {hydrate: true});546        // Hydrate it.547        SchedulerTracing.unstable_trace('initialization', 0, () => {548          interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];549          root.render(<App />);550        });551        Scheduler.unstable_flushAll();552        jest.runAllTimers();553        expect(ref.current).not.toBe(null);554        expect(onInteractionTraced).toHaveBeenCalledTimes(1);555        expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(556          interaction,557        );558        expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);559        expect(560          onInteractionScheduledWorkCompleted,561        ).toHaveBeenLastNotifiedOfInteraction(interaction);562        done();563      });564      it('traces interaction across suspended hydration', async done => {565        let suspend = false;566        let resolve;567        let promise = new Promise(resolvePromise => (resolve = resolvePromise));568        let ref = React.createRef();569        function Child() {570          if (suspend) {571            throw promise;572          } else {573            return 'Hello';574          }575        }576        function App() {577          return (578            <div>579              <React.Suspense fallback="Loading...">580                <span ref={ref}>581                  <Child />582                </span>583              </React.Suspense>584            </div>585          );586        }587        // Render the final HTML.588        // Don't suspend on the server.589        const finalHTML = ReactDOMServer.renderToString(<App />);590        const container = document.createElement('div');591        container.innerHTML = finalHTML;592        let interaction;593        const root = ReactDOM.createRoot(container, {hydrate: true});594        // Start hydrating but simulate blocking for suspense data.595        suspend = true;596        SchedulerTracing.unstable_trace('initialization', 0, () => {597          interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];598          root.render(<App />);599        });600        Scheduler.unstable_flushAll();601        jest.runAllTimers();602        expect(ref.current).toBe(null);603        expect(onInteractionTraced).toHaveBeenCalledTimes(1);604        expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(605          interaction,606        );607        expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();608        // Resolving the promise should continue hydration609        suspend = false;610        resolve();611        await promise;612        Scheduler.unstable_flushAll();613        jest.runAllTimers();614        expect(ref.current).not.toBe(null);615        expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);616        expect(617          onInteractionScheduledWorkCompleted,618        ).toHaveBeenLastNotifiedOfInteraction(interaction);619        done();620      });621      it('traces interaction across client-rendered hydration', async done => {622        let suspend = false;623        let promise = new Promise(() => {});624        let ref = React.createRef();625        function Child() {626          if (suspend) {627            throw promise;628          } else {629            return 'Hello';630          }631        }632        function App() {633          return (634            <div>635              <React.Suspense fallback="Loading...">636                <span ref={ref}>637                  <Child />638                </span>639              </React.Suspense>640            </div>641          );642        }643        // Render the final HTML.644        suspend = true;645        const finalHTML = ReactDOMServer.renderToString(<App />);646        const container = document.createElement('div');647        container.innerHTML = finalHTML;648        let interaction;649        const root = ReactDOM.createRoot(container, {hydrate: true});650        // Hydrate without suspending to fill in the client-rendered content.651        suspend = false;652        SchedulerTracing.unstable_trace('initialization', 0, () => {653          interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];654          root.render(<App />);655        });656        expect(onWorkStopped).toHaveBeenCalledTimes(1);657        // Advance time a bit so that we get into a new expiration bucket.658        Scheduler.unstable_advanceTime(300);659        jest.advanceTimersByTime(300);660        Scheduler.unstable_flushAll();661        jest.runAllTimers();662        expect(ref.current).not.toBe(null);663        // We should've had two commits that was traced.664        // First one that hydrates the parent, and then one that hydrates665        // the boundary at higher than Never priority.666        expect(onWorkStopped).toHaveBeenCalledTimes(3);667        expect(onInteractionTraced).toHaveBeenCalledTimes(1);668        expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(669          interaction,670        );671        expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);672        expect(673          onInteractionScheduledWorkCompleted,674        ).toHaveBeenLastNotifiedOfInteraction(interaction);675        done();676      });677    });678  });...TrackingSubscriptions-test.internal.js
Source:TrackingSubscriptions-test.internal.js  
1/**2 * Copyright (c) 2013-present, Facebook, Inc.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @jest-environment node8 */9'use strict';10describe('TrackingSubscriptions', () => {11  let SchedulerTracking;12  let ReactFeatureFlags;13  let currentTime;14  let onInteractionScheduledWorkCompleted;15  let onInteractionTracked;16  let onWorkCanceled;17  let onWorkScheduled;18  let onWorkStarted;19  let onWorkStopped;20  let throwInOnInteractionScheduledWorkCompleted;21  let throwInOnInteractionTracked;22  let throwInOnWorkCanceled;23  let throwInOnWorkScheduled;24  let throwInOnWorkStarted;25  let throwInOnWorkStopped;26  let firstSubscriber;27  let secondSubscriber;28  const firstEvent = {id: 0, name: 'first', timestamp: 0};29  const secondEvent = {id: 1, name: 'second', timestamp: 0};30  const threadID = 123;31  function loadModules({enableSchedulerTracking, autoSubscribe = true}) {32    jest.resetModules();33    jest.useFakeTimers();34    currentTime = 0;35    ReactFeatureFlags = require('shared/ReactFeatureFlags');36    ReactFeatureFlags.enableSchedulerTracking = enableSchedulerTracking;37    SchedulerTracking = require('schedule/tracking');38    throwInOnInteractionScheduledWorkCompleted = false;39    throwInOnInteractionTracked = false;40    throwInOnWorkCanceled = false;41    throwInOnWorkScheduled = false;42    throwInOnWorkStarted = false;43    throwInOnWorkStopped = false;44    onInteractionScheduledWorkCompleted = jest.fn(() => {45      if (throwInOnInteractionScheduledWorkCompleted) {46        throw Error('Expected error onInteractionScheduledWorkCompleted');47      }48    });49    onInteractionTracked = jest.fn(() => {50      if (throwInOnInteractionTracked) {51        throw Error('Expected error onInteractionTracked');52      }53    });54    onWorkCanceled = jest.fn(() => {55      if (throwInOnWorkCanceled) {56        throw Error('Expected error onWorkCanceled');57      }58    });59    onWorkScheduled = jest.fn(() => {60      if (throwInOnWorkScheduled) {61        throw Error('Expected error onWorkScheduled');62      }63    });64    onWorkStarted = jest.fn(() => {65      if (throwInOnWorkStarted) {66        throw Error('Expected error onWorkStarted');67      }68    });69    onWorkStopped = jest.fn(() => {70      if (throwInOnWorkStopped) {71        throw Error('Expected error onWorkStopped');72      }73    });74    firstSubscriber = {75      onInteractionScheduledWorkCompleted,76      onInteractionTracked,77      onWorkCanceled,78      onWorkScheduled,79      onWorkStarted,80      onWorkStopped,81    };82    secondSubscriber = {83      onInteractionScheduledWorkCompleted: jest.fn(),84      onInteractionTracked: jest.fn(),85      onWorkCanceled: jest.fn(),86      onWorkScheduled: jest.fn(),87      onWorkStarted: jest.fn(),88      onWorkStopped: jest.fn(),89    };90    if (autoSubscribe) {91      SchedulerTracking.unstable_subscribe(firstSubscriber);92      SchedulerTracking.unstable_subscribe(secondSubscriber);93    }94  }95  describe('enabled', () => {96    beforeEach(() => loadModules({enableSchedulerTracking: true}));97    it('should lazily subscribe to tracking and unsubscribe again if there are no external subscribers', () => {98      loadModules({enableSchedulerTracking: true, autoSubscribe: false});99      expect(SchedulerTracking.__subscriberRef.current).toBe(null);100      SchedulerTracking.unstable_subscribe(firstSubscriber);101      expect(SchedulerTracking.__subscriberRef.current).toBeDefined();102      SchedulerTracking.unstable_subscribe(secondSubscriber);103      expect(SchedulerTracking.__subscriberRef.current).toBeDefined();104      SchedulerTracking.unstable_unsubscribe(secondSubscriber);105      expect(SchedulerTracking.__subscriberRef.current).toBeDefined();106      SchedulerTracking.unstable_unsubscribe(firstSubscriber);107      expect(SchedulerTracking.__subscriberRef.current).toBe(null);108    });109    describe('error handling', () => {110      it('should cover onInteractionTracked/onWorkStarted within', done => {111        SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {112          const mock = jest.fn();113          // It should call the callback before re-throwing114          throwInOnInteractionTracked = true;115          expect(() =>116            SchedulerTracking.unstable_track(117              secondEvent.name,118              currentTime,119              mock,120              threadID,121            ),122          ).toThrow('Expected error onInteractionTracked');123          throwInOnInteractionTracked = false;124          expect(mock).toHaveBeenCalledTimes(1);125          throwInOnWorkStarted = true;126          expect(() =>127            SchedulerTracking.unstable_track(128              secondEvent.name,129              currentTime,130              mock,131              threadID,132            ),133          ).toThrow('Expected error onWorkStarted');134          expect(mock).toHaveBeenCalledTimes(2);135          // It should restore the previous/outer interactions136          expect(SchedulerTracking.unstable_getCurrent()).toMatchInteractions([137            firstEvent,138          ]);139          // It should call other subscribers despite the earlier error140          expect(secondSubscriber.onInteractionTracked).toHaveBeenCalledTimes(141            3,142          );143          expect(secondSubscriber.onWorkStarted).toHaveBeenCalledTimes(3);144          done();145        });146      });147      it('should cover onWorkStopped within track', done => {148        SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {149          let innerInteraction;150          const mock = jest.fn(() => {151            innerInteraction = Array.from(152              SchedulerTracking.unstable_getCurrent(),153            )[1];154          });155          throwInOnWorkStopped = true;156          expect(() =>157            SchedulerTracking.unstable_track(158              secondEvent.name,159              currentTime,160              mock,161            ),162          ).toThrow('Expected error onWorkStopped');163          throwInOnWorkStopped = false;164          // It should restore the previous/outer interactions165          expect(SchedulerTracking.unstable_getCurrent()).toMatchInteractions([166            firstEvent,167          ]);168          // It should update the interaction count so as not to interfere with subsequent calls169          expect(innerInteraction.__count).toBe(0);170          // It should call other subscribers despite the earlier error171          expect(secondSubscriber.onWorkStopped).toHaveBeenCalledTimes(1);172          done();173        });174      });175      it('should cover onInteractionScheduledWorkCompleted within track', done => {176        SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {177          const mock = jest.fn();178          throwInOnInteractionScheduledWorkCompleted = true;179          expect(() =>180            SchedulerTracking.unstable_track(181              secondEvent.name,182              currentTime,183              mock,184            ),185          ).toThrow('Expected error onInteractionScheduledWorkCompleted');186          throwInOnInteractionScheduledWorkCompleted = false;187          // It should restore the previous/outer interactions188          expect(SchedulerTracking.unstable_getCurrent()).toMatchInteractions([189            firstEvent,190          ]);191          // It should call other subscribers despite the earlier error192          expect(193            secondSubscriber.onInteractionScheduledWorkCompleted,194          ).toHaveBeenCalledTimes(1);195          done();196        });197      });198      it('should cover the callback within track', done => {199        expect(onWorkStarted).not.toHaveBeenCalled();200        expect(onWorkStopped).not.toHaveBeenCalled();201        expect(() => {202          SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {203            throw Error('Expected error callback');204          });205        }).toThrow('Expected error callback');206        expect(onWorkStarted).toHaveBeenCalledTimes(1);207        expect(onWorkStopped).toHaveBeenCalledTimes(1);208        done();209      });210      it('should cover onWorkScheduled within wrap', done => {211        SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {212          const interaction = Array.from(213            SchedulerTracking.unstable_getCurrent(),214          )[0];215          const beforeCount = interaction.__count;216          throwInOnWorkScheduled = true;217          expect(() => SchedulerTracking.unstable_wrap(() => {})).toThrow(218            'Expected error onWorkScheduled',219          );220          // It should not update the interaction count so as not to interfere with subsequent calls221          expect(interaction.__count).toBe(beforeCount);222          // It should call other subscribers despite the earlier error223          expect(secondSubscriber.onWorkScheduled).toHaveBeenCalledTimes(1);224          done();225        });226      });227      it('should cover onWorkStarted within wrap', () => {228        const mock = jest.fn();229        let interaction, wrapped;230        SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {231          interaction = Array.from(SchedulerTracking.unstable_getCurrent())[0];232          wrapped = SchedulerTracking.unstable_wrap(mock);233        });234        expect(interaction.__count).toBe(1);235        throwInOnWorkStarted = true;236        expect(wrapped).toThrow('Expected error onWorkStarted');237        // It should call the callback before re-throwing238        expect(mock).toHaveBeenCalledTimes(1);239        // It should update the interaction count so as not to interfere with subsequent calls240        expect(interaction.__count).toBe(0);241        // It should call other subscribers despite the earlier error242        expect(secondSubscriber.onWorkStarted).toHaveBeenCalledTimes(2);243      });244      it('should cover onWorkStopped within wrap', done => {245        SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {246          const outerInteraction = Array.from(247            SchedulerTracking.unstable_getCurrent(),248          )[0];249          expect(outerInteraction.__count).toBe(1);250          let wrapped;251          let innerInteraction;252          SchedulerTracking.unstable_track(253            secondEvent.name,254            currentTime,255            () => {256              innerInteraction = Array.from(257                SchedulerTracking.unstable_getCurrent(),258              )[1];259              expect(outerInteraction.__count).toBe(1);260              expect(innerInteraction.__count).toBe(1);261              wrapped = SchedulerTracking.unstable_wrap(jest.fn());262              expect(outerInteraction.__count).toBe(2);263              expect(innerInteraction.__count).toBe(2);264            },265          );266          expect(outerInteraction.__count).toBe(2);267          expect(innerInteraction.__count).toBe(1);268          throwInOnWorkStopped = true;269          expect(wrapped).toThrow('Expected error onWorkStopped');270          throwInOnWorkStopped = false;271          // It should restore the previous interactions272          expect(SchedulerTracking.unstable_getCurrent()).toMatchInteractions([273            outerInteraction,274          ]);275          // It should update the interaction count so as not to interfere with subsequent calls276          expect(outerInteraction.__count).toBe(1);277          expect(innerInteraction.__count).toBe(0);278          expect(secondSubscriber.onWorkStopped).toHaveBeenCalledTimes(2);279          done();280        });281      });282      it('should cover the callback within wrap', done => {283        expect(onWorkStarted).not.toHaveBeenCalled();284        expect(onWorkStopped).not.toHaveBeenCalled();285        let wrapped;286        let interaction;287        SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {288          interaction = Array.from(SchedulerTracking.unstable_getCurrent())[0];289          wrapped = SchedulerTracking.unstable_wrap(() => {290            throw Error('Expected error wrap');291          });292        });293        expect(onWorkStarted).toHaveBeenCalledTimes(1);294        expect(onWorkStopped).toHaveBeenCalledTimes(1);295        expect(wrapped).toThrow('Expected error wrap');296        expect(onWorkStarted).toHaveBeenCalledTimes(2);297        expect(onWorkStopped).toHaveBeenCalledTimes(2);298        expect(onWorkStopped).toHaveBeenLastNotifiedOfWork([interaction]);299        done();300      });301      it('should cover onWorkCanceled within wrap', () => {302        let interaction, wrapped;303        SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {304          interaction = Array.from(SchedulerTracking.unstable_getCurrent())[0];305          wrapped = SchedulerTracking.unstable_wrap(jest.fn());306        });307        expect(interaction.__count).toBe(1);308        throwInOnWorkCanceled = true;309        expect(wrapped.cancel).toThrow('Expected error onWorkCanceled');310        expect(onWorkCanceled).toHaveBeenCalledTimes(1);311        // It should update the interaction count so as not to interfere with subsequent calls312        expect(interaction.__count).toBe(0);313        expect(314          onInteractionScheduledWorkCompleted,315        ).toHaveBeenLastNotifiedOfInteraction(firstEvent);316        // It should call other subscribers despite the earlier error317        expect(secondSubscriber.onWorkCanceled).toHaveBeenCalledTimes(1);318      });319    });320    it('calls lifecycle methods for track', () => {321      expect(onInteractionTracked).not.toHaveBeenCalled();322      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();323      SchedulerTracking.unstable_track(324        firstEvent.name,325        currentTime,326        () => {327          expect(onInteractionTracked).toHaveBeenCalledTimes(1);328          expect(onInteractionTracked).toHaveBeenLastNotifiedOfInteraction(329            firstEvent,330          );331          expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();332          expect(onWorkStarted).toHaveBeenCalledTimes(1);333          expect(onWorkStarted).toHaveBeenLastNotifiedOfWork(334            new Set([firstEvent]),335            threadID,336          );337          expect(onWorkStopped).not.toHaveBeenCalled();338          SchedulerTracking.unstable_track(339            secondEvent.name,340            currentTime,341            () => {342              expect(onInteractionTracked).toHaveBeenCalledTimes(2);343              expect(onInteractionTracked).toHaveBeenLastNotifiedOfInteraction(344                secondEvent,345              );346              expect(347                onInteractionScheduledWorkCompleted,348              ).not.toHaveBeenCalled();349              expect(onWorkStarted).toHaveBeenCalledTimes(2);350              expect(onWorkStarted).toHaveBeenLastNotifiedOfWork(351                new Set([firstEvent, secondEvent]),352                threadID,353              );354              expect(onWorkStopped).not.toHaveBeenCalled();355            },356            threadID,357          );358          expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);359          expect(360            onInteractionScheduledWorkCompleted,361          ).toHaveBeenLastNotifiedOfInteraction(secondEvent);362          expect(onWorkStopped).toHaveBeenCalledTimes(1);363          expect(onWorkStopped).toHaveBeenLastNotifiedOfWork(364            new Set([firstEvent, secondEvent]),365            threadID,366          );367        },368        threadID,369      );370      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(2);371      expect(372        onInteractionScheduledWorkCompleted,373      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);374      expect(onWorkScheduled).not.toHaveBeenCalled();375      expect(onWorkCanceled).not.toHaveBeenCalled();376      expect(onWorkStarted).toHaveBeenCalledTimes(2);377      expect(onWorkStopped).toHaveBeenCalledTimes(2);378      expect(onWorkStopped).toHaveBeenLastNotifiedOfWork(379        new Set([firstEvent]),380        threadID,381      );382    });383    it('calls lifecycle methods for wrap', () => {384      const unwrapped = jest.fn();385      let wrapped;386      SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {387        expect(onInteractionTracked).toHaveBeenCalledTimes(1);388        expect(onInteractionTracked).toHaveBeenLastNotifiedOfInteraction(389          firstEvent,390        );391        SchedulerTracking.unstable_track(secondEvent.name, currentTime, () => {392          expect(onInteractionTracked).toHaveBeenCalledTimes(2);393          expect(onInteractionTracked).toHaveBeenLastNotifiedOfInteraction(394            secondEvent,395          );396          wrapped = SchedulerTracking.unstable_wrap(unwrapped, threadID);397          expect(onWorkScheduled).toHaveBeenCalledTimes(1);398          expect(onWorkScheduled).toHaveBeenLastNotifiedOfWork(399            new Set([firstEvent, secondEvent]),400            threadID,401          );402        });403      });404      expect(onInteractionTracked).toHaveBeenCalledTimes(2);405      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();406      wrapped();407      expect(unwrapped).toHaveBeenCalled();408      expect(onWorkScheduled).toHaveBeenCalledTimes(1);409      expect(onWorkCanceled).not.toHaveBeenCalled();410      expect(onWorkStarted).toHaveBeenCalledTimes(3);411      expect(onWorkStarted).toHaveBeenLastNotifiedOfWork(412        new Set([firstEvent, secondEvent]),413        threadID,414      );415      expect(onWorkStopped).toHaveBeenCalledTimes(3);416      expect(onWorkStopped).toHaveBeenLastNotifiedOfWork(417        new Set([firstEvent, secondEvent]),418        threadID,419      );420      expect(421        onInteractionScheduledWorkCompleted.mock.calls[0][0],422      ).toMatchInteraction(firstEvent);423      expect(424        onInteractionScheduledWorkCompleted.mock.calls[1][0],425      ).toMatchInteraction(secondEvent);426    });427    it('should call the correct interaction subscriber methods when a wrapped callback is canceled', () => {428      const fnOne = jest.fn();429      const fnTwo = jest.fn();430      let wrappedOne, wrappedTwo;431      SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {432        wrappedOne = SchedulerTracking.unstable_wrap(fnOne, threadID);433        SchedulerTracking.unstable_track(secondEvent.name, currentTime, () => {434          wrappedTwo = SchedulerTracking.unstable_wrap(fnTwo, threadID);435        });436      });437      expect(onInteractionTracked).toHaveBeenCalledTimes(2);438      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();439      expect(onWorkCanceled).not.toHaveBeenCalled();440      expect(onWorkStarted).toHaveBeenCalledTimes(2);441      expect(onWorkStopped).toHaveBeenCalledTimes(2);442      wrappedTwo.cancel();443      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);444      expect(445        onInteractionScheduledWorkCompleted,446      ).toHaveBeenLastNotifiedOfInteraction(secondEvent);447      expect(onWorkCanceled).toHaveBeenCalledTimes(1);448      expect(onWorkCanceled).toHaveBeenLastNotifiedOfWork(449        new Set([firstEvent, secondEvent]),450        threadID,451      );452      wrappedOne.cancel();453      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(2);454      expect(455        onInteractionScheduledWorkCompleted,456      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);457      expect(onWorkCanceled).toHaveBeenCalledTimes(2);458      expect(onWorkCanceled).toHaveBeenLastNotifiedOfWork(459        new Set([firstEvent]),460        threadID,461      );462      expect(fnOne).not.toHaveBeenCalled();463      expect(fnTwo).not.toHaveBeenCalled();464    });465    it('should not end an interaction twice if wrap is used to schedule follow up work within another wrap', () => {466      const fnOne = jest.fn(() => {467        wrappedTwo = SchedulerTracking.unstable_wrap(fnTwo, threadID);468      });469      const fnTwo = jest.fn();470      let wrappedOne, wrappedTwo;471      SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {472        wrappedOne = SchedulerTracking.unstable_wrap(fnOne, threadID);473      });474      expect(onInteractionTracked).toHaveBeenCalledTimes(1);475      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();476      wrappedOne();477      expect(onInteractionTracked).toHaveBeenCalledTimes(1);478      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();479      wrappedTwo();480      expect(onInteractionTracked).toHaveBeenCalledTimes(1);481      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);482      expect(483        onInteractionScheduledWorkCompleted,484      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);485    });486    it('should not decrement the interaction count twice if a wrapped function is run twice', () => {487      const unwrappedOne = jest.fn();488      const unwrappedTwo = jest.fn();489      let wrappedOne, wrappedTwo;490      SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {491        wrappedOne = SchedulerTracking.unstable_wrap(unwrappedOne, threadID);492        wrappedTwo = SchedulerTracking.unstable_wrap(unwrappedTwo, threadID);493      });494      expect(onInteractionTracked).toHaveBeenCalledTimes(1);495      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();496      wrappedOne();497      expect(unwrappedOne).toHaveBeenCalledTimes(1);498      expect(onInteractionTracked).toHaveBeenCalledTimes(1);499      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();500      wrappedOne();501      expect(unwrappedOne).toHaveBeenCalledTimes(2);502      expect(onInteractionTracked).toHaveBeenCalledTimes(1);503      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();504      wrappedTwo();505      expect(onInteractionTracked).toHaveBeenCalledTimes(1);506      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);507      expect(508        onInteractionScheduledWorkCompleted,509      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);510    });511    it('should unsubscribe', () => {512      SchedulerTracking.unstable_unsubscribe(firstSubscriber);513      SchedulerTracking.unstable_track(firstEvent.name, currentTime, () => {});514      expect(onInteractionTracked).not.toHaveBeenCalled();515    });516  });517  describe('disabled', () => {518    beforeEach(() => loadModules({enableSchedulerTracking: false}));519    // TODO520  });...TracingSubscriptions-test.internal.js
Source:TracingSubscriptions-test.internal.js  
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @jest-environment node8 */9'use strict';10describe('TracingSubscriptions', () => {11  let SchedulerTracing;12  let ReactFeatureFlags;13  let currentTime;14  let onInteractionScheduledWorkCompleted;15  let onInteractionTraced;16  let onWorkCanceled;17  let onWorkScheduled;18  let onWorkStarted;19  let onWorkStopped;20  let throwInOnInteractionScheduledWorkCompleted;21  let throwInOnInteractionTraced;22  let throwInOnWorkCanceled;23  let throwInOnWorkScheduled;24  let throwInOnWorkStarted;25  let throwInOnWorkStopped;26  let firstSubscriber;27  let secondSubscriber;28  const firstEvent = {id: 0, name: 'first', timestamp: 0};29  const secondEvent = {id: 1, name: 'second', timestamp: 0};30  const threadID = 123;31  function loadModules({enableSchedulerTracing, autoSubscribe = true}) {32    jest.resetModules();33    jest.useFakeTimers();34    currentTime = 0;35    ReactFeatureFlags = require('shared/ReactFeatureFlags');36    ReactFeatureFlags.enableSchedulerTracing = enableSchedulerTracing;37    SchedulerTracing = require('scheduler/tracing');38    throwInOnInteractionScheduledWorkCompleted = false;39    throwInOnInteractionTraced = false;40    throwInOnWorkCanceled = false;41    throwInOnWorkScheduled = false;42    throwInOnWorkStarted = false;43    throwInOnWorkStopped = false;44    onInteractionScheduledWorkCompleted = jest.fn(() => {45      if (throwInOnInteractionScheduledWorkCompleted) {46        throw Error('Expected error onInteractionScheduledWorkCompleted');47      }48    });49    onInteractionTraced = jest.fn(() => {50      if (throwInOnInteractionTraced) {51        throw Error('Expected error onInteractionTraced');52      }53    });54    onWorkCanceled = jest.fn(() => {55      if (throwInOnWorkCanceled) {56        throw Error('Expected error onWorkCanceled');57      }58    });59    onWorkScheduled = jest.fn(() => {60      if (throwInOnWorkScheduled) {61        throw Error('Expected error onWorkScheduled');62      }63    });64    onWorkStarted = jest.fn(() => {65      if (throwInOnWorkStarted) {66        throw Error('Expected error onWorkStarted');67      }68    });69    onWorkStopped = jest.fn(() => {70      if (throwInOnWorkStopped) {71        throw Error('Expected error onWorkStopped');72      }73    });74    firstSubscriber = {75      onInteractionScheduledWorkCompleted,76      onInteractionTraced,77      onWorkCanceled,78      onWorkScheduled,79      onWorkStarted,80      onWorkStopped,81    };82    secondSubscriber = {83      onInteractionScheduledWorkCompleted: jest.fn(),84      onInteractionTraced: jest.fn(),85      onWorkCanceled: jest.fn(),86      onWorkScheduled: jest.fn(),87      onWorkStarted: jest.fn(),88      onWorkStopped: jest.fn(),89    };90    if (autoSubscribe) {91      SchedulerTracing.unstable_subscribe(firstSubscriber);92      SchedulerTracing.unstable_subscribe(secondSubscriber);93    }94  }95  describe('enabled', () => {96    beforeEach(() => loadModules({enableSchedulerTracing: true}));97    it('should lazily subscribe to tracing and unsubscribe again if there are no external subscribers', () => {98      loadModules({enableSchedulerTracing: true, autoSubscribe: false});99      expect(SchedulerTracing.__subscriberRef.current).toBe(null);100      SchedulerTracing.unstable_subscribe(firstSubscriber);101      expect(SchedulerTracing.__subscriberRef.current).toBeDefined();102      SchedulerTracing.unstable_subscribe(secondSubscriber);103      expect(SchedulerTracing.__subscriberRef.current).toBeDefined();104      SchedulerTracing.unstable_unsubscribe(secondSubscriber);105      expect(SchedulerTracing.__subscriberRef.current).toBeDefined();106      SchedulerTracing.unstable_unsubscribe(firstSubscriber);107      expect(SchedulerTracing.__subscriberRef.current).toBe(null);108    });109    describe('error handling', () => {110      it('should cover onInteractionTraced/onWorkStarted within', done => {111        SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {112          const mock = jest.fn();113          // It should call the callback before re-throwing114          throwInOnInteractionTraced = true;115          expect(() =>116            SchedulerTracing.unstable_trace(117              secondEvent.name,118              currentTime,119              mock,120              threadID,121            ),122          ).toThrow('Expected error onInteractionTraced');123          throwInOnInteractionTraced = false;124          expect(mock).toHaveBeenCalledTimes(1);125          throwInOnWorkStarted = true;126          expect(() =>127            SchedulerTracing.unstable_trace(128              secondEvent.name,129              currentTime,130              mock,131              threadID,132            ),133          ).toThrow('Expected error onWorkStarted');134          expect(mock).toHaveBeenCalledTimes(2);135          // It should restore the previous/outer interactions136          expect(SchedulerTracing.unstable_getCurrent()).toMatchInteractions([137            firstEvent,138          ]);139          // It should call other subscribers despite the earlier error140          expect(secondSubscriber.onInteractionTraced).toHaveBeenCalledTimes(3);141          expect(secondSubscriber.onWorkStarted).toHaveBeenCalledTimes(3);142          done();143        });144      });145      it('should cover onWorkStopped within trace', done => {146        SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {147          let innerInteraction;148          const mock = jest.fn(() => {149            innerInteraction = Array.from(150              SchedulerTracing.unstable_getCurrent(),151            )[1];152          });153          throwInOnWorkStopped = true;154          expect(() =>155            SchedulerTracing.unstable_trace(156              secondEvent.name,157              currentTime,158              mock,159            ),160          ).toThrow('Expected error onWorkStopped');161          throwInOnWorkStopped = false;162          // It should restore the previous/outer interactions163          expect(SchedulerTracing.unstable_getCurrent()).toMatchInteractions([164            firstEvent,165          ]);166          // It should update the interaction count so as not to interfere with subsequent calls167          expect(innerInteraction.__count).toBe(0);168          // It should call other subscribers despite the earlier error169          expect(secondSubscriber.onWorkStopped).toHaveBeenCalledTimes(1);170          done();171        });172      });173      it('should cover onInteractionScheduledWorkCompleted within trace', done => {174        SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {175          const mock = jest.fn();176          throwInOnInteractionScheduledWorkCompleted = true;177          expect(() =>178            SchedulerTracing.unstable_trace(179              secondEvent.name,180              currentTime,181              mock,182            ),183          ).toThrow('Expected error onInteractionScheduledWorkCompleted');184          throwInOnInteractionScheduledWorkCompleted = false;185          // It should restore the previous/outer interactions186          expect(SchedulerTracing.unstable_getCurrent()).toMatchInteractions([187            firstEvent,188          ]);189          // It should call other subscribers despite the earlier error190          expect(191            secondSubscriber.onInteractionScheduledWorkCompleted,192          ).toHaveBeenCalledTimes(1);193          done();194        });195      });196      it('should cover the callback within trace', done => {197        expect(onWorkStarted).not.toHaveBeenCalled();198        expect(onWorkStopped).not.toHaveBeenCalled();199        expect(() => {200          SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {201            throw Error('Expected error callback');202          });203        }).toThrow('Expected error callback');204        expect(onWorkStarted).toHaveBeenCalledTimes(1);205        expect(onWorkStopped).toHaveBeenCalledTimes(1);206        done();207      });208      it('should cover onWorkScheduled within wrap', done => {209        SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {210          const interaction = Array.from(211            SchedulerTracing.unstable_getCurrent(),212          )[0];213          const beforeCount = interaction.__count;214          throwInOnWorkScheduled = true;215          expect(() => SchedulerTracing.unstable_wrap(() => {})).toThrow(216            'Expected error onWorkScheduled',217          );218          // It should not update the interaction count so as not to interfere with subsequent calls219          expect(interaction.__count).toBe(beforeCount);220          // It should call other subscribers despite the earlier error221          expect(secondSubscriber.onWorkScheduled).toHaveBeenCalledTimes(1);222          done();223        });224      });225      it('should cover onWorkStarted within wrap', () => {226        const mock = jest.fn();227        let interaction, wrapped;228        SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {229          interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];230          wrapped = SchedulerTracing.unstable_wrap(mock);231        });232        expect(interaction.__count).toBe(1);233        throwInOnWorkStarted = true;234        expect(wrapped).toThrow('Expected error onWorkStarted');235        // It should call the callback before re-throwing236        expect(mock).toHaveBeenCalledTimes(1);237        // It should update the interaction count so as not to interfere with subsequent calls238        expect(interaction.__count).toBe(0);239        // It should call other subscribers despite the earlier error240        expect(secondSubscriber.onWorkStarted).toHaveBeenCalledTimes(2);241      });242      it('should cover onWorkStopped within wrap', done => {243        SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {244          const outerInteraction = Array.from(245            SchedulerTracing.unstable_getCurrent(),246          )[0];247          expect(outerInteraction.__count).toBe(1);248          let wrapped;249          let innerInteraction;250          SchedulerTracing.unstable_trace(secondEvent.name, currentTime, () => {251            innerInteraction = Array.from(252              SchedulerTracing.unstable_getCurrent(),253            )[1];254            expect(outerInteraction.__count).toBe(1);255            expect(innerInteraction.__count).toBe(1);256            wrapped = SchedulerTracing.unstable_wrap(jest.fn());257            expect(outerInteraction.__count).toBe(2);258            expect(innerInteraction.__count).toBe(2);259          });260          expect(outerInteraction.__count).toBe(2);261          expect(innerInteraction.__count).toBe(1);262          throwInOnWorkStopped = true;263          expect(wrapped).toThrow('Expected error onWorkStopped');264          throwInOnWorkStopped = false;265          // It should restore the previous interactions266          expect(SchedulerTracing.unstable_getCurrent()).toMatchInteractions([267            outerInteraction,268          ]);269          // It should update the interaction count so as not to interfere with subsequent calls270          expect(outerInteraction.__count).toBe(1);271          expect(innerInteraction.__count).toBe(0);272          expect(secondSubscriber.onWorkStopped).toHaveBeenCalledTimes(2);273          done();274        });275      });276      it('should cover the callback within wrap', done => {277        expect(onWorkStarted).not.toHaveBeenCalled();278        expect(onWorkStopped).not.toHaveBeenCalled();279        let wrapped;280        let interaction;281        SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {282          interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];283          wrapped = SchedulerTracing.unstable_wrap(() => {284            throw Error('Expected error wrap');285          });286        });287        expect(onWorkStarted).toHaveBeenCalledTimes(1);288        expect(onWorkStopped).toHaveBeenCalledTimes(1);289        expect(wrapped).toThrow('Expected error wrap');290        expect(onWorkStarted).toHaveBeenCalledTimes(2);291        expect(onWorkStopped).toHaveBeenCalledTimes(2);292        expect(onWorkStopped).toHaveBeenLastNotifiedOfWork([interaction]);293        done();294      });295      it('should cover onWorkCanceled within wrap', () => {296        let interaction, wrapped;297        SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {298          interaction = Array.from(SchedulerTracing.unstable_getCurrent())[0];299          wrapped = SchedulerTracing.unstable_wrap(jest.fn());300        });301        expect(interaction.__count).toBe(1);302        throwInOnWorkCanceled = true;303        expect(wrapped.cancel).toThrow('Expected error onWorkCanceled');304        expect(onWorkCanceled).toHaveBeenCalledTimes(1);305        // It should update the interaction count so as not to interfere with subsequent calls306        expect(interaction.__count).toBe(0);307        expect(308          onInteractionScheduledWorkCompleted,309        ).toHaveBeenLastNotifiedOfInteraction(firstEvent);310        // It should call other subscribers despite the earlier error311        expect(secondSubscriber.onWorkCanceled).toHaveBeenCalledTimes(1);312      });313    });314    it('calls lifecycle methods for trace', () => {315      expect(onInteractionTraced).not.toHaveBeenCalled();316      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();317      SchedulerTracing.unstable_trace(318        firstEvent.name,319        currentTime,320        () => {321          expect(onInteractionTraced).toHaveBeenCalledTimes(1);322          expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(323            firstEvent,324          );325          expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();326          expect(onWorkStarted).toHaveBeenCalledTimes(1);327          expect(onWorkStarted).toHaveBeenLastNotifiedOfWork(328            new Set([firstEvent]),329            threadID,330          );331          expect(onWorkStopped).not.toHaveBeenCalled();332          SchedulerTracing.unstable_trace(333            secondEvent.name,334            currentTime,335            () => {336              expect(onInteractionTraced).toHaveBeenCalledTimes(2);337              expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(338                secondEvent,339              );340              expect(341                onInteractionScheduledWorkCompleted,342              ).not.toHaveBeenCalled();343              expect(onWorkStarted).toHaveBeenCalledTimes(2);344              expect(onWorkStarted).toHaveBeenLastNotifiedOfWork(345                new Set([firstEvent, secondEvent]),346                threadID,347              );348              expect(onWorkStopped).not.toHaveBeenCalled();349            },350            threadID,351          );352          expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);353          expect(354            onInteractionScheduledWorkCompleted,355          ).toHaveBeenLastNotifiedOfInteraction(secondEvent);356          expect(onWorkStopped).toHaveBeenCalledTimes(1);357          expect(onWorkStopped).toHaveBeenLastNotifiedOfWork(358            new Set([firstEvent, secondEvent]),359            threadID,360          );361        },362        threadID,363      );364      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(2);365      expect(366        onInteractionScheduledWorkCompleted,367      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);368      expect(onWorkScheduled).not.toHaveBeenCalled();369      expect(onWorkCanceled).not.toHaveBeenCalled();370      expect(onWorkStarted).toHaveBeenCalledTimes(2);371      expect(onWorkStopped).toHaveBeenCalledTimes(2);372      expect(onWorkStopped).toHaveBeenLastNotifiedOfWork(373        new Set([firstEvent]),374        threadID,375      );376    });377    it('calls lifecycle methods for wrap', () => {378      const unwrapped = jest.fn();379      let wrapped;380      SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {381        expect(onInteractionTraced).toHaveBeenCalledTimes(1);382        expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(383          firstEvent,384        );385        SchedulerTracing.unstable_trace(secondEvent.name, currentTime, () => {386          expect(onInteractionTraced).toHaveBeenCalledTimes(2);387          expect(onInteractionTraced).toHaveBeenLastNotifiedOfInteraction(388            secondEvent,389          );390          wrapped = SchedulerTracing.unstable_wrap(unwrapped, threadID);391          expect(onWorkScheduled).toHaveBeenCalledTimes(1);392          expect(onWorkScheduled).toHaveBeenLastNotifiedOfWork(393            new Set([firstEvent, secondEvent]),394            threadID,395          );396        });397      });398      expect(onInteractionTraced).toHaveBeenCalledTimes(2);399      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();400      wrapped();401      expect(unwrapped).toHaveBeenCalled();402      expect(onWorkScheduled).toHaveBeenCalledTimes(1);403      expect(onWorkCanceled).not.toHaveBeenCalled();404      expect(onWorkStarted).toHaveBeenCalledTimes(3);405      expect(onWorkStarted).toHaveBeenLastNotifiedOfWork(406        new Set([firstEvent, secondEvent]),407        threadID,408      );409      expect(onWorkStopped).toHaveBeenCalledTimes(3);410      expect(onWorkStopped).toHaveBeenLastNotifiedOfWork(411        new Set([firstEvent, secondEvent]),412        threadID,413      );414      expect(415        onInteractionScheduledWorkCompleted.mock.calls[0][0],416      ).toMatchInteraction(firstEvent);417      expect(418        onInteractionScheduledWorkCompleted.mock.calls[1][0],419      ).toMatchInteraction(secondEvent);420    });421    it('should call the correct interaction subscriber methods when a wrapped callback is canceled', () => {422      const fnOne = jest.fn();423      const fnTwo = jest.fn();424      let wrappedOne, wrappedTwo;425      SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {426        wrappedOne = SchedulerTracing.unstable_wrap(fnOne, threadID);427        SchedulerTracing.unstable_trace(secondEvent.name, currentTime, () => {428          wrappedTwo = SchedulerTracing.unstable_wrap(fnTwo, threadID);429        });430      });431      expect(onInteractionTraced).toHaveBeenCalledTimes(2);432      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();433      expect(onWorkCanceled).not.toHaveBeenCalled();434      expect(onWorkStarted).toHaveBeenCalledTimes(2);435      expect(onWorkStopped).toHaveBeenCalledTimes(2);436      wrappedTwo.cancel();437      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);438      expect(439        onInteractionScheduledWorkCompleted,440      ).toHaveBeenLastNotifiedOfInteraction(secondEvent);441      expect(onWorkCanceled).toHaveBeenCalledTimes(1);442      expect(onWorkCanceled).toHaveBeenLastNotifiedOfWork(443        new Set([firstEvent, secondEvent]),444        threadID,445      );446      wrappedOne.cancel();447      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(2);448      expect(449        onInteractionScheduledWorkCompleted,450      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);451      expect(onWorkCanceled).toHaveBeenCalledTimes(2);452      expect(onWorkCanceled).toHaveBeenLastNotifiedOfWork(453        new Set([firstEvent]),454        threadID,455      );456      expect(fnOne).not.toHaveBeenCalled();457      expect(fnTwo).not.toHaveBeenCalled();458    });459    it('should not end an interaction twice if wrap is used to schedule follow up work within another wrap', () => {460      const fnOne = jest.fn(() => {461        wrappedTwo = SchedulerTracing.unstable_wrap(fnTwo, threadID);462      });463      const fnTwo = jest.fn();464      let wrappedOne, wrappedTwo;465      SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {466        wrappedOne = SchedulerTracing.unstable_wrap(fnOne, threadID);467      });468      expect(onInteractionTraced).toHaveBeenCalledTimes(1);469      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();470      wrappedOne();471      expect(onInteractionTraced).toHaveBeenCalledTimes(1);472      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();473      wrappedTwo();474      expect(onInteractionTraced).toHaveBeenCalledTimes(1);475      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);476      expect(477        onInteractionScheduledWorkCompleted,478      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);479    });480    it('should not decrement the interaction count twice if a wrapped function is run twice', () => {481      const unwrappedOne = jest.fn();482      const unwrappedTwo = jest.fn();483      let wrappedOne, wrappedTwo;484      SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {485        wrappedOne = SchedulerTracing.unstable_wrap(unwrappedOne, threadID);486        wrappedTwo = SchedulerTracing.unstable_wrap(unwrappedTwo, threadID);487      });488      expect(onInteractionTraced).toHaveBeenCalledTimes(1);489      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();490      wrappedOne();491      expect(unwrappedOne).toHaveBeenCalledTimes(1);492      expect(onInteractionTraced).toHaveBeenCalledTimes(1);493      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();494      wrappedOne();495      expect(unwrappedOne).toHaveBeenCalledTimes(2);496      expect(onInteractionTraced).toHaveBeenCalledTimes(1);497      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();498      wrappedTwo();499      expect(onInteractionTraced).toHaveBeenCalledTimes(1);500      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);501      expect(502        onInteractionScheduledWorkCompleted,503      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);504    });505    it('should unsubscribe', () => {506      SchedulerTracing.unstable_unsubscribe(firstSubscriber);507      SchedulerTracing.unstable_trace(firstEvent.name, currentTime, () => {});508      expect(onInteractionTraced).not.toHaveBeenCalled();509    });510  });511  describe('disabled', () => {512    beforeEach(() => loadModules({enableSchedulerTracing: false}));513    // TODO514  });...Using AI Code Generation
1const playwright = require('playwright');2(async () => {3    const browser = await playwright['chromium'].launch({ headless: false });4    const page = await browser.newPage();5    await page.click('text=Docs');6    await page.waitForSelector('text=API');7    await page.click('text=API');8    await page.waitForSelector('text=BrowserContext');9    await page.click('text=BrowserContext');10    await page.waitForSelector('text=BrowserContext');11    await page.click('text=BrowserContext');12    await page.waitForSelector('text=BrowserContext');13    await page.click('text=BrowserContext');14    await page.waitForSelector('text=BrowserContext');15    await page.click('text=BrowserContext');16    await page.waitForSelector('text=BrowserContext');17    await page.click('text=BrowserContext');18    await page.waitForSelector('text=BrowserContext');19    await page.click('text=BrowserContext');20    await page.waitForSelector('text=BrowserContext');21    await page.click('text=BrowserContext');22    await page.waitForSelector('text=BrowserContext');23    await page.click('text=BrowserContext');24    await page.waitForSelector('text=BrowserContext');25    await page.click('text=BrowserContext');26    await page.waitForSelector('text=BrowserContext');27    await page.click('text=BrowserContext');28    await page.waitForSelector('text=BrowserContext');29    await page.click('text=BrowserContext');30    await page.waitForSelector('text=BrowserContext');31    await page.click('text=BrowserContext');32    await page.waitForSelector('text=BrowserContext');33    await page.click('text=BrowserContext');34    await page.waitForSelector('text=BrowserContext');35    await page.click('text=BrowserContext');36    await page.waitForSelector('text=BrowserContext');37    await page.click('text=BrowserContext');38    await page.waitForSelector('text=BrowserContext');39    await page.click('text=BrowserContext');40    await page.waitForSelector('text=BrowserContext');41    await page.click('text=BrowserContext');42    await page.waitForSelector('text=BrowserContext');43    await page.click('text=BrowserContext');44    await page.waitForSelector('text=BrowserContext');45    await page.click('text=BrowserContext');46    await page.waitForSelector('text=BrowserContext');47    await page.click('text=BrowserContext');Using AI Code Generation
1const { Playwright } = require('playwright');2const playwright = new Playwright();3const browser = await playwright.chromium.launch();4const context = await browser.newContext();5const page = await context.newPage();6const client = await page.context().newCDPSession(page);7await client.send('Performance.enable');8await client.send('Performance.setCPUThrottlingRate', { rate: 4 });9await client.send('Performance.start');10await page.click('button');11await client.send('Performance.stop');12const metrics = await client.send('Performance.getMetrics');13const { duration } = metrics.metrics.find(m => m.name === 'Timestamp::DocumentInteractive');14console.log('DocumentInteractive: ' + duration);15await browser.close();Using AI Code Generation
1const { Playwright } = require('playwright');2const playwright = new Playwright();3const browser = await playwright.webkit.launch();4const context = await browser.newContext();5const page = await context.newPage();6await page.screenshot({ path: 'example.png' });7await browser.close();8const { Playwright } = require('playwright');9const playwright = new Playwright();10const browser = await playwright.webkit.launch();11const context = await browser.newContext();12const page = await context.newPage();13await page.waitForSelector('text=Get started');14await page.click('text=Get started');15await browser.close();16const { Playwright } = require('playwright');17const playwright = new Playwright();18const browser = await playwright.webkit.launch();19const context = await browser.newContext();20const page = await context.newPage();21await page.waitForSelector('text=Get started');22await page.click('text=Get started');23await page.waitForSelector('text=Install Playwright');24await browser.close();25const { Playwright } = require('playwright');26const playwright = new Playwright();27const browser = await playwright.webkit.launch();28const context = await browser.newContext();29const page = await context.newPage();30await page.waitForSelector('Using AI Code Generation
1const playwright = require('playwright');2const { Playwright } = require('playwright/lib/server/playwright');3const { PlaywrightServer } = require('playwright/lib/server/playwrightServer');4const { PlaywrightDispatcher } = require('playwright/lib/server/playwrightDispatcher');5const { DispatcherConnection } = require('playwright/lib/server/dispatchers/dispatcher');6const { PlaywrightChannel } = require('playwright/lib/server/playwright');7const { PlaywrightClient } = require('playwright/lib/client/playwright');8const { BrowserServer } = require('playwright/lib/server/browserServer');9const { BrowserServerChannel } = require('playwright/lib/server/browserServer');10const { BrowserServerDispatcher } = require('playwright/lib/server/browserServerDispatcher');11const { BrowserContextChannel } = require('playwright/lib/server/browserContext');12const { BrowserContextDispatcher } = require('playwright/lib/server/browserContextDispatcher');13const { BrowserContext } = require('playwright/lib/server/browserContext');14const { BrowserChannel } = require('playwright/lib/server/browser');15const { BrowserDispatcher } = require('playwright/lib/server/browserDispatcher');16const { Browser } = require('playwright/lib/server/browser');17const { PageChannel } = require('playwright/lib/server/page');18const { PageDispatcher } = require('playwright/lib/server/pageDispatcher');19const { Page } = require('playwright/lib/server/page');20const { FrameChannel } = require('playwright/lib/server/frame');21const { FrameDispatcher } = require('playwright/lib/server/frameDispatcher');22const { Frame } = require('playwright/lib/server/frame');23const { WorkerChannel } = require('playwright/lib/server/worker');24const { WorkerDispatcher } = require('playwright/lib/server/workerDispatcher');25const { Worker } = require('playwright/lib/server/worker');26const { WebsocketServer } = require('playwright/lib/server/websocketServer');27const { WebsocketTransport } = require('playwright/lib/server/websocketTransport');28const { WebsocketServerTransport } = require('playwright/lib/server/websocketServerTransport');29const { WebSocketTransport } = require('playwright/lib/server/webSocketTransport');30const { WebSocketServerTransport } = require('playwright/lib/server/webSocketServerTransport');31const { WebSocketServer } = require('playwright/lib/server/webSocketServer');32const { WebSocketChannel } = require('playwright/lib/server/webSocketChannel');33const { WebSocketDispatcherUsing AI Code Generation
1const { Playwright } = require('playwright-core');2const playwright = new Playwright();3const browser = await playwright.chromium.launch();4const context = await browser.newContext();5const page = await context.newPage();6const worker = await page.evaluateHandle(() => new Worker(URL.createObjectURL(new Blob(['console.log("hey!")'], {type: 'application/javascript'}))));7await worker.evaluate(() => new Promise(f => setTimeout(f, 1000)));8await playwright._onWorkerCreated(worker);9await playwright._onWorkerDestroyed(worker);10await browser.close();Using AI Code Generation
1const playwright = require('playwright');2const { Playwright } = require('playwright-core/lib/server/playwright.js');3async function main() {4  const browser = await playwright.chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  await page.click('text=Get started');8  await page.waitForTimeout(5000);9  await browser.close();10}11main();12const { Playwright } = require('playwright-core/lib/server/playwright.js');13async function main() {14  const browser = await playwright.chromium.launch();15  const context = await browser.newContext();16  const page = await context.newPage();17  await page.click('text=Get started');18  await page.waitForTimeout(5000);19  await browser.close();20}21main();22const { Playwright } = require('playwright-core/lib/server/playwright.js');23async function main() {24  const browser = await playwright.chromium.launch();25  const context = await browser.newContext();26  const page = await context.newPage();27  await page.click('text=Get started');28  await page.waitForTimeout(5000);29  await browser.close();30}31main();32const { Playwright } = require('playwright-core/lib/server/playwright.js');33async function main() {34  const browser = await playwright.chromium.launch();35  const context = await browser.newContext();36  const page = await context.newPage();37  await page.click('text=Get started');38  await page.waitForTimeout(5000);39  await browser.close();40}41main();42const { Playwright } = require('playwright-core/lib/server/playwright.js');43async function main() {44  const browser = await playwright.chromium.launch();45  const context = await browser.newContext();46  const page = await context.newPage();47  await page.click('text=Get startedUsing AI Code Generation
1const playwright = require('playwright');2const { InternalApi } = require('playwright/lib/server/frames');3const { Frame } = require('playwright/lib/server/frames');4const { Page } = require('playwright/lib/server/page');5const { chromium, webkit, firefox } = require('playwright');6(async () => {7  const browser = await chromium.launch({ headless: false });8  const context = await browser.newContext();9  const page = await context.newPage();10  await page.screenshot({ path: `example.png` });11  await browser.close();12})();13const playwright = require('playwright');14const { InternalApi } = require('playwright/lib/server/frames');15const { Frame } = require('playwright/lib/server/frames');16const { Page } = require('playwright/lib/server/page');17const { chromium, webkit, firefox } = require('playwright');18(async () => {19  const browser = await chromium.launch({ headless: false });20  const context = await browser.newContext();21  const page = await context.newPage();22  await page.screenshot({ path: `example.png` });23  await browser.close();24})();25const playwright = require('playwright');26const { InternalApi } = require('playwright/lib/server/frames');27const { Frame } = require('playwright/lib/server/frames');28const { Page } = require('playwright/lib/server/page');29const { chromium, webkit, firefox } = require('playwright');30(async () => {31  const browser = await chromium.launch({ headless: false });32  const context = await browser.newContext();33  const page = await context.newPage();34  await page.screenshot({ path: `example.png` });35  await browser.close();36})();37const playwright = require('playwright');38const { InternalApi } = require('playwright/lib/server/frames');39const { Frame } = require('playwright/lib/server/frames');40const { Page } = require('playwright/lib/server/page');41const { chromium, webkit, firefox } = require('Using AI Code Generation
1const { Playwright } = require('@playwright/test');2const playwrightInternal = new Playwright();3const playwright = new Playwright();4const browser = await playwright.chromium.launch({ headless: false });5const context = await browser.newContext();6const page = await context.newPage();7await page.click('text=Get started');8await playwrightInternal._inflightRecorder.onInteractionScheduledWorkCompleted(page);9- The generated code uses ES6 modules. So, you can import the files as shown below:10  import Login from './generated/Login.js';11  const login = new Login(page);12  await login.enterUsername('username');13  await login.enterPassword('password');14  await login.clickLogin();15  import { test, expect } from '@playwright/test';16  import Login from './generated/Login.js';17  test('Login test', async ({ page }) => {18    const login = new Login(page);19    await login.enterUsername('username');20    await login.enterPassword('password');21    await login.clickLogin();22    expect(await page.innerText('.login-success')).toBe('Login successful');23  });24- If you want to use the generated code with Playwright Test, you can use the `playwright-test-codegen` package to generate the test files for you. The generated test files will use the generated code. The generated test files will also have the `test` and `expect` imports. You can install the `playwright-test-codegen` package as shown below:Using AI Code Generation
1const playwright = require('playwright');2(async () => {3  for (const browserType of BROWSER) {4    const browser = await playwright[browserType].launch();5    const context = await browser.newContext();6    const page = await context.newPage();7    await page.screenshot({ path: `example-${browserType}.png` });8    await browser.close();9  }10})();11const playwright = require('playwright');12(async () => {13  for (const browserType of BROWSER) {14    const browser = await playwright[browserType].launch();15    const context = await browser.newContext();16    const page = await context.newPage();17    await page.screenshot({ path: `example-${browserType}.png` });18    await browser.close();19  }20})();21const playwright = require('playwright');22(async () => {23  for (const browserType of BROWSER) {24    const browser = await playwright[browserType].launch();25    const context = await browser.newContext();26    const page = await context.newPage();27    await page.screenshot({ path: `example-${browserType}.png` });28    await browser.close();29  }30})();31const playwright = require('playwright');32(async () => {33  for (const browserType of BROWSER) {34    const browser = await playwright[browserType].launch();35    const context = await browser.newContext();36    const page = await context.newPage();LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
