Best JavaScript code snippet using playwright-internal
ReactFiberWorkLoop.js
Source:ReactFiberWorkLoop.js
...471 // TODO: This does not account for low pri updates that were already472 // scheduled before the root started rendering. Need to track the next473 // pending expiration time (perhaps by backtracking the return path) and474 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.475 markRootSuspendedAtTime(root, renderExpirationTime);476 }477 }478 // Mark that the root has a pending update.479 markRootUpdatedAtTime(root, expirationTime);480 }481 return root;482}483function getNextRootExpirationTimeToWorkOn(root: FiberRoot): ExpirationTime {484 // Determines the next expiration time that the root should render, taking485 // into account levels that may be suspended, or levels that may have486 // received a ping.487 const lastExpiredTime = root.lastExpiredTime;488 if (lastExpiredTime !== NoWork) {489 return lastExpiredTime;490 }491 // "Pending" refers to any update that hasn't committed yet, including if it492 // suspended. The "suspended" range is therefore a subset.493 const firstPendingTime = root.firstPendingTime;494 if (!isRootSuspendedAtTime(root, firstPendingTime)) {495 // The highest priority pending time is not suspended. Let's work on that.496 return firstPendingTime;497 }498 // If the first pending time is suspended, check if there's a lower priority499 // pending level that we know about. Or check if we received a ping. Work500 // on whichever is higher priority.501 const lastPingedTime = root.lastPingedTime;502 const nextKnownPendingLevel = root.nextKnownPendingLevel;503 return lastPingedTime > nextKnownPendingLevel504 ? lastPingedTime505 : nextKnownPendingLevel;506}507// Use this function to schedule a task for a root. There's only one task per508// root; if a task was already scheduled, we'll check to make sure the509// expiration time of the existing task is the same as the expiration time of510// the next level that the root has work on. This function is called on every511// update, and right before exiting a task.512function ensureRootIsScheduled(root: FiberRoot) {513 const lastExpiredTime = root.lastExpiredTime;514 if (lastExpiredTime !== NoWork) {515 // Special case: Expired work should flush synchronously.516 root.callbackExpirationTime = Sync;517 root.callbackPriority = ImmediatePriority;518 root.callbackNode = scheduleSyncCallback(519 performSyncWorkOnRoot.bind(null, root),520 );521 return;522 }523 const expirationTime = getNextRootExpirationTimeToWorkOn(root);524 const existingCallbackNode = root.callbackNode;525 if (expirationTime === NoWork) {526 // There's nothing to work on.527 if (existingCallbackNode !== null) {528 root.callbackNode = null;529 root.callbackExpirationTime = NoWork;530 root.callbackPriority = NoPriority;531 }532 return;533 }534 // TODO: If this is an update, we already read the current time. Pass the535 // time as an argument.536 const currentTime = requestCurrentTime();537 const priorityLevel = inferPriorityFromExpirationTime(538 currentTime,539 expirationTime,540 );541 // If there's an existing render task, confirm it has the correct priority and542 // expiration time. Otherwise, we'll cancel it and schedule a new one.543 if (existingCallbackNode !== null) {544 const existingCallbackPriority = root.callbackPriority;545 const existingCallbackExpirationTime = root.callbackExpirationTime;546 if (547 // Callback must have the exact same expiration time.548 existingCallbackExpirationTime === expirationTime &&549 // Callback must have greater or equal priority.550 existingCallbackPriority >= priorityLevel551 ) {552 // Existing callback is sufficient.553 return;554 }555 // Need to schedule a new task.556 // TODO: Instead of scheduling a new task, we should be able to change the557 // priority of the existing one.558 cancelCallback(existingCallbackNode);559 }560 root.callbackExpirationTime = expirationTime;561 root.callbackPriority = priorityLevel;562 let callbackNode;563 if (expirationTime === Sync) {564 // Sync React callbacks are scheduled on a special internal queue565 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));566 } else if (disableSchedulerTimeoutBasedOnReactExpirationTime) {567 callbackNode = scheduleCallback(568 priorityLevel,569 performConcurrentWorkOnRoot.bind(null, root),570 );571 } else {572 callbackNode = scheduleCallback(573 priorityLevel,574 performConcurrentWorkOnRoot.bind(null, root),575 // Compute a task timeout based on the expiration time. This also affects576 // ordering because tasks are processed in timeout order.577 {timeout: expirationTimeToMs(expirationTime) - now()},578 );579 }580 root.callbackNode = callbackNode;581}582// This is the entry point for every concurrent task, i.e. anything that583// goes through Scheduler.584function performConcurrentWorkOnRoot(root, didTimeout) {585 // Since we know we're in a React event, we can clear the current586 // event time. The next update will compute a new event time.587 currentEventTime = NoWork;588 if (didTimeout) {589 // The render task took too long to complete. Mark the current time as590 // expired to synchronously render all expired work in a single batch.591 const currentTime = requestCurrentTime();592 markRootExpiredAtTime(root, currentTime);593 // This will schedule a synchronous callback.594 ensureRootIsScheduled(root);595 return null;596 }597 // Determine the next expiration time to work on, using the fields stored598 // on the root.599 const expirationTime = getNextRootExpirationTimeToWorkOn(root);600 if (expirationTime !== NoWork) {601 const originalCallbackNode = root.callbackNode;602 invariant(603 (executionContext & (RenderContext | CommitContext)) === NoContext,604 'Should not already be working.',605 );606 flushPassiveEffects();607 // If the root or expiration time have changed, throw out the existing stack608 // and prepare a fresh one. Otherwise we'll continue where we left off.609 if (610 root !== workInProgressRoot ||611 expirationTime !== renderExpirationTime612 ) {613 prepareFreshStack(root, expirationTime);614 startWorkOnPendingInteractions(root, expirationTime);615 }616 // If we have a work-in-progress fiber, it means there's still work to do617 // in this root.618 if (workInProgress !== null) {619 const prevExecutionContext = executionContext;620 executionContext |= RenderContext;621 const prevDispatcher = pushDispatcher(root);622 const prevInteractions = pushInteractions(root);623 startWorkLoopTimer(workInProgress);624 do {625 try {626 workLoopConcurrent();627 break;628 } catch (thrownValue) {629 handleError(root, thrownValue);630 }631 } while (true);632 resetContextDependencies();633 executionContext = prevExecutionContext;634 popDispatcher(prevDispatcher);635 if (enableSchedulerTracing) {636 popInteractions(((prevInteractions: any): Set<Interaction>));637 }638 if (workInProgressRootExitStatus === RootFatalErrored) {639 const fatalError = workInProgressRootFatalError;640 stopInterruptedWorkLoopTimer();641 prepareFreshStack(root, expirationTime);642 markRootSuspendedAtTime(root, expirationTime);643 ensureRootIsScheduled(root);644 throw fatalError;645 }646 if (workInProgress !== null) {647 // There's still work left over. Exit without committing.648 stopInterruptedWorkLoopTimer();649 } else {650 // We now have a consistent tree. The next step is either to commit it,651 // or, if something suspended, wait to commit it after a timeout.652 stopFinishedWorkLoopTimer();653 const finishedWork: Fiber = ((root.finishedWork =654 root.current.alternate): any);655 root.finishedExpirationTime = expirationTime;656 resolveLocksOnRoot(root, expirationTime);657 finishConcurrentRender(658 root,659 finishedWork,660 workInProgressRootExitStatus,661 expirationTime,662 );663 }664 ensureRootIsScheduled(root);665 if (root.callbackNode === originalCallbackNode) {666 // The task node scheduled for this root is the same one that's667 // currently executed. Need to return a continuation.668 return performConcurrentWorkOnRoot.bind(null, root);669 }670 }671 }672 return null;673}674function finishConcurrentRender(675 root,676 finishedWork,677 exitStatus,678 expirationTime,679) {680 // Set this to null to indicate there's no in-progress render.681 workInProgressRoot = null;682 switch (exitStatus) {683 case RootIncomplete:684 case RootFatalErrored: {685 invariant(false, 'Root did not complete. This is a bug in React.');686 }687 // Flow knows about invariant, so it complains if I add a break688 // statement, but eslint doesn't know about invariant, so it complains689 // if I do. eslint-disable-next-line no-fallthrough690 case RootErrored: {691 if (expirationTime !== Idle) {692 // If this was an async render, the error may have happened due to693 // a mutation in a concurrent event. Try rendering one more time,694 // synchronously, to see if the error goes away. If there are695 // lower priority updates, let's include those, too, in case they696 // fix the inconsistency. Render at Idle to include all updates.697 markRootExpiredAtTime(root, Idle);698 break;699 }700 // Commit the root in its errored state.701 commitRoot(root);702 break;703 }704 case RootSuspended: {705 markRootSuspendedAtTime(root, expirationTime);706 const lastSuspendedTime = root.lastSuspendedTime;707 if (expirationTime === lastSuspendedTime) {708 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);709 }710 flushSuspensePriorityWarningInDEV();711 // We have an acceptable loading state. We need to figure out if we712 // should immediately commit it or wait a bit.713 // If we have processed new updates during this render, we may now714 // have a new loading state ready. We want to ensure that we commit715 // that as soon as possible.716 const hasNotProcessedNewUpdates =717 workInProgressRootLatestProcessedExpirationTime === Sync;718 if (719 hasNotProcessedNewUpdates &&720 // do not delay if we're inside an act() scope721 !(722 __DEV__ &&723 flushSuspenseFallbacksInTests &&724 IsThisRendererActing.current725 )726 ) {727 // If we have not processed any new updates during this pass, then728 // this is either a retry of an existing fallback state or a729 // hidden tree. Hidden trees shouldn't be batched with other work730 // and after that's fixed it can only be a retry. We're going to731 // throttle committing retries so that we don't show too many732 // loading states too quickly.733 let msUntilTimeout =734 globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();735 // Don't bother with a very short suspense time.736 if (msUntilTimeout > 10) {737 if (workInProgressRootHasPendingPing) {738 const lastPingedTime = root.lastPingedTime;739 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {740 // This render was pinged but we didn't get to restart741 // earlier so try restarting now instead.742 root.lastPingedTime = expirationTime;743 prepareFreshStack(root, expirationTime);744 break;745 }746 }747 const nextTime = getNextRootExpirationTimeToWorkOn(root);748 if (nextTime !== NoWork && nextTime !== expirationTime) {749 // There's additional work on this root.750 break;751 }752 if (753 lastSuspendedTime !== NoWork &&754 lastSuspendedTime !== expirationTime755 ) {756 // We should prefer to render the fallback of at the last757 // suspended level. Ping the last suspended level to try758 // rendering it again.759 root.lastPingedTime = lastSuspendedTime;760 break;761 }762 // The render is suspended, it hasn't timed out, and there's no763 // lower priority work to do. Instead of committing the fallback764 // immediately, wait for more data to arrive.765 root.timeoutHandle = scheduleTimeout(766 commitRoot.bind(null, root),767 msUntilTimeout,768 );769 break;770 }771 }772 // The work expired. Commit immediately.773 commitRoot(root);774 break;775 }776 case RootSuspendedWithDelay: {777 markRootSuspendedAtTime(root, expirationTime);778 const lastSuspendedTime = root.lastSuspendedTime;779 if (expirationTime === lastSuspendedTime) {780 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);781 }782 flushSuspensePriorityWarningInDEV();783 if (784 // do not delay if we're inside an act() scope785 !(786 __DEV__ &&787 flushSuspenseFallbacksInTests &&788 IsThisRendererActing.current789 )790 ) {791 // We're suspended in a state that should be avoided. We'll try to792 // avoid committing it for as long as the timeouts let us.793 if (workInProgressRootHasPendingPing) {794 const lastPingedTime = root.lastPingedTime;795 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {796 // This render was pinged but we didn't get to restart earlier797 // so try restarting now instead.798 root.lastPingedTime = expirationTime;799 prepareFreshStack(root, expirationTime);800 break;801 }802 }803 const nextTime = getNextRootExpirationTimeToWorkOn(root);804 if (nextTime !== NoWork && nextTime !== expirationTime) {805 // There's additional work on this root.806 break;807 }808 if (809 lastSuspendedTime !== NoWork &&810 lastSuspendedTime !== expirationTime811 ) {812 // We should prefer to render the fallback of at the last813 // suspended level. Ping the last suspended level to try814 // rendering it again.815 root.lastPingedTime = lastSuspendedTime;816 break;817 }818 let msUntilTimeout;819 if (workInProgressRootLatestSuspenseTimeout !== Sync) {820 // We have processed a suspense config whose expiration time we821 // can use as the timeout.822 msUntilTimeout =823 expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();824 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {825 // This should never normally happen because only new updates826 // cause delayed states, so we should have processed something.827 // However, this could also happen in an offscreen tree.828 msUntilTimeout = 0;829 } else {830 // If we don't have a suspense config, we're going to use a831 // heuristic to determine how long we can suspend.832 const eventTimeMs: number = inferTimeFromExpirationTime(833 workInProgressRootLatestProcessedExpirationTime,834 );835 const currentTimeMs = now();836 const timeUntilExpirationMs =837 expirationTimeToMs(expirationTime) - currentTimeMs;838 let timeElapsed = currentTimeMs - eventTimeMs;839 if (timeElapsed < 0) {840 // We get this wrong some time since we estimate the time.841 timeElapsed = 0;842 }843 msUntilTimeout = jnd(timeElapsed) - timeElapsed;844 // Clamp the timeout to the expiration time. TODO: Once the845 // event time is exact instead of inferred from expiration time846 // we don't need this.847 if (timeUntilExpirationMs < msUntilTimeout) {848 msUntilTimeout = timeUntilExpirationMs;849 }850 }851 // Don't bother with a very short suspense time.852 if (msUntilTimeout > 10) {853 // The render is suspended, it hasn't timed out, and there's no854 // lower priority work to do. Instead of committing the fallback855 // immediately, wait for more data to arrive.856 root.timeoutHandle = scheduleTimeout(857 commitRoot.bind(null, root),858 msUntilTimeout,859 );860 break;861 }862 }863 // The work expired. Commit immediately.864 commitRoot(root);865 break;866 }867 case RootCompleted: {868 // The work completed. Ready to commit.869 if (870 // do not delay if we're inside an act() scope871 !(872 __DEV__ &&873 flushSuspenseFallbacksInTests &&874 IsThisRendererActing.current875 ) &&876 workInProgressRootLatestProcessedExpirationTime !== Sync &&877 workInProgressRootCanSuspendUsingConfig !== null878 ) {879 // If we have exceeded the minimum loading delay, which probably880 // means we have shown a spinner already, we might have to suspend881 // a bit longer to ensure that the spinner is shown for882 // enough time.883 const msUntilTimeout = computeMsUntilSuspenseLoadingDelay(884 workInProgressRootLatestProcessedExpirationTime,885 expirationTime,886 workInProgressRootCanSuspendUsingConfig,887 );888 if (msUntilTimeout > 10) {889 markRootSuspendedAtTime(root, expirationTime);890 root.timeoutHandle = scheduleTimeout(891 commitRoot.bind(null, root),892 msUntilTimeout,893 );894 break;895 }896 }897 commitRoot(root);898 break;899 }900 case RootLocked: {901 // This root has a lock that prevents it from committing. Exit. If902 // we begin work on the root again, without any intervening updates,903 // it will finish without doing additional work.904 markRootSuspendedAtTime(root, expirationTime);905 break;906 }907 default: {908 invariant(false, 'Unknown root exit status.');909 }910 }911}912// This is the entry point for synchronous tasks that don't go913// through Scheduler914function performSyncWorkOnRoot(root) {915 // Check if there's expired work on this root. Otherwise, render at Sync.916 const lastExpiredTime = root.lastExpiredTime;917 const expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;918 if (root.finishedExpirationTime === expirationTime) {919 // There's already a pending commit at this expiration time.920 // TODO: This is poorly factored. This case only exists for the921 // batch.commit() API.922 commitRoot(root);923 } else {924 invariant(925 (executionContext & (RenderContext | CommitContext)) === NoContext,926 'Should not already be working.',927 );928 flushPassiveEffects();929 // If the root or expiration time have changed, throw out the existing stack930 // and prepare a fresh one. Otherwise we'll continue where we left off.931 if (932 root !== workInProgressRoot ||933 expirationTime !== renderExpirationTime934 ) {935 prepareFreshStack(root, expirationTime);936 startWorkOnPendingInteractions(root, expirationTime);937 }938 // If we have a work-in-progress fiber, it means there's still work to do939 // in this root.940 if (workInProgress !== null) {941 const prevExecutionContext = executionContext;942 executionContext |= RenderContext;943 const prevDispatcher = pushDispatcher(root);944 const prevInteractions = pushInteractions(root);945 startWorkLoopTimer(workInProgress);946 do {947 try {948 workLoopSync();949 break;950 } catch (thrownValue) {951 handleError(root, thrownValue);952 }953 } while (true);954 resetContextDependencies();955 executionContext = prevExecutionContext;956 popDispatcher(prevDispatcher);957 if (enableSchedulerTracing) {958 popInteractions(((prevInteractions: any): Set<Interaction>));959 }960 if (workInProgressRootExitStatus === RootFatalErrored) {961 const fatalError = workInProgressRootFatalError;962 stopInterruptedWorkLoopTimer();963 prepareFreshStack(root, expirationTime);964 markRootSuspendedAtTime(root, expirationTime);965 ensureRootIsScheduled(root);966 throw fatalError;967 }968 if (workInProgress !== null) {969 // This is a sync render, so we should have finished the whole tree.970 invariant(971 false,972 'Cannot commit an incomplete root. This error is likely caused by a ' +973 'bug in React. Please file an issue.',974 );975 } else {976 // We now have a consistent tree. Because this is a sync render, we977 // will commit it even if something suspended. The only exception is978 // if the root is locked (using the unstable_createBatch API).979 stopFinishedWorkLoopTimer();980 root.finishedWork = (root.current.alternate: any);981 root.finishedExpirationTime = expirationTime;982 resolveLocksOnRoot(root, expirationTime);983 finishSyncRender(root, workInProgressRootExitStatus, expirationTime);984 }985 // Before exiting, make sure there's a callback scheduled for the next986 // pending level.987 ensureRootIsScheduled(root);988 }989 }990 return null;991}992function finishSyncRender(root, exitStatus, expirationTime) {993 if (exitStatus === RootLocked) {994 // This root has a lock that prevents it from committing. Exit. If we995 // begin work on the root again, without any intervening updates, it996 // will finish without doing additional work.997 markRootSuspendedAtTime(root, expirationTime);998 } else {999 // Set this to null to indicate there's no in-progress render.1000 workInProgressRoot = null;1001 if (__DEV__) {1002 if (1003 exitStatus === RootSuspended ||1004 exitStatus === RootSuspendedWithDelay1005 ) {1006 flushSuspensePriorityWarningInDEV();1007 }1008 }1009 commitRoot(root);1010 }1011}1012export function flushRoot(root: FiberRoot, expirationTime: ExpirationTime) {1013 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {1014 invariant(1015 false,1016 'work.commit(): Cannot commit while already rendering. This likely ' +1017 'means you attempted to commit from inside a lifecycle method.',1018 );1019 }1020 markRootExpiredAtTime(root, expirationTime);1021 ensureRootIsScheduled(root);1022 flushSyncCallbackQueue();1023}1024export function flushDiscreteUpdates() {1025 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.1026 // However, `act` uses `batchedUpdates`, so there's no way to distinguish1027 // those two cases. Need to fix this before exposing flushDiscreteUpdates1028 // as a public API.1029 if (1030 (executionContext & (BatchedContext | RenderContext | CommitContext)) !==1031 NoContext1032 ) {1033 if (__DEV__ && (executionContext & RenderContext) !== NoContext) {1034 warning(1035 false,1036 'unstable_flushDiscreteUpdates: Cannot flush updates when React is ' +1037 'already rendering.',1038 );1039 }1040 // We're already rendering, so we can't synchronously flush pending work.1041 // This is probably a nested event dispatch triggered by a lifecycle/effect,1042 // like `el.focus()`. Exit.1043 return;1044 }1045 flushPendingDiscreteUpdates();1046 // If the discrete updates scheduled passive effects, flush them now so that1047 // they fire before the next serial event.1048 flushPassiveEffects();1049}1050function resolveLocksOnRoot(root: FiberRoot, expirationTime: ExpirationTime) {1051 const firstBatch = root.firstBatch;1052 if (1053 firstBatch !== null &&1054 firstBatch._defer &&1055 firstBatch._expirationTime >= expirationTime1056 ) {1057 scheduleCallback(NormalPriority, () => {1058 firstBatch._onComplete();1059 return null;1060 });1061 workInProgressRootExitStatus = RootLocked;1062 }1063}1064export function deferredUpdates<A>(fn: () => A): A {1065 // TODO: Remove in favor of Scheduler.next1066 return runWithPriority(NormalPriority, fn);1067}1068export function syncUpdates<A, B, C, R>(1069 fn: (A, B, C) => R,1070 a: A,1071 b: B,1072 c: C,1073): R {1074 return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c));1075}1076function flushPendingDiscreteUpdates() {1077 if (rootsWithPendingDiscreteUpdates !== null) {1078 // For each root with pending discrete updates, schedule a callback to1079 // immediately flush them.1080 const roots = rootsWithPendingDiscreteUpdates;1081 rootsWithPendingDiscreteUpdates = null;1082 roots.forEach((expirationTime, root) => {1083 markRootExpiredAtTime(root, expirationTime);1084 ensureRootIsScheduled(root);1085 });1086 // Now flush the immediate queue.1087 flushSyncCallbackQueue();1088 }1089}1090export function batchedUpdates<A, R>(fn: A => R, a: A): R {1091 const prevExecutionContext = executionContext;1092 executionContext |= BatchedContext;1093 try {1094 return fn(a);1095 } finally {1096 executionContext = prevExecutionContext;1097 if (executionContext === NoContext) {1098 // Flush the immediate callbacks that were scheduled during this batch1099 flushSyncCallbackQueue();1100 }1101 }1102}1103export function batchedEventUpdates<A, R>(fn: A => R, a: A): R {1104 const prevExecutionContext = executionContext;1105 executionContext |= EventContext;1106 try {1107 return fn(a);1108 } finally {1109 executionContext = prevExecutionContext;1110 if (executionContext === NoContext) {1111 // Flush the immediate callbacks that were scheduled during this batch1112 flushSyncCallbackQueue();1113 }1114 }1115}1116export function discreteUpdates<A, B, C, R>(1117 fn: (A, B, C) => R,1118 a: A,1119 b: B,1120 c: C,1121): R {1122 const prevExecutionContext = executionContext;1123 executionContext |= DiscreteEventContext;1124 try {1125 // Should this1126 return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c));1127 } finally {1128 executionContext = prevExecutionContext;1129 if (executionContext === NoContext) {1130 // Flush the immediate callbacks that were scheduled during this batch1131 flushSyncCallbackQueue();1132 }1133 }1134}1135export function unbatchedUpdates<A, R>(fn: (a: A) => R, a: A): R {1136 const prevExecutionContext = executionContext;1137 executionContext &= ~BatchedContext;1138 executionContext |= LegacyUnbatchedContext;1139 try {1140 return fn(a);1141 } finally {1142 executionContext = prevExecutionContext;1143 if (executionContext === NoContext) {1144 // Flush the immediate callbacks that were scheduled during this batch1145 flushSyncCallbackQueue();1146 }1147 }1148}1149export function flushSync<A, R>(fn: A => R, a: A): R {1150 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {1151 invariant(1152 false,1153 'flushSync was called from inside a lifecycle method. It cannot be ' +1154 'called when React is already rendering.',1155 );1156 }1157 const prevExecutionContext = executionContext;1158 executionContext |= BatchedContext;1159 try {1160 return runWithPriority(ImmediatePriority, fn.bind(null, a));1161 } finally {1162 executionContext = prevExecutionContext;1163 // Flush the immediate callbacks that were scheduled during this batch.1164 // Note that this will happen even if batchedUpdates is higher up1165 // the stack.1166 flushSyncCallbackQueue();1167 }1168}1169export function flushControlled(fn: () => mixed): void {1170 const prevExecutionContext = executionContext;1171 executionContext |= BatchedContext;1172 try {1173 runWithPriority(ImmediatePriority, fn);1174 } finally {1175 executionContext = prevExecutionContext;1176 if (executionContext === NoContext) {1177 // Flush the immediate callbacks that were scheduled during this batch1178 flushSyncCallbackQueue();1179 }1180 }1181}1182function prepareFreshStack(root, expirationTime) {1183 root.finishedWork = null;1184 root.finishedExpirationTime = NoWork;1185 const timeoutHandle = root.timeoutHandle;1186 if (timeoutHandle !== noTimeout) {1187 // The root previous suspended and scheduled a timeout to commit a fallback1188 // state. Now that we have additional work, cancel the timeout.1189 root.timeoutHandle = noTimeout;1190 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above1191 cancelTimeout(timeoutHandle);1192 }1193 if (workInProgress !== null) {1194 let interruptedWork = workInProgress.return;1195 while (interruptedWork !== null) {1196 unwindInterruptedWork(interruptedWork);1197 interruptedWork = interruptedWork.return;1198 }1199 }1200 workInProgressRoot = root;1201 workInProgress = createWorkInProgress(root.current, null, expirationTime);1202 renderExpirationTime = expirationTime;1203 workInProgressRootExitStatus = RootIncomplete;1204 workInProgressRootFatalError = null;1205 workInProgressRootLatestProcessedExpirationTime = Sync;1206 workInProgressRootLatestSuspenseTimeout = Sync;1207 workInProgressRootCanSuspendUsingConfig = null;1208 workInProgressRootNextUnprocessedUpdateTime = NoWork;1209 workInProgressRootHasPendingPing = false;1210 if (enableSchedulerTracing) {1211 spawnedWorkDuringRender = null;1212 }1213 if (__DEV__) {1214 ReactStrictModeWarnings.discardPendingWarnings();1215 componentsThatTriggeredHighPriSuspend = null;1216 }1217}1218function handleError(root, thrownValue) {1219 do {1220 try {1221 // Reset module-level state that was set during the render phase.1222 resetContextDependencies();1223 resetHooks();1224 if (workInProgress === null || workInProgress.return === null) {1225 // Expected to be working on a non-root fiber. This is a fatal error1226 // because there's no ancestor that can handle it; the root is1227 // supposed to capture all errors that weren't caught by an error1228 // boundary.1229 workInProgressRootExitStatus = RootFatalErrored;1230 workInProgressRootFatalError = thrownValue;1231 return null;1232 }1233 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {1234 // Record the time spent rendering before an error was thrown. This1235 // avoids inaccurate Profiler durations in the case of a1236 // suspended render.1237 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);1238 }1239 throwException(1240 root,1241 workInProgress.return,1242 workInProgress,1243 thrownValue,1244 renderExpirationTime,1245 );1246 workInProgress = completeUnitOfWork(workInProgress);1247 } catch (yetAnotherThrownValue) {1248 // Something in the return path also threw.1249 thrownValue = yetAnotherThrownValue;1250 continue;1251 }1252 // Return to the normal work loop.1253 return;1254 } while (true);1255}1256function pushDispatcher(root) {1257 const prevDispatcher = ReactCurrentDispatcher.current;1258 ReactCurrentDispatcher.current = ContextOnlyDispatcher;1259 if (prevDispatcher === null) {1260 // The React isomorphic package does not include a default dispatcher.1261 // Instead the first renderer will lazily attach one, in order to give1262 // nicer error messages.1263 return ContextOnlyDispatcher;1264 } else {1265 return prevDispatcher;1266 }1267}1268function popDispatcher(prevDispatcher) {1269 ReactCurrentDispatcher.current = prevDispatcher;1270}1271function pushInteractions(root) {1272 if (enableSchedulerTracing) {1273 const prevInteractions: Set<Interaction> | null = __interactionsRef.current;1274 __interactionsRef.current = root.memoizedInteractions;1275 return prevInteractions;1276 }1277 return null;1278}1279function popInteractions(prevInteractions) {1280 if (enableSchedulerTracing) {1281 __interactionsRef.current = prevInteractions;1282 }1283}1284export function markCommitTimeOfFallback() {1285 globalMostRecentFallbackTime = now();1286}1287export function markRenderEventTimeAndConfig(1288 expirationTime: ExpirationTime,1289 suspenseConfig: null | SuspenseConfig,1290): void {1291 if (1292 expirationTime < workInProgressRootLatestProcessedExpirationTime &&1293 expirationTime > Idle1294 ) {1295 workInProgressRootLatestProcessedExpirationTime = expirationTime;1296 }1297 if (suspenseConfig !== null) {1298 if (1299 expirationTime < workInProgressRootLatestSuspenseTimeout &&1300 expirationTime > Idle1301 ) {1302 workInProgressRootLatestSuspenseTimeout = expirationTime;1303 // Most of the time we only have one config and getting wrong is not bad.1304 workInProgressRootCanSuspendUsingConfig = suspenseConfig;1305 }1306 }1307}1308export function markUnprocessedUpdateTime(1309 expirationTime: ExpirationTime,1310): void {1311 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {1312 workInProgressRootNextUnprocessedUpdateTime = expirationTime;1313 }1314}1315export function renderDidSuspend(): void {1316 if (workInProgressRootExitStatus === RootIncomplete) {1317 workInProgressRootExitStatus = RootSuspended;1318 }1319}1320export function renderDidSuspendDelayIfPossible(): void {1321 if (1322 workInProgressRootExitStatus === RootIncomplete ||1323 workInProgressRootExitStatus === RootSuspended1324 ) {1325 workInProgressRootExitStatus = RootSuspendedWithDelay;1326 }1327 // Check if there's a lower priority update somewhere else in the tree.1328 if (1329 workInProgressRootNextUnprocessedUpdateTime !== NoWork &&1330 workInProgressRoot !== null1331 ) {1332 // Mark the current render as suspended, and then mark that there's a1333 // pending update.1334 // TODO: This should immediately interrupt the current render, instead1335 // of waiting until the next time we yield.1336 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime);1337 markRootUpdatedAtTime(1338 workInProgressRoot,1339 workInProgressRootNextUnprocessedUpdateTime,1340 );1341 }1342}1343export function renderDidError() {1344 if (workInProgressRootExitStatus !== RootCompleted) {1345 workInProgressRootExitStatus = RootErrored;1346 }1347}1348// Called during render to determine if anything has suspended.1349// Returns false if we're not sure.1350export function renderHasNotSuspendedYet(): boolean {...
ReactFiberRoot.old.js
Source:ReactFiberRoot.old.js
...80 firstSuspendedTime >= expirationTime &&81 lastSuspendedTime <= expirationTime82 );83}84export function markRootSuspendedAtTime(85 root: FiberRoot,86 expirationTime: ExpirationTime,87): void {88 const firstSuspendedTime = root.firstSuspendedTime;89 const lastSuspendedTime = root.lastSuspendedTime;90 if (firstSuspendedTime < expirationTime) {91 root.firstSuspendedTime = expirationTime;92 }93 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {94 root.lastSuspendedTime = expirationTime;95 }96 if (expirationTime <= root.lastPingedTime) {97 root.lastPingedTime = NoWork;98 }...
ReactFiberRoot.new.js
Source:ReactFiberRoot.new.js
...80 firstSuspendedTime >= expirationTime &&81 lastSuspendedTime <= expirationTime82 );83}84export function markRootSuspendedAtTime(85 root: FiberRoot,86 expirationTime: ExpirationTime,87): void {88 const firstSuspendedTime = root.firstSuspendedTime;89 const lastSuspendedTime = root.lastSuspendedTime;90 if (firstSuspendedTime < expirationTime) {91 root.firstSuspendedTime = expirationTime;92 }93 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {94 root.lastSuspendedTime = expirationTime;95 }96 if (expirationTime <= root.lastPingedTime) {97 root.lastPingedTime = NoWork;98 }...
ReactFiberRoot.js
Source:ReactFiberRoot.js
...37 var firstSuspendedTime = root.firstSuspendedTime;38 var lastSuspendedTime = root.lastSuspendedTime;39 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;40 }41 function markRootSuspendedAtTime(root, expirationTime) {42 var firstSuspendedTime = root.firstSuspendedTime;43 var lastSuspendedTime = root.lastSuspendedTime;44 if (firstSuspendedTime < expirationTime) {45 root.firstSuspendedTime = expirationTime;46 }47 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {48 root.lastSuspendedTime = expirationTime;49 }50 if (expirationTime <= root.lastPingedTime) {51 root.lastPingedTime = NoWork;52 }53 if (expirationTime <= root.lastExpiredTime) {54 root.lastExpiredTime = NoWork;55 }...
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})();9const playwright = require('playwright');10module.exports = {11 chromium: {12 launch: async (options) => {13 const browser = await playwright.chromium.launch(options);14 const context = await browser.newContext();15 const page = await context.newPage();16 await page.screenshot({ path: 'example.png' });17 await browser.close();18 },19 },20};21const myPlaywright = require('./myPlaywright');22(async () => {23 const browser = await myPlaywright.chromium.launch();24 await browser.close();25})();26const { chromium } = require('playwright');27(async () => {28 const browser = await chromium.launch();29 const context = await browser.newContext();30 const page = await context.newPage();31 await page.screenshot({ path: 'example.png' });32 await browser.close();33})();34const { chromium } = require('playwright');35const { markRootSuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');36(async () => {37 const browser = await chromium.launch();38 const context = await browser.newContext();39 const page = await context.newPage();40 await page.screenshot({ path: 'example.png' });41 await browser.close();42})();43const { chromium } = require('playwright');44const { markRootSuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');45(async () => {46 const browser = await chromium.launch();47 const context = await browser.newContext();48 const page = await context.newPage();49 await page.screenshot({ path: 'example.png' });50 await browser.close();51})();
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})();9 at Object.dispatch (/node_modules/playwright/lib/client/protocol.js:110:13)10 at Connection._onMessage (/node_modules/playwright/lib/client/connection.js:131:24)11 at WebSocketTransport._ws.addEventListener.event (/node_modules/playwright/lib/client/connection.js:53:46)12 at WebSocket.onMessage (/node_modules/ws/lib/event-target.js:132:16)13 at WebSocket.emit (events.js:315:20)14 at Receiver.receiverOnMessage (/node_modules/ws/lib/websocket.js:789:20)15 at Receiver.emit (events.js:315:20)16 at Receiver.dataMessage (/node_modules/ws/lib/receiver.js:437:14)17 at Receiver.getData (/node_modules/ws/lib/receiver.js:367:17)18 at Receiver.startLoop (/node_modules/ws/lib/receiver.js:153:22)
Using AI Code Generation
1const { markRootSuspendedAtTime } = require('playwright-core/lib/server/supplements/recorder/recorderSupplement');2markRootSuspendedAtTime(1000);3markRootSuspendedAtTime(2000);4const { markRootUnsuspendedAtTime } = require('playwright-core/lib/server/supplements/recorder/recorderSupplement');5markRootUnsuspendedAtTime(3000);6markRootUnsuspendedAtTime(4000);7const { markRootSuspendedAtTime } = require('playwright-core/lib/server/supplements/recorder/recorderSupplement');8markRootSuspendedAtTime(5000);9markRootSuspendedAtTime(6000);10const { markRootUnsuspendedAtTime } = require('playwright-core/lib/server/supplements/recorder/recorderSupplement');11markRootUnsuspendedAtTime(7000);12markRootUnsuspendedAtTime(8000);13const { markRootSuspendedAtTime } = require('playwright-core/lib/server/supplements/recorder/recorderSupplement');14markRootSuspendedAtTime(9000);15markRootSuspendedAtTime(10000);16const { markRootUnsuspendedAtTime } = require('playwright-core/lib/server/supplements/recorder/recorderSupplement');17markRootUnsuspendedAtTime(11000);18markRootUnsuspendedAtTime(12000);19const { markRootSuspendedAtTime } = require('playwright-core/lib/server/supplements/recorder/recorderSupplement');20markRootSuspendedAtTime(13000);21markRootSuspendedAtTime(14000);22const { markRootUnsuspendedAtTime } = require('playwright-core/lib/server/supplements/recorder/recorderSupplement');23markRootUnsuspendedAtTime(
Using AI Code Generation
1const { markRootSuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');2markRootSuspendedAtTime(1000);3const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');4markRootUnsuspendedAtTime(1000);5const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');6markRootUnsuspendedAtTime(1000);7const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');8markRootUnsuspendedAtTime(1000);9const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');10markRootUnsuspendedAtTime(1000);11const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');12markRootUnsuspendedAtTime(1000);13const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');14markRootUnsuspendedAtTime(1000);15const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');16markRootUnsuspendedAtTime(1000);17const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement');18markRootUnsuspendedAtTime(1000);
Using AI Code Generation
1const { markRootSuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');2markRootSuspendedAtTime(1000);3const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');4markRootUnsuspendedAtTime(1000);5const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');6markRootUnsuspendedAtTime(1000);7const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');8markRootUnsuspendedAtTime(1000);9const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');10markRootUnsuspendedAtTime(1000);11const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');12markRootUnsuspendedAtTime(1000);13const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');14markRootUnsuspendedAtTime(1000);15const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');16markRootUnsuspendedAtTime(1000);17const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');18markRootUnsuspendedAtTime(1000);
Using AI Code Generation
1const playwright = require('playwright');2const { markRootSuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');3const browser = await playwright['chromium'].launch({4});5const context = await browser.newContext();6const page = await context.newPage();7await markRootSuspendedAtTime(page, 1000);8await page.screenshot({ path: 'screenshot.png' });9await browser.close();
Using AI Code Generation
1const { markRootSuspendedAtTime } = require('playwright/lib/server/trace/recorder/snapshotter');2markRootSuspendedAtTime(1000);3const { test, expect } = require('@playwright/test');4test('test', async ({ page }) => {5 expect(1).toBe(1);6});7module.exports = {8 use: {9 },10 };11{12 "bin": {13 },14 "scripts": {15 },16 "repository": {
Using AI Code Generation
1const { markRootSuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');2markRootSuspendedAtTime(1000, 'test');3const { markRootUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');4markRootUnsuspendedAtTime(2000, 'test');5const { markRootStartedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');6markRootStartedAtTime(3000, 'test');7const { markRootFinishedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');8markRootFinishedAtTime(4000, 'test');9const { markRootFailedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');10markRootFailedAtTime(5000, 'test');11const { markStepStartedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');12markStepStartedAtTime(6000, 'test');13const { markStepSuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');14markStepSuspendedAtTime(7000, 'test');15const { markStepUnsuspendedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');16markStepUnsuspendedAtTime(8000, 'test');17const { markStepFinishedAtTime } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');18markStepFinishedAtTime(9000, 'test');
Using AI Code Generation
1const { markRootSuspendedAtTime } = require('playwright/internal/inspector/inspector')2markRootSuspendedAtTime(1000, 2000)3const { markRootSuspendedAtTime } = require('playwright/internal/inspector/inspector')4markRootSuspendedAtTime(1000, 2000)5const { markRootSuspendedAtTime } = require('playwright/internal/inspector/inspector')6markRootSuspendedAtTime(1000, 2000)7const { markRootSuspendedAtTime } = require('playwright/internal/inspector/inspector')8markRootSuspendedAtTime(1000, 2000)9const { markRootSuspendedAtTime } = require('playwright/internal/inspector/inspector')10markRootSuspendedAtTime(1000, 2000)11const { markRootSuspendedAtTime } = require('playwright/internal/inspector/inspector')12markRootSuspendedAtTime(1000, 2000)13const { markRootSuspendedAtTime } = require('playwright/internal/inspector/inspector')14markRootSuspendedAtTime(1000, 2000)15const { markRootSuspendedAtTime } = require('playwright/internal/inspector/inspector')16markRootSuspendedAtTime(1000, 2000)17const { markRootSuspendedAtTime } = require('playwright/internal/inspector/inspector')18markRootSuspendedAtTime(1000, 2000)19const { markRootSuspendedAtTime } = require('playwright/internal/inspector/ins
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!!