Repository: puppeteer/puppeteer
File: packages/puppeteer-core/src/common/util.ts (TypeScript)

Code before:
    assert(args.length === 0, 'Cannot evaluate a string with arguments');
    return fun;
  }

  function serializeArgument(arg: unknown): string {
    if (Object.is(arg, undefined)) {
      return 'undefined';
    }
    return JSON.stringify(arg);
  }

  return `(${fun})(${args.map(serializeArgument).join(',')})`;
}

/**
 * @internal
 */
export function addPageBinding(type: string, name: string): void {
  // This is the CDP binding.
  // @ts-expect-error: In a different context.
  const callCdp = globalThis[name];

  // Depending on the frame loading state either Runtime.evaluate or
  // Page.addScriptToEvaluateOnNewDocument might succeed. Let's check that we
  // don't re-wrap Puppeteer's binding.
  if (callCdp.toString().includes('This is the Puppeteer binding.')) {
    return;
  }

  // We replace the CDP binding with a Puppeteer binding.
  Object.assign(globalThis, {
    [name](...args: unknown[]): Promise<unknown> {
      // This is the Puppeteer binding.
      // @ts-expect-error: In a different context.
      const callPuppeteer = globalThis[name];
      callPuppeteer.args ??= new Map();
      callPuppeteer.callbacks ??= new Map();

      const seq = (callPuppeteer.lastSeq ?? 0) + 1;
      callPuppeteer.lastSeq = seq;
      callPuppeteer.args.set(seq, args);

      callCdp(
        JSON.stringify({
          type,
          name,
          seq,
          args,
          isTrivial: !args.some(value => {
            return value instanceof Node;
          }),

Review comment (suggestion):
I don't like looking for a specific Comment in the function. How about we do this after:
```ts
Object.assign(globalThis[name],{
  toString(): {
    return 'PuppeteerBinding'
  }
}
```
And this turns into
```suggestion
  if (callCdp.toString() === 'PuppeteerBinding') {
```

Code after:
    assert(args.length === 0, 'Cannot evaluate a string with arguments');
    return fun;
  }

  function serializeArgument(arg: unknown): string {
    if (Object.is(arg, undefined)) {
      return 'undefined';
    }
    return JSON.stringify(arg);
  }

  return `(${fun})(${args.map(serializeArgument).join(',')})`;
}

/**
 * @internal
 */
export function addPageBinding(type: string, name: string): void {
  // This is the CDP binding.
  // @ts-expect-error: In a different context.
  const callCdp = globalThis[name];

  // Depending on the frame loading state either Runtime.evaluate or
  // Page.addScriptToEvaluateOnNewDocument might succeed. Let's check that we
  // don't re-wrap Puppeteer's binding.
  if (callCdp[Symbol.toStringTag] === 'PuppeteerBinding') {
    return;
  }

  // We replace the CDP binding with a Puppeteer binding.
  Object.assign(globalThis, {
    [name](...args: unknown[]): Promise<unknown> {
      // This is the Puppeteer binding.
      // @ts-expect-error: In a different context.
      const callPuppeteer = globalThis[name];
      callPuppeteer.args ??= new Map();
      callPuppeteer.callbacks ??= new Map();

      const seq = (callPuppeteer.lastSeq ?? 0) + 1;
      callPuppeteer.lastSeq = seq;
      callPuppeteer.args.set(seq, args);

      callCdp(
        JSON.stringify({
          type,
          name,
          seq,
          args,
          isTrivial: !args.some(value => {
            return value instanceof Node;
          }),