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/insLambdaTest’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!!
