Best JavaScript code snippet using playwright-internal
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  });...InteractionTrackingSubscriptions-test.internal.js
Source:InteractionTrackingSubscriptions-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('InteractionTracking', () => {11  let InteractionTracking;12  let InteractionTrackingSubscriptions;13  let ReactFeatureFlags;14  let currentTime;15  let onInteractionScheduledWorkCompleted;16  let onInteractionTracked;17  let onWorkCanceled;18  let onWorkScheduled;19  let onWorkStarted;20  let onWorkStopped;21  let throwInOnInteractionScheduledWorkCompleted;22  let throwInOnInteractionTracked;23  let throwInOnWorkCanceled;24  let throwInOnWorkScheduled;25  let throwInOnWorkStarted;26  let throwInOnWorkStopped;27  let firstSubscriber;28  let secondSubscriber;29  const firstEvent = {id: 0, name: 'first', timestamp: 0};30  const secondEvent = {id: 1, name: 'second', timestamp: 0};31  const threadID = 123;32  function loadModules({enableInteractionTracking}) {33    jest.resetModules();34    jest.useFakeTimers();35    currentTime = 0;36    ReactFeatureFlags = require('shared/ReactFeatureFlags');37    ReactFeatureFlags.enableInteractionTracking = enableInteractionTracking;38    InteractionTracking = require('interaction-tracking');39    InteractionTrackingSubscriptions = require('interaction-tracking/subscriptions');40    throwInOnInteractionScheduledWorkCompleted = false;41    throwInOnInteractionTracked = false;42    throwInOnWorkCanceled = false;43    throwInOnWorkScheduled = false;44    throwInOnWorkStarted = false;45    throwInOnWorkStopped = false;46    onInteractionScheduledWorkCompleted = jest.fn(() => {47      if (throwInOnInteractionScheduledWorkCompleted) {48        throw Error('Expected error onInteractionScheduledWorkCompleted');49      }50    });51    onInteractionTracked = jest.fn(() => {52      if (throwInOnInteractionTracked) {53        throw Error('Expected error onInteractionTracked');54      }55    });56    onWorkCanceled = jest.fn(() => {57      if (throwInOnWorkCanceled) {58        throw Error('Expected error onWorkCanceled');59      }60    });61    onWorkScheduled = jest.fn(() => {62      if (throwInOnWorkScheduled) {63        throw Error('Expected error onWorkScheduled');64      }65    });66    onWorkStarted = jest.fn(() => {67      if (throwInOnWorkStarted) {68        throw Error('Expected error onWorkStarted');69      }70    });71    onWorkStopped = jest.fn(() => {72      if (throwInOnWorkStopped) {73        throw Error('Expected error onWorkStopped');74      }75    });76    firstSubscriber = {77      onInteractionScheduledWorkCompleted,78      onInteractionTracked,79      onWorkCanceled,80      onWorkScheduled,81      onWorkStarted,82      onWorkStopped,83    };84    secondSubscriber = {85      onInteractionScheduledWorkCompleted: jest.fn(),86      onInteractionTracked: jest.fn(),87      onWorkCanceled: jest.fn(),88      onWorkScheduled: jest.fn(),89      onWorkStarted: jest.fn(),90      onWorkStopped: jest.fn(),91    };92    InteractionTrackingSubscriptions.subscribe(firstSubscriber);93    InteractionTrackingSubscriptions.subscribe(secondSubscriber);94  }95  describe('enabled', () => {96    beforeEach(() => loadModules({enableInteractionTracking: true}));97    describe('error handling', () => {98      it('should cover onInteractionTracked/onWorkStarted within', done => {99        InteractionTracking.track(firstEvent.name, currentTime, () => {100          const mock = jest.fn();101          // It should call the callback before re-throwing102          throwInOnInteractionTracked = true;103          expect(() =>104            InteractionTracking.track(105              secondEvent.name,106              currentTime,107              mock,108              threadID,109            ),110          ).toThrow('Expected error onInteractionTracked');111          throwInOnInteractionTracked = false;112          expect(mock).toHaveBeenCalledTimes(1);113          throwInOnWorkStarted = true;114          expect(() =>115            InteractionTracking.track(116              secondEvent.name,117              currentTime,118              mock,119              threadID,120            ),121          ).toThrow('Expected error onWorkStarted');122          expect(mock).toHaveBeenCalledTimes(2);123          // It should restore the previous/outer interactions124          expect(InteractionTracking.getCurrent()).toMatchInteractions([125            firstEvent,126          ]);127          // It should call other subscribers despite the earlier error128          expect(secondSubscriber.onInteractionTracked).toHaveBeenCalledTimes(129            3,130          );131          expect(secondSubscriber.onWorkStarted).toHaveBeenCalledTimes(3);132          done();133        });134      });135      it('should cover onWorkStopped within track', done => {136        InteractionTracking.track(firstEvent.name, currentTime, () => {137          let innerInteraction;138          const mock = jest.fn(() => {139            innerInteraction = Array.from(InteractionTracking.getCurrent())[1];140          });141          throwInOnWorkStopped = true;142          expect(() =>143            InteractionTracking.track(secondEvent.name, currentTime, mock),144          ).toThrow('Expected error onWorkStopped');145          throwInOnWorkStopped = false;146          // It should restore the previous/outer interactions147          expect(InteractionTracking.getCurrent()).toMatchInteractions([148            firstEvent,149          ]);150          // It should update the interaction count so as not to interfere with subsequent calls151          expect(innerInteraction.__count).toBe(0);152          // It should call other subscribers despite the earlier error153          expect(secondSubscriber.onWorkStopped).toHaveBeenCalledTimes(1);154          done();155        });156      });157      it('should cover onInteractionScheduledWorkCompleted within track', done => {158        InteractionTracking.track(firstEvent.name, currentTime, () => {159          const mock = jest.fn();160          throwInOnInteractionScheduledWorkCompleted = true;161          expect(() =>162            InteractionTracking.track(secondEvent.name, currentTime, mock),163          ).toThrow('Expected error onInteractionScheduledWorkCompleted');164          throwInOnInteractionScheduledWorkCompleted = false;165          // It should restore the previous/outer interactions166          expect(InteractionTracking.getCurrent()).toMatchInteractions([167            firstEvent,168          ]);169          // It should call other subscribers despite the earlier error170          expect(171            secondSubscriber.onInteractionScheduledWorkCompleted,172          ).toHaveBeenCalledTimes(1);173          done();174        });175      });176      it('should cover the callback within track', done => {177        expect(onWorkStarted).not.toHaveBeenCalled();178        expect(onWorkStopped).not.toHaveBeenCalled();179        expect(() => {180          InteractionTracking.track(firstEvent.name, currentTime, () => {181            throw Error('Expected error callback');182          });183        }).toThrow('Expected error callback');184        expect(onWorkStarted).toHaveBeenCalledTimes(1);185        expect(onWorkStopped).toHaveBeenCalledTimes(1);186        done();187      });188      it('should cover onWorkScheduled within wrap', done => {189        InteractionTracking.track(firstEvent.name, currentTime, () => {190          const interaction = Array.from(InteractionTracking.getCurrent())[0];191          const beforeCount = interaction.__count;192          throwInOnWorkScheduled = true;193          expect(() => InteractionTracking.wrap(() => {})).toThrow(194            'Expected error onWorkScheduled',195          );196          // It should not update the interaction count so as not to interfere with subsequent calls197          expect(interaction.__count).toBe(beforeCount);198          // It should call other subscribers despite the earlier error199          expect(secondSubscriber.onWorkScheduled).toHaveBeenCalledTimes(1);200          done();201        });202      });203      it('should cover onWorkStarted within wrap', () => {204        const mock = jest.fn();205        let interaction, wrapped;206        InteractionTracking.track(firstEvent.name, currentTime, () => {207          interaction = Array.from(InteractionTracking.getCurrent())[0];208          wrapped = InteractionTracking.wrap(mock);209        });210        expect(interaction.__count).toBe(1);211        throwInOnWorkStarted = true;212        expect(wrapped).toThrow('Expected error onWorkStarted');213        // It should call the callback before re-throwing214        expect(mock).toHaveBeenCalledTimes(1);215        // It should update the interaction count so as not to interfere with subsequent calls216        expect(interaction.__count).toBe(0);217        // It should call other subscribers despite the earlier error218        expect(secondSubscriber.onWorkStarted).toHaveBeenCalledTimes(2);219      });220      it('should cover onWorkStopped within wrap', done => {221        InteractionTracking.track(firstEvent.name, currentTime, () => {222          const outerInteraction = Array.from(223            InteractionTracking.getCurrent(),224          )[0];225          expect(outerInteraction.__count).toBe(1);226          let wrapped;227          let innerInteraction;228          InteractionTracking.track(secondEvent.name, currentTime, () => {229            innerInteraction = Array.from(InteractionTracking.getCurrent())[1];230            expect(outerInteraction.__count).toBe(1);231            expect(innerInteraction.__count).toBe(1);232            wrapped = InteractionTracking.wrap(jest.fn());233            expect(outerInteraction.__count).toBe(2);234            expect(innerInteraction.__count).toBe(2);235          });236          expect(outerInteraction.__count).toBe(2);237          expect(innerInteraction.__count).toBe(1);238          throwInOnWorkStopped = true;239          expect(wrapped).toThrow('Expected error onWorkStopped');240          throwInOnWorkStopped = false;241          // It should restore the previous interactions242          expect(InteractionTracking.getCurrent()).toMatchInteractions([243            outerInteraction,244          ]);245          // It should update the interaction count so as not to interfere with subsequent calls246          expect(outerInteraction.__count).toBe(1);247          expect(innerInteraction.__count).toBe(0);248          expect(secondSubscriber.onWorkStopped).toHaveBeenCalledTimes(2);249          done();250        });251      });252      it('should cover the callback within wrap', done => {253        expect(onWorkStarted).not.toHaveBeenCalled();254        expect(onWorkStopped).not.toHaveBeenCalled();255        let wrapped;256        let interaction;257        InteractionTracking.track(firstEvent.name, currentTime, () => {258          interaction = Array.from(InteractionTracking.getCurrent())[0];259          wrapped = InteractionTracking.wrap(() => {260            throw Error('Expected error wrap');261          });262        });263        expect(onWorkStarted).toHaveBeenCalledTimes(1);264        expect(onWorkStopped).toHaveBeenCalledTimes(1);265        expect(wrapped).toThrow('Expected error wrap');266        expect(onWorkStarted).toHaveBeenCalledTimes(2);267        expect(onWorkStopped).toHaveBeenCalledTimes(2);268        expect(onWorkStopped).toHaveBeenLastNotifiedOfWork([interaction]);269        done();270      });271      it('should cover onWorkCanceled within wrap', () => {272        let interaction, wrapped;273        InteractionTracking.track(firstEvent.name, currentTime, () => {274          interaction = Array.from(InteractionTracking.getCurrent())[0];275          wrapped = InteractionTracking.wrap(jest.fn());276        });277        expect(interaction.__count).toBe(1);278        throwInOnWorkCanceled = true;279        expect(wrapped.cancel).toThrow('Expected error onWorkCanceled');280        expect(onWorkCanceled).toHaveBeenCalledTimes(1);281        // It should update the interaction count so as not to interfere with subsequent calls282        expect(interaction.__count).toBe(0);283        expect(284          onInteractionScheduledWorkCompleted,285        ).toHaveBeenLastNotifiedOfInteraction(firstEvent);286        // It should call other subscribers despite the earlier error287        expect(secondSubscriber.onWorkCanceled).toHaveBeenCalledTimes(1);288      });289    });290    it('calls lifecycle methods for track', () => {291      expect(onInteractionTracked).not.toHaveBeenCalled();292      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();293      InteractionTracking.track(294        firstEvent.name,295        currentTime,296        () => {297          expect(onInteractionTracked).toHaveBeenCalledTimes(1);298          expect(onInteractionTracked).toHaveBeenLastNotifiedOfInteraction(299            firstEvent,300          );301          expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();302          expect(onWorkStarted).toHaveBeenCalledTimes(1);303          expect(onWorkStarted).toHaveBeenLastNotifiedOfWork(304            new Set([firstEvent]),305            threadID,306          );307          expect(onWorkStopped).not.toHaveBeenCalled();308          InteractionTracking.track(309            secondEvent.name,310            currentTime,311            () => {312              expect(onInteractionTracked).toHaveBeenCalledTimes(2);313              expect(onInteractionTracked).toHaveBeenLastNotifiedOfInteraction(314                secondEvent,315              );316              expect(317                onInteractionScheduledWorkCompleted,318              ).not.toHaveBeenCalled();319              expect(onWorkStarted).toHaveBeenCalledTimes(2);320              expect(onWorkStarted).toHaveBeenLastNotifiedOfWork(321                new Set([firstEvent, secondEvent]),322                threadID,323              );324              expect(onWorkStopped).not.toHaveBeenCalled();325            },326            threadID,327          );328          expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);329          expect(330            onInteractionScheduledWorkCompleted,331          ).toHaveBeenLastNotifiedOfInteraction(secondEvent);332          expect(onWorkStopped).toHaveBeenCalledTimes(1);333          expect(onWorkStopped).toHaveBeenLastNotifiedOfWork(334            new Set([firstEvent, secondEvent]),335            threadID,336          );337        },338        threadID,339      );340      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(2);341      expect(342        onInteractionScheduledWorkCompleted,343      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);344      expect(onWorkScheduled).not.toHaveBeenCalled();345      expect(onWorkCanceled).not.toHaveBeenCalled();346      expect(onWorkStarted).toHaveBeenCalledTimes(2);347      expect(onWorkStopped).toHaveBeenCalledTimes(2);348      expect(onWorkStopped).toHaveBeenLastNotifiedOfWork(349        new Set([firstEvent]),350        threadID,351      );352    });353    it('calls lifecycle methods for wrap', () => {354      const unwrapped = jest.fn();355      let wrapped;356      InteractionTracking.track(firstEvent.name, currentTime, () => {357        expect(onInteractionTracked).toHaveBeenCalledTimes(1);358        expect(onInteractionTracked).toHaveBeenLastNotifiedOfInteraction(359          firstEvent,360        );361        InteractionTracking.track(secondEvent.name, currentTime, () => {362          expect(onInteractionTracked).toHaveBeenCalledTimes(2);363          expect(onInteractionTracked).toHaveBeenLastNotifiedOfInteraction(364            secondEvent,365          );366          wrapped = InteractionTracking.wrap(unwrapped, threadID);367          expect(onWorkScheduled).toHaveBeenCalledTimes(1);368          expect(onWorkScheduled).toHaveBeenLastNotifiedOfWork(369            new Set([firstEvent, secondEvent]),370            threadID,371          );372        });373      });374      expect(onInteractionTracked).toHaveBeenCalledTimes(2);375      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();376      wrapped();377      expect(unwrapped).toHaveBeenCalled();378      expect(onWorkScheduled).toHaveBeenCalledTimes(1);379      expect(onWorkCanceled).not.toHaveBeenCalled();380      expect(onWorkStarted).toHaveBeenCalledTimes(3);381      expect(onWorkStarted).toHaveBeenLastNotifiedOfWork(382        new Set([firstEvent, secondEvent]),383        threadID,384      );385      expect(onWorkStopped).toHaveBeenCalledTimes(3);386      expect(onWorkStopped).toHaveBeenLastNotifiedOfWork(387        new Set([firstEvent, secondEvent]),388        threadID,389      );390      expect(391        onInteractionScheduledWorkCompleted.mock.calls[0][0],392      ).toMatchInteraction(firstEvent);393      expect(394        onInteractionScheduledWorkCompleted.mock.calls[1][0],395      ).toMatchInteraction(secondEvent);396    });397    it('should call the correct interaction subscriber methods when a wrapped callback is canceled', () => {398      const fnOne = jest.fn();399      const fnTwo = jest.fn();400      let wrappedOne, wrappedTwo;401      InteractionTracking.track(firstEvent.name, currentTime, () => {402        wrappedOne = InteractionTracking.wrap(fnOne, threadID);403        InteractionTracking.track(secondEvent.name, currentTime, () => {404          wrappedTwo = InteractionTracking.wrap(fnTwo, threadID);405        });406      });407      expect(onInteractionTracked).toHaveBeenCalledTimes(2);408      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();409      expect(onWorkCanceled).not.toHaveBeenCalled();410      expect(onWorkStarted).toHaveBeenCalledTimes(2);411      expect(onWorkStopped).toHaveBeenCalledTimes(2);412      wrappedTwo.cancel();413      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);414      expect(415        onInteractionScheduledWorkCompleted,416      ).toHaveBeenLastNotifiedOfInteraction(secondEvent);417      expect(onWorkCanceled).toHaveBeenCalledTimes(1);418      expect(onWorkCanceled).toHaveBeenLastNotifiedOfWork(419        new Set([firstEvent, secondEvent]),420        threadID,421      );422      wrappedOne.cancel();423      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(2);424      expect(425        onInteractionScheduledWorkCompleted,426      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);427      expect(onWorkCanceled).toHaveBeenCalledTimes(2);428      expect(onWorkCanceled).toHaveBeenLastNotifiedOfWork(429        new Set([firstEvent]),430        threadID,431      );432      expect(fnOne).not.toHaveBeenCalled();433      expect(fnTwo).not.toHaveBeenCalled();434    });435    it('should not end an interaction twice if wrap is used to schedule follow up work within another wrap', () => {436      const fnOne = jest.fn(() => {437        wrappedTwo = InteractionTracking.wrap(fnTwo, threadID);438      });439      const fnTwo = jest.fn();440      let wrappedOne, wrappedTwo;441      InteractionTracking.track(firstEvent.name, currentTime, () => {442        wrappedOne = InteractionTracking.wrap(fnOne, threadID);443      });444      expect(onInteractionTracked).toHaveBeenCalledTimes(1);445      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();446      wrappedOne();447      expect(onInteractionTracked).toHaveBeenCalledTimes(1);448      expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();449      wrappedTwo();450      expect(onInteractionTracked).toHaveBeenCalledTimes(1);451      expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);452      expect(453        onInteractionScheduledWorkCompleted,454      ).toHaveBeenLastNotifiedOfInteraction(firstEvent);455    });456    it('should unsubscribe', () => {457      InteractionTrackingSubscriptions.unsubscribe(firstSubscriber);458      InteractionTracking.track(firstEvent.name, currentTime, () => {});459      expect(onInteractionTracked).not.toHaveBeenCalled();460    });461  });462  describe('disabled', () => {463    beforeEach(() => loadModules({enableInteractionTracking: false}));464    // TODO465  });...scheduler-tracing.development.js
Source:scheduler-tracing.development.js  
...93  var threadID = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_THREAD_ID;94  var wrappedInteractions = exports.__interactionsRef.current;95  var subscriber = exports.__subscriberRef.current;96  if (subscriber !== null) {97    subscriber.onWorkScheduled(wrappedInteractions, threadID);98  } // Update the pending async work count for the current interactions.99  // Update after calling subscribers in case of error.100  wrappedInteractions.forEach(function (interaction) {101    interaction.__count++;102  });103  var hasRun = false;104  function wrapped() {105    var prevInteractions = exports.__interactionsRef.current;106    exports.__interactionsRef.current = wrappedInteractions;107    subscriber = exports.__subscriberRef.current;108    try {109      var returnValue;110      try {111        if (subscriber !== null) {112          subscriber.onWorkStarted(wrappedInteractions, threadID);113        }114      } finally {115        try {116          returnValue = callback.apply(undefined, arguments);117        } finally {118          exports.__interactionsRef.current = prevInteractions;119          if (subscriber !== null) {120            subscriber.onWorkStopped(wrappedInteractions, threadID);121          }122        }123      }124      return returnValue;125    } finally {126      if (!hasRun) {127        // We only expect a wrapped function to be executed once,128        // But in the event that it's executed more than onceâ129        // Only decrement the outstanding interaction counts once.130        hasRun = true; // Update pending async counts for all wrapped interactions.131        // If this was the last scheduled async work for any of them,132        // Mark them as completed.133        wrappedInteractions.forEach(function (interaction) {134          interaction.__count--;135          if (subscriber !== null && interaction.__count === 0) {136            subscriber.onInteractionScheduledWorkCompleted(interaction);137          }138        });139      }140    }141  }142  wrapped.cancel = function cancel() {143    subscriber = exports.__subscriberRef.current;144    try {145      if (subscriber !== null) {146        subscriber.onWorkCanceled(wrappedInteractions, threadID);147      }148    } finally {149      // Update pending async counts for all wrapped interactions.150      // If this was the last scheduled async work for any of them,151      // Mark them as completed.152      wrappedInteractions.forEach(function (interaction) {153        interaction.__count--;154        if (subscriber && interaction.__count === 0) {155          subscriber.onInteractionScheduledWorkCompleted(interaction);156        }157      });158    }159  };160  return wrapped;161}162var subscribers = null;163{164  subscribers = new Set();165}166function unstable_subscribe(subscriber) {167  {168    subscribers.add(subscriber);169    if (subscribers.size === 1) {170      exports.__subscriberRef.current = {171        onInteractionScheduledWorkCompleted: onInteractionScheduledWorkCompleted,172        onInteractionTraced: onInteractionTraced,173        onWorkCanceled: onWorkCanceled,174        onWorkScheduled: onWorkScheduled,175        onWorkStarted: onWorkStarted,176        onWorkStopped: onWorkStopped177      };178    }179  }180}181function unstable_unsubscribe(subscriber) {182  {183    subscribers.delete(subscriber);184    if (subscribers.size === 0) {185      exports.__subscriberRef.current = null;186    }187  }188}189function onInteractionTraced(interaction) {190  var didCatchError = false;191  var caughtError = null;192  subscribers.forEach(function (subscriber) {193    try {194      subscriber.onInteractionTraced(interaction);195    } catch (error) {196      if (!didCatchError) {197        didCatchError = true;198        caughtError = error;199      }200    }201  });202  if (didCatchError) {203    throw caughtError;204  }205}206function onInteractionScheduledWorkCompleted(interaction) {207  var didCatchError = false;208  var caughtError = null;209  subscribers.forEach(function (subscriber) {210    try {211      subscriber.onInteractionScheduledWorkCompleted(interaction);212    } catch (error) {213      if (!didCatchError) {214        didCatchError = true;215        caughtError = error;216      }217    }218  });219  if (didCatchError) {220    throw caughtError;221  }222}223function onWorkScheduled(interactions, threadID) {224  var didCatchError = false;225  var caughtError = null;226  subscribers.forEach(function (subscriber) {227    try {228      subscriber.onWorkScheduled(interactions, threadID);229    } catch (error) {230      if (!didCatchError) {231        didCatchError = true;232        caughtError = error;233      }234    }235  });236  if (didCatchError) {237    throw caughtError;238  }239}240function onWorkStarted(interactions, threadID) {241  var didCatchError = false;242  var caughtError = null;...SchedulerTracing-profiling.js
Source:SchedulerTracing-profiling.js  
...42    }43  });44  if (didCatchError) throw caughtError;45}46function onWorkScheduled(interactions, threadID) {47  var didCatchError = !1,48    caughtError = null;49  subscribers.forEach(function(subscriber) {50    try {51      subscriber.onWorkScheduled(interactions, threadID);52    } catch (error) {53      didCatchError || ((didCatchError = !0), (caughtError = error));54    }55  });56  if (didCatchError) throw caughtError;57}58function onWorkStarted(interactions, threadID) {59  var didCatchError = !1,60    caughtError = null;61  subscribers.forEach(function(subscriber) {62    try {63      subscriber.onWorkStarted(interactions, threadID);64    } catch (error) {65      didCatchError || ((didCatchError = !0), (caughtError = error));66    }67  });68  if (didCatchError) throw caughtError;69}70function onWorkStopped(interactions, threadID) {71  var didCatchError = !1,72    caughtError = null;73  subscribers.forEach(function(subscriber) {74    try {75      subscriber.onWorkStopped(interactions, threadID);76    } catch (error) {77      didCatchError || ((didCatchError = !0), (caughtError = error));78    }79  });80  if (didCatchError) throw caughtError;81}82function onWorkCanceled(interactions, threadID) {83  var didCatchError = !1,84    caughtError = null;85  subscribers.forEach(function(subscriber) {86    try {87      subscriber.onWorkCanceled(interactions, threadID);88    } catch (error) {89      didCatchError || ((didCatchError = !0), (caughtError = error));90    }91  });92  if (didCatchError) throw caughtError;93}94exports.unstable_clear = function(callback) {95  var prevInteractions = exports.__interactionsRef.current;96  exports.__interactionsRef.current = new Set();97  try {98    return callback();99  } finally {100    exports.__interactionsRef.current = prevInteractions;101  }102};103exports.unstable_getCurrent = function() {104  return exports.__interactionsRef.current;105};106exports.unstable_getThreadID = function() {107  return ++threadIDCounter;108};109exports.unstable_trace = function(name, timestamp, callback) {110  var threadID =111      3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : 0,112    interaction = {113      __count: 1,114      id: interactionIDCounter++,115      name: name,116      timestamp: timestamp117    },118    prevInteractions = exports.__interactionsRef.current,119    interactions = new Set(prevInteractions);120  interactions.add(interaction);121  exports.__interactionsRef.current = interactions;122  var subscriber = exports.__subscriberRef.current,123    returnValue = void 0;124  try {125    if (null !== subscriber) subscriber.onInteractionTraced(interaction);126  } finally {127    try {128      if (null !== subscriber) subscriber.onWorkStarted(interactions, threadID);129    } finally {130      try {131        returnValue = callback();132      } finally {133        exports.__interactionsRef.current = prevInteractions;134        try {135          if (null !== subscriber)136            subscriber.onWorkStopped(interactions, threadID);137        } finally {138          if (139            (interaction.__count--,140            null !== subscriber && 0 === interaction.__count)141          )142            subscriber.onInteractionScheduledWorkCompleted(interaction);143        }144      }145    }146  }147  return returnValue;148};149exports.unstable_wrap = function(callback) {150  function wrapped() {151    var prevInteractions = exports.__interactionsRef.current;152    exports.__interactionsRef.current = wrappedInteractions;153    subscriber = exports.__subscriberRef.current;154    try {155      var returnValue = void 0;156      try {157        if (null !== subscriber)158          subscriber.onWorkStarted(wrappedInteractions, threadID);159      } finally {160        try {161          returnValue = callback.apply(void 0, arguments);162        } finally {163          if (164            ((exports.__interactionsRef.current = prevInteractions),165            null !== subscriber)166          )167            subscriber.onWorkStopped(wrappedInteractions, threadID);168        }169      }170      return returnValue;171    } finally {172      hasRun ||173        ((hasRun = !0),174        wrappedInteractions.forEach(function(interaction) {175          interaction.__count--;176          if (null !== subscriber && 0 === interaction.__count)177            subscriber.onInteractionScheduledWorkCompleted(interaction);178        }));179    }180  }181  var threadID =182      1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : 0,183    wrappedInteractions = exports.__interactionsRef.current,184    subscriber = exports.__subscriberRef.current;185  if (null !== subscriber)186    subscriber.onWorkScheduled(wrappedInteractions, threadID);187  wrappedInteractions.forEach(function(interaction) {188    interaction.__count++;189  });190  var hasRun = !1;191  wrapped.cancel = function() {192    subscriber = exports.__subscriberRef.current;193    try {194      if (null !== subscriber)195        subscriber.onWorkCanceled(wrappedInteractions, threadID);196    } finally {197      wrappedInteractions.forEach(function(interaction) {198        interaction.__count--;199        if (subscriber && 0 === interaction.__count)200          subscriber.onInteractionScheduledWorkCompleted(interaction);...TracingSubscriptions.js
Source:TracingSubscriptions.js  
...58    if (didCatchError) {59      throw caughtError;60    }61  }62  function onWorkScheduled(interactions, threadID) {63    var didCatchError = false;64    var caughtError = null;65    subscribers.forEach(function (subscriber) {66      try {67        subscriber.onWorkScheduled(interactions, threadID);68      } catch (error) {69        if (!didCatchError) {70          didCatchError = true;71          caughtError = error;72        }73      }74    });75    if (didCatchError) {76      throw caughtError;77    }78  }79  function onWorkStarted(interactions, threadID) {80    var didCatchError = false;81    var caughtError = null;...Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const page = await browser.newPage();5  await page.screenshot({ path: 'example.png' });6  await browser.close();7})();8const { chromium } = require('playwright');9(async () => {10  const browser = await chromium.launch();11  const page = await browser.newPage();12  await page.screenshot({ path: 'example.png' });13  await browser.close();14})();15const { chromium } = require('playwright');16(async () => {17  const browser = await chromium.launch();18  const page = await browser.newPage();19  await page.screenshot({ path: 'example.png' });20  await browser.close();21})();22const { chromium } = require('playwright');23(async () => {24  const browser = await chromium.launch();25  const page = await browser.newPage();26  await page.screenshot({ path: 'example.png' });27  await browser.close();28})();29const { chromium } = require('playwright');30(async () => {31  const browser = await chromium.launch();32  const page = await browser.newPage();33  await page.screenshot({ path: 'example.png' });34  await browser.close();35})();36const { chromium } = require('playwright');37(async () => {38  const browser = await chromium.launch();39  const page = await browser.newPage();40  await page.screenshot({ path: 'example.png' });41  await browser.close();42})();43const { chromiumUsing 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.type("input[type='text']", "Hello World");6  await page.screenshot({path: `example.png`});7  await browser.close();8})();9const playwright = require('playwright');10(async () => {11  const browser = await playwright.chromium.launch({headless: false});12  const page = await browser.newPage();13  await page.type("input[type='text']", "Hello World");14  await page.screenshot({path: `example.png`});15  await browser.close();16})();17const playwright = require('playwright');18(async () => {19  const browser = await playwright.chromium.launch({headless: false});20  const page = await browser.newPage();21  await page.type("input[type='text']", "Hello World");22  await page.screenshot({path: `example.png`});23  await browser.close();24})();25const playwright = require('playwright');26(async () => {27  const browser = await playwright.chromium.launch({headless: false});28  const page = await browser.newPage();29  await page.type("input[type='text']", "Hello World");30  await page.screenshot({path: `example.png`});31  await browser.close();32})();33const playwright = require('playwright');34(async () => {35  const browser = await playwright.chromium.launch({headless: false});36  const page = await browser.newPage();37  await page.type("input[type='text']", "Hello World");38  await page.screenshot({path: `example.png`});39  await browser.close();40})();41const playwright = require('playwright');42(async () => {43  const browser = await playwright.chromium.launch({headless: false});Using AI Code Generation
1const { chromium } = require('playwright');2const { onWorkScheduled } = require('playwright/lib/server/supplements/recorder/recorderSupplement');3(async () => {4  const browser = await chromium.launch();5  const page = await browser.newPage();6  onWorkScheduled((event) => console.log(event));7  await page.close();8  await browser.close();9})();10{11  args: {12    options: {13    }14  }15}16const { onWorkScheduled } = require('playwright/lib/server/supplements/recorder/recorderSupplement');17const { Page } = require('playwright/lib/server/page');18const { BrowserContext } = require('playwright/lib/server/browserContext');19const originalPageGoto = Page.prototype.goto;20Page.prototype.goto = async function (...args) {21  const result = await originalPageGoto.apply(this, args);22  onWorkScheduled({ type: 'page', method: 'goto', args });23  return result;24};25const originalBrowserContextNewPage = BrowserContext.prototype.newPage;26BrowserContext.prototype.newPage = async function (...args) {27  const result = await originalBrowserContextNewPage.apply(this, args);28  onWorkScheduled({ type: 'browserContext', method: 'newUsing AI Code Generation
1const { Playwright } = require('playwright-core');2const { chromium } = require('playwright-core');3const fs = require('fs');4const browser = await chromium.launch({5});6const context = await browser.newContext();7const page = await context.newPage();8const playwright = new Playwright();9const browserServer = await playwright.chromium.launchServer({10});11const browserContext = await browserServer.newContext();12browserContext.onWorkScheduled((work) => {13    console.log(`Work scheduled: ${work.metadata.url}`);14});15browserContext.onWorkFinished((work) => {16    console.log(`Work finished: ${work.metadata.url}`);17});18const page1 = await browserContext.newPage();19const page2 = await browserContext.newPage();20const page3 = await browserContext.newPage();21const page4 = await browserContext.newPage();22const page5 = await browserContext.newPage();23const playwright = new Playwright();24const browserServer = await playwright.chromium.launchServer({25});26const browserContext = await browserServer.newContext();27browserContext.onWorkScheduled((work) => {28    console.log(`Work scheduled: ${work.metadata.url}`);29});30browserContext.onWorkFinished((work) => {31    console.log(`Work finished: ${work.metadata.url}`);32});33const page1 = await browserContext.newPage();34const page2 = await browserContext.newPage();35const page3 = await browserContext.newPage();Using AI Code Generation
1const { Playwright } = require('playwright-core');2const { PlaywrightDispatcher } = Playwright;3const { DispatcherConnection } = require('playwright-core/lib/server/dispatcher');4const connection = new DispatcherConnection();5const playwrightDispatcher = new PlaywrightDispatcher(connection, Playwright);6const playwright = playwrightDispatcher._object;7playwright.on('workScheduled', (event) => {8  console.log('workScheduled', event);9});10playwright.on('workStarted', (event) => {11  console.log('workStarted', event);12});13playwright.on('workDone', (event) => {14  console.log('workDone', event);15});16playwright.on('workCanceled', (event) => {17  console.log('workCanceled', event);18});19playwright.on('workFailed', (event) => {20  console.log('workFailed', event);21});22const browser = await playwright.chromium.launch();23const context = await browser.newContext();24const page = await context.newPage();25await browser.close();Using AI Code Generation
1const { Playwright } = require('playwright');2const playwright = new Playwright();3const { helper } = playwright._electron;4const { onWorkScheduled } = helper;5onWorkScheduled((event) => {6  console.log('onWorkScheduled', event);7});8const { Playwright } = require('playwright');9const playwright = new Playwright();10const { helper } = playwright._electron;11const { onWorkStopped } = helper;12onWorkStopped((event) => {13  console.log('onWorkStopped', event);14});15- [playwright](Using AI Code Generation
1const { onWorkScheduled } = require("@playwright/test/lib/worker/workerType");2onWorkScheduled((payload) => {3  console.log("onWorkScheduled", payload);4});5const { onWorkStarted } = require("@playwright/test/lib/worker/workerType");6onWorkStarted((payload) => {7  console.log("onWorkStarted", payload);8});9const { onWorkDone } = require("@playwright/test/lib/worker/workerType");10onWorkDone((payload) => {11  console.log("onWorkDone", payload);12});13const { onBeforeInput } = require("@playwright/test/lib/worker/workerType");14onBeforeInput((payload) => {15  console.log("onBeforeInput", payload);16});17const { onAfterInput } = require("@playwright/test/lib/worker/workerType");18onAfterInput((payload) => {19  console.log("onAfterInput", payload);20});21const { onBeforeCall } = require("@playwright/test/lib/worker/workerType");22onBeforeCall((payload) => {23  console.log("onBeforeCall", payload);24});25const { onAfterCall } = require("@playwright/test/lib/worker/workerType");26onAfterCall((payload) => {27  console.log("onAfterCall", payload);28});29const { onBeforeWaitForEvent } = require("@playwright/test/lib/worker/workerType");30onBeforeWaitForEvent((payload) => {31  console.log("onBeforeWaitForEvent", payload);32});33const { onAfterWaitForEvent } = require("@playwright/test/lib/worker/workerType");34onAfterWaitForEvent((payload) => {35  console.log("onAfterWaitForEvent", payload);36});37const { onBeforeWaitForTimeout } = require("@Using AI Code Generation
1const playwright = require("playwright");2const { onWorkScheduled } = playwright._internalApi;3const { onWorkStarted, onWorkDone } = onWorkScheduled(4  (event) => console.log(event),5  { waitForStableState: true }6);7const playwright = require("playwright");8const { onWorkStarted, onWorkDone } = playwright._internalApi;9onWorkStarted((event) => console.log(event));10onWorkDone((event) => console.log(event));11const playwright = require("playwright");12const { onWorkStarted, onWorkDone } = playwright._internalApi;13onWorkStarted((event) => console.log(event));14onWorkDone((event) => console.log(event));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!!
