Best JavaScript code snippet using playwright-internal
ReactFiberUnwindWork.js
Source:ReactFiberUnwindWork.js  
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9import type {Fiber} from './ReactFiber';10import type {FiberRoot} from './ReactFiberRoot';11import type {ExpirationTime} from './ReactFiberExpirationTime';12import type {CapturedValue} from './ReactCapturedValue';13import type {Update} from './ReactUpdateQueue';14import type {Thenable} from './ReactFiberScheduler';15import {unstable_wrap as Schedule_tracing_wrap} from 'scheduler/tracing';16import getComponentName from 'shared/getComponentName';17import warningWithoutStack from 'shared/warningWithoutStack';18import {19  ClassComponent,20  HostRoot,21  HostComponent,22  HostPortal,23  ContextProvider,24  SuspenseComponent,25  DehydratedSuspenseComponent,26  IncompleteClassComponent,27  EventComponent,28  EventTarget,29} from 'shared/ReactWorkTags';30import {31  DidCapture,32  Incomplete,33  NoEffect,34  ShouldCapture,35  LifecycleEffectMask,36} from 'shared/ReactSideEffectTags';37import {38  enableSchedulerTracing,39  enableSuspenseServerRenderer,40  enableEventAPI,41} from 'shared/ReactFeatureFlags';42import {ConcurrentMode, NoContext} from './ReactTypeOfMode';43import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent';44import {createCapturedValue} from './ReactCapturedValue';45import {46  enqueueCapturedUpdate,47  createUpdate,48  CaptureUpdate,49  ForceUpdate,50  enqueueUpdate,51} from './ReactUpdateQueue';52import {logError} from './ReactFiberCommitWork';53import {getStackByFiberInDevAndProd} from './ReactCurrentFiber';54import {popHostContainer, popHostContext} from './ReactFiberHostContext';55import {56  isContextProvider as isLegacyContextProvider,57  popContext as popLegacyContext,58  popTopLevelContextObject as popTopLevelLegacyContextObject,59} from './ReactFiberContext';60import {popProvider} from './ReactFiberNewContext';61import {62  renderDidError,63  onUncaughtError,64  markLegacyErrorBoundaryAsFailed,65  isAlreadyFailedLegacyErrorBoundary,66  pingSuspendedRoot,67  resolveRetryThenable,68} from './ReactFiberScheduler';69import invariant from 'shared/invariant';70import {Sync} from './ReactFiberExpirationTime';71const PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;72const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;73function createRootErrorUpdate(74  fiber: Fiber,75  errorInfo: CapturedValue<mixed>,76  expirationTime: ExpirationTime,77): Update<mixed> {78  const update = createUpdate(expirationTime);79  // Unmount the root by rendering null.80  update.tag = CaptureUpdate;81  // Caution: React DevTools currently depends on this property82  // being called "element".83  update.payload = {element: null};84  const error = errorInfo.value;85  update.callback = () => {86    onUncaughtError(error);87    logError(fiber, errorInfo);88  };89  return update;90}91function createClassErrorUpdate(92  fiber: Fiber,93  errorInfo: CapturedValue<mixed>,94  expirationTime: ExpirationTime,95): Update<mixed> {96  const update = createUpdate(expirationTime);97  update.tag = CaptureUpdate;98  const getDerivedStateFromError = fiber.type.getDerivedStateFromError;99  if (typeof getDerivedStateFromError === 'function') {100    const error = errorInfo.value;101    update.payload = () => {102      return getDerivedStateFromError(error);103    };104  }105  const inst = fiber.stateNode;106  if (inst !== null && typeof inst.componentDidCatch === 'function') {107    update.callback = function callback() {108      if (typeof getDerivedStateFromError !== 'function') {109        // To preserve the preexisting retry behavior of error boundaries,110        // we keep track of which ones already failed during this batch.111        // This gets reset before we yield back to the browser.112        // TODO: Warn in strict mode if getDerivedStateFromError is113        // not defined.114        markLegacyErrorBoundaryAsFailed(this);115      }116      const error = errorInfo.value;117      const stack = errorInfo.stack;118      logError(fiber, errorInfo);119      this.componentDidCatch(error, {120        componentStack: stack !== null ? stack : '',121      });122      if (__DEV__) {123        if (typeof getDerivedStateFromError !== 'function') {124          // If componentDidCatch is the only error boundary method defined,125          // then it needs to call setState to recover from errors.126          // If no state update is scheduled then the boundary will swallow the error.127          warningWithoutStack(128            fiber.expirationTime === Sync,129            '%s: Error boundaries should implement getDerivedStateFromError(). ' +130              'In that method, return a state update to display an error message or fallback UI.',131            getComponentName(fiber.type) || 'Unknown',132          );133        }134      }135    };136  }137  return update;138}139function attachPingListener(140  root: FiberRoot,141  renderExpirationTime: ExpirationTime,142  thenable: Thenable,143) {144  // Attach a listener to the promise to "ping" the root and retry. But145  // only if one does not already exist for the current render expiration146  // time (which acts like a "thread ID" here).147  let pingCache = root.pingCache;148  let threadIDs;149  if (pingCache === null) {150    pingCache = root.pingCache = new PossiblyWeakMap();151    threadIDs = new Set();152    pingCache.set(thenable, threadIDs);153  } else {154    threadIDs = pingCache.get(thenable);155    if (threadIDs === undefined) {156      threadIDs = new Set();157      pingCache.set(thenable, threadIDs);158    }159  }160  if (!threadIDs.has(renderExpirationTime)) {161    // Memoize using the thread ID to prevent redundant listeners.162    threadIDs.add(renderExpirationTime);163    let ping = pingSuspendedRoot.bind(164      null,165      root,166      thenable,167      renderExpirationTime,168    );169    if (enableSchedulerTracing) {170      ping = Schedule_tracing_wrap(ping);171    }172    thenable.then(ping, ping);173  }174}175function throwException(176  root: FiberRoot,177  returnFiber: Fiber,178  sourceFiber: Fiber,179  value: mixed,180  renderExpirationTime: ExpirationTime,181) {182  // The source fiber did not complete.183  sourceFiber.effectTag |= Incomplete;184  // Its effect list is no longer valid.185  sourceFiber.firstEffect = sourceFiber.lastEffect = null;186  if (187    value !== null &&188    typeof value === 'object' &&189    typeof value.then === 'function'190  ) {191    // This is a thenable.192    const thenable: Thenable = (value: any);193    // Schedule the nearest Suspense to re-render the timed out view.194    let workInProgress = returnFiber;195    do {196      if (197        workInProgress.tag === SuspenseComponent &&198        shouldCaptureSuspense(workInProgress)199      ) {200        // Found the nearest boundary.201        // Stash the promise on the boundary fiber. If the boundary times out, we'll202        // attach another listener to flip the boundary back to its normal state.203        const thenables: Set<Thenable> = (workInProgress.updateQueue: any);204        if (thenables === null) {205          const updateQueue = (new Set(): any);206          updateQueue.add(thenable);207          workInProgress.updateQueue = updateQueue;208        } else {209          thenables.add(thenable);210        }211        // If the boundary is outside of concurrent mode, we should *not*212        // suspend the commit. Pretend as if the suspended component rendered213        // null and keep rendering. In the commit phase, we'll schedule a214        // subsequent synchronous update to re-render the Suspense.215        //216        // Note: It doesn't matter whether the component that suspended was217        // inside a concurrent mode tree. If the Suspense is outside of it, we218        // should *not* suspend the commit.219        if ((workInProgress.mode & ConcurrentMode) === NoContext) {220          workInProgress.effectTag |= DidCapture;221          // We're going to commit this fiber even though it didn't complete.222          // But we shouldn't call any lifecycle methods or callbacks. Remove223          // all lifecycle effect tags.224          sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);225          if (sourceFiber.tag === ClassComponent) {226            const currentSourceFiber = sourceFiber.alternate;227            if (currentSourceFiber === null) {228              // This is a new mount. Change the tag so it's not mistaken for a229              // completed class component. For example, we should not call230              // componentWillUnmount if it is deleted.231              sourceFiber.tag = IncompleteClassComponent;232            } else {233              // When we try rendering again, we should not reuse the current fiber,234              // since it's known to be in an inconsistent state. Use a force updte to235              // prevent a bail out.236              const update = createUpdate(Sync);237              update.tag = ForceUpdate;238              enqueueUpdate(sourceFiber, update);239            }240          }241          // The source fiber did not complete. Mark it with Sync priority to242          // indicate that it still has pending work.243          sourceFiber.expirationTime = Sync;244          // Exit without suspending.245          return;246        }247        // Confirmed that the boundary is in a concurrent mode tree. Continue248        // with the normal suspend path.249        attachPingListener(root, renderExpirationTime, thenable);250        workInProgress.effectTag |= ShouldCapture;251        workInProgress.expirationTime = renderExpirationTime;252        return;253      } else if (254        enableSuspenseServerRenderer &&255        workInProgress.tag === DehydratedSuspenseComponent256      ) {257        attachPingListener(root, renderExpirationTime, thenable);258        // Since we already have a current fiber, we can eagerly add a retry listener.259        let retryCache = workInProgress.memoizedState;260        if (retryCache === null) {261          retryCache = workInProgress.memoizedState = new PossiblyWeakSet();262          const current = workInProgress.alternate;263          invariant(264            current,265            'A dehydrated suspense boundary must commit before trying to render. ' +266              'This is probably a bug in React.',267          );268          current.memoizedState = retryCache;269        }270        // Memoize using the boundary fiber to prevent redundant listeners.271        if (!retryCache.has(thenable)) {272          retryCache.add(thenable);273          let retry = resolveRetryThenable.bind(null, workInProgress, thenable);274          if (enableSchedulerTracing) {275            retry = Schedule_tracing_wrap(retry);276          }277          thenable.then(retry, retry);278        }279        workInProgress.effectTag |= ShouldCapture;280        workInProgress.expirationTime = renderExpirationTime;281        return;282      }283      // This boundary already captured during this render. Continue to the next284      // boundary.285      workInProgress = workInProgress.return;286    } while (workInProgress !== null);287    // No boundary was found. Fallthrough to error mode.288    // TODO: Use invariant so the message is stripped in prod?289    value = new Error(290      (getComponentName(sourceFiber.type) || 'A React component') +291        ' suspended while rendering, but no fallback UI was specified.\n' +292        '\n' +293        'Add a <Suspense fallback=...> component higher in the tree to ' +294        'provide a loading indicator or placeholder to display.' +295        getStackByFiberInDevAndProd(sourceFiber),296    );297  }298  // We didn't find a boundary that could handle this type of exception. Start299  // over and traverse parent path again, this time treating the exception300  // as an error.301  renderDidError();302  value = createCapturedValue(value, sourceFiber);303  let workInProgress = returnFiber;304  do {305    switch (workInProgress.tag) {306      case HostRoot: {307        const errorInfo = value;308        workInProgress.effectTag |= ShouldCapture;309        workInProgress.expirationTime = renderExpirationTime;310        const update = createRootErrorUpdate(311          workInProgress,312          errorInfo,313          renderExpirationTime,314        );315        enqueueCapturedUpdate(workInProgress, update);316        return;317      }318      case ClassComponent:319        // Capture and retry320        const errorInfo = value;321        const ctor = workInProgress.type;322        const instance = workInProgress.stateNode;323        if (324          (workInProgress.effectTag & DidCapture) === NoEffect &&325          (typeof ctor.getDerivedStateFromError === 'function' ||326            (instance !== null &&327              typeof instance.componentDidCatch === 'function' &&328              !isAlreadyFailedLegacyErrorBoundary(instance)))329        ) {330          workInProgress.effectTag |= ShouldCapture;331          workInProgress.expirationTime = renderExpirationTime;332          // Schedule the error boundary to re-render using updated state333          const update = createClassErrorUpdate(334            workInProgress,335            errorInfo,336            renderExpirationTime,337          );338          enqueueCapturedUpdate(workInProgress, update);339          return;340        }341        break;342      default:343        break;344    }345    workInProgress = workInProgress.return;346  } while (workInProgress !== null);347}348function unwindWork(349  workInProgress: Fiber,350  renderExpirationTime: ExpirationTime,351) {352  switch (workInProgress.tag) {353    case ClassComponent: {354      const Component = workInProgress.type;355      if (isLegacyContextProvider(Component)) {356        popLegacyContext(workInProgress);357      }358      const effectTag = workInProgress.effectTag;359      if (effectTag & ShouldCapture) {360        workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture;361        return workInProgress;362      }363      return null;364    }365    case HostRoot: {366      popHostContainer(workInProgress);367      popTopLevelLegacyContextObject(workInProgress);368      const effectTag = workInProgress.effectTag;369      invariant(370        (effectTag & DidCapture) === NoEffect,371        'The root failed to unmount after an error. This is likely a bug in ' +372          'React. Please file an issue.',373      );374      workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture;375      return workInProgress;376    }377    case HostComponent: {378      // TODO: popHydrationState379      popHostContext(workInProgress);380      return null;381    }382    case SuspenseComponent: {383      const effectTag = workInProgress.effectTag;384      if (effectTag & ShouldCapture) {385        workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture;386        // Captured a suspense effect. Re-render the boundary.387        return workInProgress;388      }389      return null;390    }391    case DehydratedSuspenseComponent: {392      if (enableSuspenseServerRenderer) {393        // TODO: popHydrationState394        const effectTag = workInProgress.effectTag;395        if (effectTag & ShouldCapture) {396          workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture;397          // Captured a suspense effect. Re-render the boundary.398          return workInProgress;399        }400      }401      return null;402    }403    case HostPortal:404      popHostContainer(workInProgress);405      return null;406    case ContextProvider:407      popProvider(workInProgress);408      return null;409    case EventComponent:410    case EventTarget:411      if (enableEventAPI) {412        popHostContext(workInProgress);413      }414      return null;415    default:416      return null;417  }418}419function unwindInterruptedWork(interruptedWork: Fiber) {420  switch (interruptedWork.tag) {421    case ClassComponent: {422      const childContextTypes = interruptedWork.type.childContextTypes;423      if (childContextTypes !== null && childContextTypes !== undefined) {424        popLegacyContext(interruptedWork);425      }426      break;427    }428    case HostRoot: {429      popHostContainer(interruptedWork);430      popTopLevelLegacyContextObject(interruptedWork);431      break;432    }433    case HostComponent: {434      popHostContext(interruptedWork);435      break;436    }437    case HostPortal:438      popHostContainer(interruptedWork);439      break;440    case ContextProvider:441      popProvider(interruptedWork);442      break;443    default:444      break;445  }446}447export {448  throwException,449  unwindWork,450  unwindInterruptedWork,451  createRootErrorUpdate,452  createClassErrorUpdate,...ReactFiberThrow.js
Source:ReactFiberThrow.js  
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9import type { Fiber } from './ReactFiber';10import type { FiberRoot } from './ReactFiberRoot';11import type { ExpirationTime } from './ReactFiberExpirationTime';12import type { CapturedValue } from './ReactCapturedValue';13import type { Update } from './ReactUpdateQueue';14import type { Thenable } from './ReactFiberWorkLoop';15import type { SuspenseContext } from './ReactFiberSuspenseContext';16import { unstable_wrap as Schedule_tracing_wrap } from 'scheduler/tracing';17import getComponentName from 'shared/getComponentName';18import warningWithoutStack from 'shared/warningWithoutStack';19import {20  ClassComponent,21  HostRoot,22  SuspenseComponent,23  DehydratedSuspenseComponent,24  IncompleteClassComponent,25} from 'shared/ReactWorkTags';26import {27  DidCapture,28  Incomplete,29  NoEffect,30  ShouldCapture,31  LifecycleEffectMask,32} from 'shared/ReactSideEffectTags';33import {34  enableSchedulerTracing,35  enableSuspenseServerRenderer,36} from 'shared/ReactFeatureFlags';37import { NoMode, BatchedMode } from './ReactTypeOfMode';38import { shouldCaptureSuspense } from './ReactFiberSuspenseComponent';39import { createCapturedValue } from './ReactCapturedValue';40import {41  enqueueCapturedUpdate,42  createUpdate,43  CaptureUpdate,44  ForceUpdate,45  enqueueUpdate,46} from './ReactUpdateQueue';47import { logError } from './ReactFiberCommitWork';48import { getStackByFiberInDevAndProd } from './ReactCurrentFiber';49import { markFailedErrorBoundaryForHotReloading } from './ReactFiberHotReloading';50import {51  suspenseStackCursor,52  InvisibleParentSuspenseContext,53  hasSuspenseContext,54} from './ReactFiberSuspenseContext';55import {56  renderDidError,57  onUncaughtError,58  markLegacyErrorBoundaryAsFailed,59  isAlreadyFailedLegacyErrorBoundary,60  pingSuspendedRoot,61  resolveRetryThenable,62  checkForWrongSuspensePriorityInDEV,63} from './ReactFiberWorkLoop';64import invariant from 'shared/invariant';65import { Sync } from './ReactFiberExpirationTime';66const PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;67const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;68function createRootErrorUpdate(69  fiber: Fiber,70  errorInfo: CapturedValue<mixed>,71  expirationTime: ExpirationTime,72): Update<mixed> {73  const update = createUpdate(expirationTime, null);74  // Unmount the root by rendering null.75  // éè¿æ¸²ænullæ¥å¸è½½æ ¹ç®å½ã76  update.tag = CaptureUpdate;77  // Caution: React DevTools currently depends on this property78  // being called "element".79  // 注æ:React DevToolsç®åä¾èµäºè¢«ç§°ä¸ºâelementâç屿§ã80  const error = errorInfo.value;81  update.payload = { element: null };82  update.callback = () => {83    onUncaughtError(error);84    logError(fiber, errorInfo);85  };86  return update;87}88function createClassErrorUpdate(89  fiber: Fiber,90  errorInfo: CapturedValue<mixed>,91  expirationTime: ExpirationTime,92): Update<mixed> {93  const update = createUpdate(expirationTime, null);94  update.tag = CaptureUpdate;95  const getDerivedStateFromError = fiber.type.getDerivedStateFromError;96  if (typeof getDerivedStateFromError === 'function') {97    const error = errorInfo.value;98    update.payload = () => {99      return getDerivedStateFromError(error);100    };101  }102  const inst = fiber.stateNode;103  if (inst !== null && typeof inst.componentDidCatch === 'function') {104    update.callback = function callback() {105      if (__DEV__) {106        markFailedErrorBoundaryForHotReloading(fiber);107      }108      if (typeof getDerivedStateFromError !== 'function') {109        // To preserve the preexisting retry behavior of error boundaries,110        // we keep track of which ones already failed during this batch.111        // This gets reset before we yield back to the browser.112        // TODO: Warn in strict mode if getDerivedStateFromError is113        // not defined.114        markLegacyErrorBoundaryAsFailed(this);115      }116      const error = errorInfo.value;117      const stack = errorInfo.stack;118      logError(fiber, errorInfo);119      this.componentDidCatch(error, {120        componentStack: stack !== null ? stack : '',121      });122      if (__DEV__) {123        if (typeof getDerivedStateFromError !== 'function') {124          // If componentDidCatch is the only error boundary method defined,125          // then it needs to call setState to recover from errors.126          // If no state update is scheduled then the boundary will swallow the error.127          warningWithoutStack(128            fiber.expirationTime === Sync,129            '%s: Error boundaries should implement getDerivedStateFromError(). ' +130            'In that method, return a state update to display an error message or fallback UI.',131            getComponentName(fiber.type) || 'Unknown',132          );133        }134      }135    };136  } else if (__DEV__) {137    update.callback = () => {138      markFailedErrorBoundaryForHotReloading(fiber);139    };140  }141  return update;142}143function attachPingListener(144  root: FiberRoot,145  renderExpirationTime: ExpirationTime,146  thenable: Thenable,147) {148  // Attach a listener to the promise to "ping" the root and retry. But149  // only if one does not already exist for the current render expiration150  // time (which acts like a "thread ID" here).151  let pingCache = root.pingCache;152  let threadIDs;153  if (pingCache === null) {154    pingCache = root.pingCache = new PossiblyWeakMap();155    threadIDs = new Set();156    pingCache.set(thenable, threadIDs);157  } else {158    threadIDs = pingCache.get(thenable);159    if (threadIDs === undefined) {160      threadIDs = new Set();161      pingCache.set(thenable, threadIDs);162    }163  }164  if (!threadIDs.has(renderExpirationTime)) {165    // Memoize using the thread ID to prevent redundant listeners.166    threadIDs.add(renderExpirationTime);167    let ping = pingSuspendedRoot.bind(168      null,169      root,170      thenable,171      renderExpirationTime,172    );173    if (enableSchedulerTracing) {174      ping = Schedule_tracing_wrap(ping);175    }176    thenable.then(ping, ping);177  }178}179function throwException(180  root: FiberRoot,181  returnFiber: Fiber,182  sourceFiber: Fiber,183  value: mixed,184  renderExpirationTime: ExpirationTime,185) {186  // The source fiber did not complete.187  // æº fiber 没æå®æã188  sourceFiber.effectTag |= Incomplete;189  // Its effect list is no longer valid.190  // å
¶ effect å表ä¸åææã191  sourceFiber.firstEffect = sourceFiber.lastEffect = null;192  if (193    value !== null &&194    typeof value === 'object' &&195    typeof value.then === 'function'196  ) {197    // This is a thenable.198    const thenable: Thenable = (value: any);199    checkForWrongSuspensePriorityInDEV(sourceFiber);200    let hasInvisibleParentBoundary = hasSuspenseContext(201      suspenseStackCursor.current,202      (InvisibleParentSuspenseContext: SuspenseContext),203    );204    // Schedule the nearest Suspense to re-render the timed out view.205    let workInProgress = returnFiber;206    do {207      if (208        workInProgress.tag === SuspenseComponent &&209        shouldCaptureSuspense(workInProgress, hasInvisibleParentBoundary)210      ) {211        // Found the nearest boundary.212        // Stash the promise on the boundary fiber. If the boundary times out, we'll213        // attach another listener to flip the boundary back to its normal state.214        const thenables: Set<Thenable> = (workInProgress.updateQueue: any);215        if (thenables === null) {216          const updateQueue = (new Set(): any);217          updateQueue.add(thenable);218          workInProgress.updateQueue = updateQueue;219        } else {220          thenables.add(thenable);221        }222        // If the boundary is outside of batched mode, we should *not*223        // suspend the commit. Pretend as if the suspended component rendered224        // null and keep rendering. In the commit phase, we'll schedule a225        // subsequent synchronous update to re-render the Suspense.226        //227        // Note: It doesn't matter whether the component that suspended was228        // inside a batched mode tree. If the Suspense is outside of it, we229        // should *not* suspend the commit.230        if ((workInProgress.mode & BatchedMode) === NoMode) {231          workInProgress.effectTag |= DidCapture;232          // We're going to commit this fiber even though it didn't complete.233          // But we shouldn't call any lifecycle methods or callbacks. Remove234          // all lifecycle effect tags.235          sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);236          if (sourceFiber.tag === ClassComponent) {237            const currentSourceFiber = sourceFiber.alternate;238            if (currentSourceFiber === null) {239              // This is a new mount. Change the tag so it's not mistaken for a240              // completed class component. For example, we should not call241              // componentWillUnmount if it is deleted.242              sourceFiber.tag = IncompleteClassComponent;243            } else {244              // When we try rendering again, we should not reuse the current fiber,245              // since it's known to be in an inconsistent state. Use a force updte to246              // prevent a bail out.247              const update = createUpdate(Sync, null);248              update.tag = ForceUpdate;249              enqueueUpdate(sourceFiber, update);250            }251          }252          // The source fiber did not complete. Mark it with Sync priority to253          // indicate that it still has pending work.254          sourceFiber.expirationTime = Sync;255          // Exit without suspending.256          return;257        }258        // Confirmed that the boundary is in a concurrent mode tree. Continue259        // with the normal suspend path.260        attachPingListener(root, renderExpirationTime, thenable);261        workInProgress.effectTag |= ShouldCapture;262        workInProgress.expirationTime = renderExpirationTime;263        return;264      } else if (265        enableSuspenseServerRenderer &&266        workInProgress.tag === DehydratedSuspenseComponent267      ) {268        attachPingListener(root, renderExpirationTime, thenable);269        // Since we already have a current fiber, we can eagerly add a retry listener.270        let retryCache = workInProgress.memoizedState;271        if (retryCache === null) {272          retryCache = workInProgress.memoizedState = new PossiblyWeakSet();273          const current = workInProgress.alternate;274          invariant(275            current,276            'A dehydrated suspense boundary must commit before trying to render. ' +277            'This is probably a bug in React.',278          );279          current.memoizedState = retryCache;280        }281        // Memoize using the boundary fiber to prevent redundant listeners.282        if (!retryCache.has(thenable)) {283          retryCache.add(thenable);284          let retry = resolveRetryThenable.bind(null, workInProgress, thenable);285          if (enableSchedulerTracing) {286            retry = Schedule_tracing_wrap(retry);287          }288          thenable.then(retry, retry);289        }290        workInProgress.effectTag |= ShouldCapture;291        workInProgress.expirationTime = renderExpirationTime;292        return;293      }294      // This boundary already captured during this render. Continue to the next295      // boundary.296      workInProgress = workInProgress.return;297    } while (workInProgress !== null);298    // No boundary was found. Fallthrough to error mode.299    // TODO: Use invariant so the message is stripped in prod?300    value = new Error(301      (getComponentName(sourceFiber.type) || 'A React component') +302      ' suspended while rendering, but no fallback UI was specified.\n' +303      '\n' +304      'Add a <Suspense fallback=...> component higher in the tree to ' +305      'provide a loading indicator or placeholder to display.' +306      getStackByFiberInDevAndProd(sourceFiber),307    );308  }309  // We didn't find a boundary that could handle this type of exception. Start310  // over and traverse parent path again, this time treating the exception311  // as an error.312  // æä»¬æ²¡ææ¾å°å¯ä»¥å¤çè¿ç§ç±»åå¼å¸¸çè¾¹çã313  // éæ°å¯å¨å¹¶éåç¶è·¯å¾ï¼è¿æ¬¡å°å¼å¸¸è§ä¸ºé误ã314  renderDidError();315  value = createCapturedValue(value, sourceFiber);316  let workInProgress = returnFiber;317  do {318    switch (workInProgress.tag) {319      case HostRoot: {320        const errorInfo = value;321        workInProgress.effectTag |= ShouldCapture;322        workInProgress.expirationTime = renderExpirationTime;323        const update = createRootErrorUpdate(324          workInProgress,325          errorInfo,326          renderExpirationTime,327        );328        enqueueCapturedUpdate(workInProgress, update);329        return;330      }331      case ClassComponent:332        // Capture and retry333        const errorInfo = value;334        const ctor = workInProgress.type;335        const instance = workInProgress.stateNode;336        if (337          (workInProgress.effectTag & DidCapture) === NoEffect &&338          (typeof ctor.getDerivedStateFromError === 'function' ||339            (instance !== null &&340              typeof instance.componentDidCatch === 'function' &&341              !isAlreadyFailedLegacyErrorBoundary(instance)))342        ) {343          workInProgress.effectTag |= ShouldCapture;344          workInProgress.expirationTime = renderExpirationTime;345          // Schedule the error boundary to re-render using updated state346          // ä½¿ç¨æ´æ°ç¶æéæ°æ¸²æé误边ç347          const update = createClassErrorUpdate(348            workInProgress,349            errorInfo,350            renderExpirationTime,351          );352          enqueueCapturedUpdate(workInProgress, update);353          return;354        }355        break;356      default:357        break;358    }359    workInProgress = workInProgress.return;360  } while (workInProgress !== null);361}...ReactFiberScheduler.js
Source:ReactFiberScheduler.js  
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9import {enableNewScheduler} from 'shared/ReactFeatureFlags';10import {11  requestCurrentTime as requestCurrentTime_old,12  computeExpirationForFiber as computeExpirationForFiber_old,13  captureCommitPhaseError as captureCommitPhaseError_old,14  onUncaughtError as onUncaughtError_old,15  renderDidSuspend as renderDidSuspend_old,16  renderDidError as renderDidError_old,17  pingSuspendedRoot as pingSuspendedRoot_old,18  retryTimedOutBoundary as retryTimedOutBoundary_old,19  resolveRetryThenable as resolveRetryThenable_old,20  markLegacyErrorBoundaryAsFailed as markLegacyErrorBoundaryAsFailed_old,21  isAlreadyFailedLegacyErrorBoundary as isAlreadyFailedLegacyErrorBoundary_old,22  scheduleWork as scheduleWork_old,23  flushRoot as flushRoot_old,24  batchedUpdates as batchedUpdates_old,25  unbatchedUpdates as unbatchedUpdates_old,26  flushSync as flushSync_old,27  flushControlled as flushControlled_old,28  deferredUpdates as deferredUpdates_old,29  syncUpdates as syncUpdates_old,30  interactiveUpdates as interactiveUpdates_old,31  flushInteractiveUpdates as flushInteractiveUpdates_old,32  computeUniqueAsyncExpiration as computeUniqueAsyncExpiration_old,33  flushPassiveEffects as flushPassiveEffects_old,34  warnIfNotCurrentlyActingUpdatesInDev as warnIfNotCurrentlyActingUpdatesInDev_old,35  inferStartTimeFromExpirationTime as inferStartTimeFromExpirationTime_old,36} from './ReactFiberScheduler.old';37import {38  requestCurrentTime as requestCurrentTime_new,39  computeExpirationForFiber as computeExpirationForFiber_new,40  captureCommitPhaseError as captureCommitPhaseError_new,41  onUncaughtError as onUncaughtError_new,42  renderDidSuspend as renderDidSuspend_new,43  renderDidError as renderDidError_new,44  pingSuspendedRoot as pingSuspendedRoot_new,45  retryTimedOutBoundary as retryTimedOutBoundary_new,46  resolveRetryThenable as resolveRetryThenable_new,47  markLegacyErrorBoundaryAsFailed as markLegacyErrorBoundaryAsFailed_new,48  isAlreadyFailedLegacyErrorBoundary as isAlreadyFailedLegacyErrorBoundary_new,49  scheduleWork as scheduleWork_new,50  flushRoot as flushRoot_new,51  batchedUpdates as batchedUpdates_new,52  unbatchedUpdates as unbatchedUpdates_new,53  flushSync as flushSync_new,54  flushControlled as flushControlled_new,55  deferredUpdates as deferredUpdates_new,56  syncUpdates as syncUpdates_new,57  interactiveUpdates as interactiveUpdates_new,58  flushInteractiveUpdates as flushInteractiveUpdates_new,59  computeUniqueAsyncExpiration as computeUniqueAsyncExpiration_new,60  flushPassiveEffects as flushPassiveEffects_new,61  warnIfNotCurrentlyActingUpdatesInDev as warnIfNotCurrentlyActingUpdatesInDev_new,62  inferStartTimeFromExpirationTime as inferStartTimeFromExpirationTime_new,63} from './ReactFiberScheduler.new';64// enableNewScheduler é½ä¸º falseï¼æä»¥æä»¬åªç old ç代ç 65export const requestCurrentTime = enableNewScheduler66  ? requestCurrentTime_new67  : requestCurrentTime_old;68export const computeExpirationForFiber = enableNewScheduler69  ? computeExpirationForFiber_new70  : computeExpirationForFiber_old;71export const captureCommitPhaseError = enableNewScheduler72  ? captureCommitPhaseError_new73  : captureCommitPhaseError_old;74export const onUncaughtError = enableNewScheduler75  ? onUncaughtError_new76  : onUncaughtError_old;77export const renderDidSuspend = enableNewScheduler78  ? renderDidSuspend_new79  : renderDidSuspend_old;80export const renderDidError = enableNewScheduler81  ? renderDidError_new82  : renderDidError_old;83export const pingSuspendedRoot = enableNewScheduler84  ? pingSuspendedRoot_new85  : pingSuspendedRoot_old;86export const retryTimedOutBoundary = enableNewScheduler87  ? retryTimedOutBoundary_new88  : retryTimedOutBoundary_old;89export const resolveRetryThenable = enableNewScheduler90  ? resolveRetryThenable_new91  : resolveRetryThenable_old;92export const markLegacyErrorBoundaryAsFailed = enableNewScheduler93  ? markLegacyErrorBoundaryAsFailed_new94  : markLegacyErrorBoundaryAsFailed_old;95export const isAlreadyFailedLegacyErrorBoundary = enableNewScheduler96  ? isAlreadyFailedLegacyErrorBoundary_new97  : isAlreadyFailedLegacyErrorBoundary_old;98export const scheduleWork = enableNewScheduler99  ? scheduleWork_new100  : scheduleWork_old;101export const flushRoot = enableNewScheduler ? flushRoot_new : flushRoot_old;102export const batchedUpdates = enableNewScheduler103  ? batchedUpdates_new104  : batchedUpdates_old;105export const unbatchedUpdates = enableNewScheduler106  ? unbatchedUpdates_new107  : unbatchedUpdates_old;108export const flushSync = enableNewScheduler ? flushSync_new : flushSync_old;109export const flushControlled = enableNewScheduler110  ? flushControlled_new111  : flushControlled_old;112export const deferredUpdates = enableNewScheduler113  ? deferredUpdates_new114  : deferredUpdates_old;115export const syncUpdates = enableNewScheduler116  ? syncUpdates_new117  : syncUpdates_old;118export const interactiveUpdates = enableNewScheduler119  ? interactiveUpdates_new120  : interactiveUpdates_old;121export const flushInteractiveUpdates = enableNewScheduler122  ? flushInteractiveUpdates_new123  : flushInteractiveUpdates_old;124export const computeUniqueAsyncExpiration = enableNewScheduler125  ? computeUniqueAsyncExpiration_new126  : computeUniqueAsyncExpiration_old;127export const flushPassiveEffects = enableNewScheduler128  ? flushPassiveEffects_new129  : flushPassiveEffects_old;130export const warnIfNotCurrentlyActingUpdatesInDev = enableNewScheduler131  ? warnIfNotCurrentlyActingUpdatesInDev_new132  : warnIfNotCurrentlyActingUpdatesInDev_old;133export const inferStartTimeFromExpirationTime = enableNewScheduler134  ? inferStartTimeFromExpirationTime_new135  : inferStartTimeFromExpirationTime_old;136export type Thenable = {137  then(resolve: () => mixed, reject?: () => mixed): void | Thenable,...ReactFabric-dev.js
Source:ReactFabric-dev.js  
1--- "e:\\github\\fb-react-native-forpatch-base\\Libraries\\Renderer\\oss\\ReactFabric-dev.js"	2020-01-30 13:55:47.967612100 -08002+++ "e:\\github\\ms-react-native-forpatch\\Libraries\\Renderer\\oss\\ReactFabric-dev.js"	2020-01-29 14:10:08.967885800 -08003@@ -16411,6 +16411,40 @@4         _workInProgress.effectTag |= ShouldCapture;5         _workInProgress.expirationTime = renderExpirationTime;6         return;7+      } else if (8+        enableSuspenseServerRenderer &&9+        _workInProgress.tag === DehydratedSuspenseComponent10+      ) {11+        attachPingListener(root, renderExpirationTime, thenable);12+13+        // Since we already have a current fiber, we can eagerly add a retry listener.14+        var retryCache = _workInProgress.memoizedState;15+        if (retryCache === null) {16+          retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();17+          var _current = _workInProgress.alternate;18+          invariant(19+            _current,20+            "A dehydrated suspense boundary must commit before trying to render. " +21+              "This is probably a bug in React."22+          );23+          _current.memoizedState = retryCache;24+        }25+        // Memoize using the boundary fiber to prevent redundant listeners.26+        if (!retryCache.has(thenable)) {27+          retryCache.add(thenable);28+          var retry = resolveRetryThenable.bind(29+            null,30+            _workInProgress,31+            thenable32+          );33+          if (enableSchedulerTracing) {34+            retry = tracing.unstable_wrap(retry);35+          }36+          thenable.then(retry, retry);37+        }38+        _workInProgress.effectTag |= ShouldCapture;39+        _workInProgress.expirationTime = renderExpirationTime;40+        return;41       }42       // This boundary already captured during this render. Continue to the next43       // boundary.44@@ -16933,6 +16967,10 @@45   } else {46     return false;47   }48+  // Flush any sync work that was scheduled by effects49+  if (!isBatchingUpdates && !isRendering) {50+    performSyncWork();51+  }52 }53 54 function interactiveUpdates$1(fn, a, b, c) {55@@ -18190,6 +18228,7 @@56       );57     }58   }59+  performWork(NoWork, true);60 }61 62 function flushRenderPhaseStrictModeWarningsInDEV() {63@@ -19085,6 +19124,17 @@64      * Manipulation](docs/direct-manipulation.html)).65      */66     setNativeProps: function(nativeProps) {67+      {68+        if (warnAboutDeprecatedSetNativeProps) {69+          warningWithoutStack$1(70+            false,71+            "Warning: Calling ref.setNativeProps(nativeProps) " +72+              "is deprecated and will be removed in a future release. " +73+              "Use the setNativeProps export from the react-native package instead." +74+              "\n\timport {setNativeProps} from 'react-native';\n\tsetNativeProps(ref, nativeProps);\n"75+          );76+        }77+      }78       // Class components don't have viewConfig -> validateAttributes.79       // Nor does it make sense to set native props on a non-native component.80       // Instead, find the nearest host component and set props on it.81@@ -19464,6 +19514,18 @@82     ReactNativeComponent.prototype.setNativeProps = function setNativeProps(83       nativeProps84     ) {85+      {86+        if (warnAboutDeprecatedSetNativeProps) {87+          warningWithoutStack$1(88+            false,89+            "Warning: Calling ref.setNativeProps(nativeProps) " +90+              "is deprecated and will be removed in a future release. " +91+              "Use the setNativeProps export from the react-native package instead." +92+              "\n\timport {setNativeProps} from 'react-native';\n\tsetNativeProps(ref, nativeProps);\n"93+          );94+        }95+      }96+97       // Class components don't have viewConfig -> validateAttributes.98       // Nor does it make sense to set native props on a non-native component.99       // Instead, find the nearest host component and set props on it.100@@ -19645,6 +19707,36 @@101   };102 }103 104+// Module provided by RN:105+function setNativeProps(handle, nativeProps) {106+  if (handle._nativeTag == null) {107+    !(handle._nativeTag != null)108+      ? warningWithoutStack$1(109+          false,110+          "setNativeProps was called with a ref that isn't a " +111+            "native component. Use React.forwardRef to get access to the underlying native component"112+        )113+      : void 0;114+    return;115+  }116+117+  {118+    warnForStyleProps(nativeProps, handle.viewConfig.validAttributes);119+  }120+121+  var updatePayload = create(nativeProps, handle.viewConfig.validAttributes);122+  // Avoid the overhead of bridge calls if there's no update.123+  // This is an expensive no-op for Android, and causes an unnecessary124+  // view invalidation for certain components (eg RCTTextInput) on iOS.125+  if (updatePayload != null) {126+    UIManager.updateView(127+      handle._nativeTag,128+      handle.viewConfig.uiViewClassName,129+      updatePayload130+    );131+  }132+}133+134 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;135 136 function findNodeHandle(componentOrHandle) {137@@ -19776,4 +19868,4 @@138 module.exports = fabric;139 140   })();141-}142+}...ReactNativeRenderer-dev.js
Source:ReactNativeRenderer-dev.js  
1--- "e:\\github\\fb-react-native-forpatch-base\\Libraries\\Renderer\\oss\\ReactNativeRenderer-dev.js"	2020-01-30 13:55:47.970607600 -08002+++ "e:\\github\\ms-react-native-forpatch\\Libraries\\Renderer\\oss\\ReactNativeRenderer-dev.js"	2020-01-29 14:10:08.972883100 -08003@@ -3827,6 +3827,19 @@4   }5 }6 7+var debugRenderPhaseSideEffects = false;8+var debugRenderPhaseSideEffectsForStrictMode = false;9+var enableUserTimingAPI = true;10+var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;11+var warnAboutDeprecatedLifecycles = false;12+var enableProfilerTimer = true;13+var enableSchedulerTracing = true;14+var enableSuspenseServerRenderer = false;15+16+var warnAboutDeprecatedSetNativeProps = false;17+18+// Only used in www builds.19+20 function _classCallCheck(instance, Constructor) {21   if (!(instance instanceof Constructor)) {22     throw new TypeError("Cannot call a class as a function");23@@ -16739,6 +16752,40 @@24         _workInProgress.effectTag |= ShouldCapture;25         _workInProgress.expirationTime = renderExpirationTime;26         return;27+      } else if (28+        enableSuspenseServerRenderer &&29+        _workInProgress.tag === DehydratedSuspenseComponent30+      ) {31+        attachPingListener(root, renderExpirationTime, thenable);32+33+        // Since we already have a current fiber, we can eagerly add a retry listener.34+        var retryCache = _workInProgress.memoizedState;35+        if (retryCache === null) {36+          retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();37+          var _current = _workInProgress.alternate;38+          invariant(39+            _current,40+            "A dehydrated suspense boundary must commit before trying to render. " +41+              "This is probably a bug in React."42+          );43+          _current.memoizedState = retryCache;44+        }45+        // Memoize using the boundary fiber to prevent redundant listeners.46+        if (!retryCache.has(thenable)) {47+          retryCache.add(thenable);48+          var retry = resolveRetryThenable.bind(49+            null,50+            _workInProgress,51+            thenable52+          );53+          if (enableSchedulerTracing) {54+            retry = tracing.unstable_wrap(retry);55+          }56+          thenable.then(retry, retry);57+        }58+        _workInProgress.effectTag |= ShouldCapture;59+        _workInProgress.expirationTime = renderExpirationTime;60+        return;61       }62       // This boundary already captured during this render. Continue to the next63       // boundary.64@@ -17231,6 +17278,10 @@65       root.callbackExpirationTime = NoWork;66     }67   }68+  // Flush any sync work that was scheduled by effects69+  if (!isBatchingUpdates && !isRendering) {70+    performSyncWork();71+  }72 }73 74 function flushInteractiveUpdates$1() {75@@ -19413,6 +19464,17 @@76      * Manipulation](docs/direct-manipulation.html)).77      */78     setNativeProps: function(nativeProps) {79+      {80+        if (warnAboutDeprecatedSetNativeProps) {81+          warningWithoutStack$1(82+            false,83+            "Warning: Calling ref.setNativeProps(nativeProps) " +84+              "is deprecated and will be removed in a future release. " +85+              "Use the setNativeProps export from the react-native package instead." +86+              "\n\timport {setNativeProps} from 'react-native';\n\tsetNativeProps(ref, nativeProps);\n"87+          );88+        }89+      }90       // Class components don't have viewConfig -> validateAttributes.91       // Nor does it make sense to set native props on a non-native component.92       // Instead, find the nearest host component and set props on it.93@@ -19792,6 +19854,18 @@94     ReactNativeComponent.prototype.setNativeProps = function setNativeProps(95       nativeProps96     ) {97+      {98+        if (warnAboutDeprecatedSetNativeProps) {99+          warningWithoutStack$1(100+            false,101+            "Warning: Calling ref.setNativeProps(nativeProps) " +102+              "is deprecated and will be removed in a future release. " +103+              "Use the setNativeProps export from the react-native package instead." +104+              "\n\timport {setNativeProps} from 'react-native';\n\tsetNativeProps(ref, nativeProps);\n"105+          );106+        }107+      }108+109       // Class components don't have viewConfig -> validateAttributes.110       // Nor does it make sense to set native props on a non-native component....Using AI Code Generation
1const { resolveRetryThenable } = require('playwright/lib/utils/utils');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const page = await browser.newPage();6  const element = await page.waitForSelector('text=Get started');7  await resolveRetryThenable(element);8  await element.click();9  await browser.close();10})();11const { resolveRetryThenable } = require('playwright/lib/utils/utils');12const { chromium } = require('playwright');13describe('Playwright', () => {14  it('should work', async () => {15    const browser = await chromium.launch();16    const page = await browser.newPage();17    const element = await page.waitForSelector('text=Get started');18    await resolveRetryThenable(element);19    await element.click();20    await browser.close();21  });22});Using AI Code Generation
1const { resolveRetryThenable } = require('playwright/lib/utils/utils');2const { chromium } = require('playwright');3const browser = await chromium.launch();4const context = await browser.newContext();5const page = await context.newPage();6await page.screenshot({ path: 'google.png' });7await browser.close();8const { resolveRetryThenable } = require('playwright/lib/utils/utils');9const { chromium } = require('playwright');10const browser = await chromium.launch();11const context = await browser.newContext();12const page = await context.newPage();13await page.screenshot({ path: 'google.png' });14await browser.close();15const { resolveRetryThenable } = require('playwright/lib/utils/utils');16const { resolveRetryThenable } = require('playwright/lib/utils/utils');17const { resolveRetryThenable } = require('playwright/lib/utils/utils');Using AI Code Generation
1(async () => {2  const browser = await playwright.chromium.launch();3  const page = await browser.newPage();4  await page.screenshot({ path: 'example.png' });5  await browser.close();6})();7import { test, expect } from '@playwright/test';8test('test', async ({ page }) => {9  const title = page.locator('.navbar__inner .navbar__title');10  await expect(title).toBeVisible();11  await expect(title).toHaveText('Playwright');12});Using AI Code Generation
1const { resolveRetryThenable } = require('@playwright/test/lib/utils/utils');2const { test } = require('@playwright/test');3test('test', async ({ page }) => {4  const element = await page.waitForSelector('text=Learn');5  const resolvedElement = await resolveRetryThenable(element);6  console.log('resolvedElement', resolvedElement);7});8resolvedElement ElementHandle {9  _channel: Channel {10    _callbacks: Map {},11    _connection: Connection {12      _callbacks: Map {},13      _sessions: Map {},14    },15  },16  _page: Page {17    _browserContext: BrowserContext {18    },19    _options: { viewport: null, noDefaultViewport: falseUsing AI Code Generation
1const { resolveRetryThenable } = require('playwright/lib/internal/inspectorInstrumentation');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch({ headless: false });5  const page = await browser.newPage();6  const input = await page.$('input[name="q"]');7  await input.focus();8  await input.type('Hello World');9  await page.keyboard.press('Enter');10  await page.waitForSelector('h3');11  const title = await page.title();12  console.log(title);13  await browser.close();14})();15const { resolveRetryThenable } = require('playwright/lib/internal/inspectorInstrumentation');16const { chromium } = require('playwright');17(async () => {18  const browser = await chromium.launch({ headless: false });19  const page = await browser.newPage();20  const input = await page.$('input[name="q"]');21  await input.focus();22  await input.type('Hello World');23  await page.keyboard.press('Enter');24  await page.waitForSelector('h3');25  const title = await page.title();26  console.log(title);27  await browser.close();28})();29const { resolveRetryThenable } = require('playwright/lib/internal/inspectorInstrumentation');30const { chromium } = require('playwright');31(async () => {32  const browser = await chromium.launch({ headless: false });33  const page = await browser.newPage();34  const input = await page.$('input[name="q"]');35  await input.focus();36  await input.type('Hello World');37  await page.keyboard.press('Enter');38  await page.waitForSelector('h3');39  const title = await page.title();40  console.log(title);41  await browser.close();42})();43const { resolveRetryThenable } = require('playwright/lib/internal/inspectorInstrumentation');44const { chromium } = require('playwright');45(async () => {46  const browser = await chromium.launch({ headless: false });47  const page = await browser.newPage();Using AI Code Generation
1const { resolveRetryThenable } = require('playwright/lib/utils/utils');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const page = await browser.newPage();6  await page.goto('Using AI Code Generation
1const { resolveRetryThenable } = require('playwright/lib/server/frames');2(async () => {3  const result = await resolveRetryThenable(() => Promise.resolve('foo'));4})();5const { resolveRetryThenable } = require('playwright/lib/server/frames');6(async () => {7  const page = await browser.newPage();8  await page.evaluate(() => {9    const thenable = {10      then: (resolve) => {11        setTimeout(() => resolve('foo'), 1000);12      },13    };14    window.result = resolveRetryThenable(() => thenable);15  });16  const result = await page.evaluate(() => window.result);17})();18const { chromium } = require('playwright');19(async () => {20  const browser = await chromium.launch();21  const page = await browser.newPage();22  await page.evaluate(() => {23    const thenable = {24      then: (resolve) => {25        setTimeout(() => resolve('foo'), 1000);26      },27    };28    window.result = thenable;29  });30  const result = await page.evaluate(() => window.result);31})();32const { chromium } = require('playwright');33(async () => {34  const browser = await chromium.launch();35  const page = await browser.newPage();LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
