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: false
Using 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!!