MCPcopy
hub / github.com/vercel/next.js / _chain

Method _chain

test/lib/browsers/playwright.ts:672–730  ·  view source on GitHub ↗
(
    this: Playwright<TCurrent>,
    mustBeChained: boolean,
    nextCall: (current: TCurrent) => TNext | Promise<TNext>
  )

Source from the content-addressed store, hash-verified

670 readonly [Symbol.toStringTag]: string = 'Playwright'
671
672 private _chain<TNext>(
673 this: Playwright<TCurrent>,
674 mustBeChained: boolean,
675 nextCall: (current: TCurrent) => TNext | Promise<TNext>
676 ): Playwright<TNext> & Promise<TNext> {
677 const syncError = new Error('next-browser-base-chain-error')
678
679 // If `this` is actually a proxy created by a previous chained call, it'll act like it has a `promise` property.
680 // (see proxy code below)
681 type MaybeChained<T> = Playwright<T> & {
682 promise?: Promise<T>
683 }
684 const self = this as MaybeChained<TCurrent>
685
686 let currentPromise = self.promise
687 if (!currentPromise) {
688 if (mustBeChained) {
689 // Note that this should also be enforced by the type system
690 // by adding appropriate `(this: Playwright<PreviousValue>)` type annotations
691 // to methods that expect to be chained, but tests can bypass this (or not be checked because they use JS)
692 throw new Error(
693 'Expected this call to be chained after a previous call'
694 )
695 } else {
696 // We're handling a call that does not expect to be chained after a previous one,
697 // so it's safe to default the current value to undefined -- we don't need a value to invoke `nextCall`
698 currentPromise = Promise.resolve(undefined as TCurrent)
699 }
700 }
701
702 const promise = currentPromise.then(nextCall).catch((reason: unknown) => {
703 // TODO: only patch the stacktrace if the sync callstack is missing from it
704 if (reason && typeof reason === 'object' && 'stack' in reason) {
705 const syncCallStack = syncError.stack!.split(syncError.message)[1]
706 reason.stack += `\n${syncCallStack}`
707 }
708 throw reason
709 })
710
711 function get(target: Playwright<TCurrent>, p: string | symbol): any {
712 switch (p) {
713 case 'promise':
714 return promise
715 case 'then':
716 return promise.then.bind(promise)
717 case 'catch':
718 return promise.catch.bind(promise)
719 case 'finally':
720 return promise.finally.bind(promise)
721 default:
722 return target[p]
723 }
724 }
725
726 // @ts-expect-error: we're changing `TCurrent` into TNext via proxy hacks
727 return new Proxy(this, {
728 get,
729 })

Callers 3

continueChainMethod · 0.95
startChainMethod · 0.95
startOrPreserveChainMethod · 0.95

Calls 4

thenMethod · 0.80
splitMethod · 0.80
resolveMethod · 0.65
catchMethod · 0.45

Tested by

no test coverage detected