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 });...
TracingSubscriptions.js
Source:TracingSubscriptions.js
...109 if (didCatchError) {110 throw caughtError;111 }112 }113 function onWorkCanceled(interactions, threadID) {114 var didCatchError = false;115 var caughtError = null;116 subscribers.forEach(function (subscriber) {117 try {118 subscriber.onWorkCanceled(interactions, threadID);119 } catch (error) {120 if (!didCatchError) {121 didCatchError = true;122 caughtError = error;123 }124 }125 });126 if (didCatchError) {127 throw caughtError;128 }...
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.screenshot({ path: 'example.png' });7 await browser.close();8})();9class Playwright {10 constructor() {11 this._isClosed = false;12 this._browserContexts = new Set();13 this._browserTypeToInstance = new Map();14 this._closePromise = null;15 this._closePromiseCallback = null;16 this._isClosing = false;17 this._closeCallback = null;18 this._connection = null;19 this._timeoutSettings = {};20 this._lastError = null;21 this._activeServiceWorkers = new Set();22 this._downloadCreatedListeners = [];23 this._downloadPathToGuid = new Map();24 this._downloads = new Map();25 this._downloadsDir = '';26 this._downloadsPath = '';27 this._downloadsPathCallback = null;28 this._downloadsPathPromise = null;29 this._downloadsPathPromiseCallback = null;30 this._isUnderTest = false;31 this._isPersistentContext = false;32 this._browserApp = null;33 this._browserServer = null;34 this._defaultContextOptions = {};35 this._deviceDescriptors = {};36 this._tracing = null;37 this._tracingStartedCallback = null;38 this._tracingStoppedCallback = null;39 this._tracingPath = null;40 this._videoRecorder = null;41 this._videoPath = null;42 this._videoSize = null;43 this._videoCallback = null;44 this._videoOptions = {};45 this._videoStartedCallback = null;46 this._videoStoppedCallback = null;47 this._workers = new Set();48 this._routes = [];49 this._routesWithInterception = [];50 this._requestInterceptor = null;51 this._requestInterceptionEnabled = false;52 this._requestInterceptionEnabledCallback = null;53 this._permissions = new Map();54 this._timeoutSettings.timeout = 30000;55 this._timeoutSettings.navigationTimeout = 30000;56 this._timeoutSettings.waitUntil = 'load';
Using AI Code Generation
1const { firefox } = require('playwright');2(async () => {3 const browser = await firefox.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.screenshot({ path: 'playwright.png' });7 await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11 const browser = await chromium.launch();12 const context = await browser.newContext();13 const page = await context.newPage();14 await page.screenshot({ path: 'playwright.png' });15 await browser.close();16})();17const { webkit } = require('playwright');18(async () => {19 const browser = await webkit.launch();20 const context = await browser.newContext();21 const page = await context.newPage();22 await page.screenshot({ path: 'playwright.png' });23 await browser.close();24})();25const { firefox } = require('playwright');26(async () => {27 const browser = await firefox.launch();28 const context = await browser.newContext();29 const page = await context.newPage();30 await page.screenshot({ path: 'playwright.png' });31 await browser.close();32})();33const { chromium } = require('playwright');34(async () => {35 const browser = await chromium.launch();36 const context = await browser.newContext();37 const page = await context.newPage();38 await page.screenshot({ path: 'playwright.png' });39 await browser.close();40})();41const { webkit } = require('playwright');42(async () => {43 const browser = await webkit.launch();44 const context = await browser.newContext();
Using AI Code Generation
1const { Playwright } = require('@playwright/test');2const { BrowserContext } = require('@playwright/test/lib/server/browserContext');3const { BrowserServer } = require('@playwright/test/lib/server/browserServer');4const { Browser } = require('@playwright/test/lib/server/browser');5const { Page } = require('@playwright/test/lib/server/page');6const originalBrowserContext = BrowserContext.prototype.onWorkCanceled;7BrowserContext.prototype.onWorkCanceled = function (work) {8 console.log('onWorkCanceled called');9 originalBrowserContext.call(this, work);10};11const originalBrowserServer = BrowserServer.prototype.onWorkCanceled;12BrowserServer.prototype.onWorkCanceled = function (work) {13 console.log('onWorkCanceled called');14 originalBrowserServer.call(this, work);15};16const originalBrowser = Browser.prototype.onWorkCanceled;17Browser.prototype.onWorkCanceled = function (work) {18 console.log('onWorkCanceled called');19 originalBrowser.call(this, work);20};21const originalPage = Page.prototype.onWorkCanceled;22Page.prototype.onWorkCanceled = function (work) {23 console.log('onWorkCanceled called');24 originalPage.call(this, work);25};26const playwright = Playwright.create();27const browser = await playwright.chromium.launch();28const context = await browser.newContext();29const page = await context.newPage();30await page.close();31await context.close();32await browser.close();
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!!