Repository: puppeteer/puppeteer
File: packages/puppeteer-core/src/cdp/Page.ts (TypeScript)

Code before:
    return this.#emulationManager.javascriptEnabled;
  }

  override async openDevTools(): Promise<Page> {
    const session = await this.browser().target().createCDPSession();

    const pageTargetId = this.target()._targetId;
    const openDevToolsResponse = await session.send('Target.openDevTools', {
      targetId: pageTargetId,
    });

    const targetInfoResponse = await session.send('Target.getTargetInfo', {
      targetId: openDevToolsResponse.targetId,
    });

    const connection = session.connection();
    assert(connection, 'No connection when opening DevTools from page');
    const createSession = (isAutoAttachEmulated: boolean) => {
      return connection._createSession(
        targetInfoResponse.targetInfo,
        isAutoAttachEmulated,
      );
    };
    const devtoolsTarget = new DevToolsTarget(
      targetInfoResponse.targetInfo,
      undefined,
      this.browserContext(),
      this.#targetManager,
      createSession,
      this.viewport(),
    );
    return await devtoolsTarget.asPage();
  }

  override async waitForFileChooser(
    options: WaitTimeoutOptions = {},
  ): Promise<FileChooser> {
    const needsEnable = this.#fileChooserDeferreds.size === 0;
    const {timeout = this._timeoutSettings.timeout()} = options;
    const deferred = Deferred.create<FileChooser>({
      message: `Waiting for \`FileChooser\` failed: ${timeout}ms exceeded`,
      timeout,
    });

    if (options.signal) {
      options.signal.addEventListener(
        'abort',
        () => {
          deferred.reject(options.signal?.reason);
        },
        {once: true},

Review comment (suggestion):
@OrKoN this is supposed to be a `CdpCDPSession`, but I couldn't find the right way to pass this through.

I tried `this.#primaryTabTarget` but that just hangs (I don't think it's the right one anyway but thought I would try it). Open to help on what to do here - or confirmation that `undefined` is OK.

Code after:
    return this.#emulationManager.javascriptEnabled;
  }

  override async openDevTools(): Promise<Page> {
    const pageTargetId = this.target()._targetId;
    const browser = this.browser() as CdpBrowser;
    const devtoolsPage = await browser._createDevToolsPage(pageTargetId);
    return devtoolsPage;
  }

  override async waitForFileChooser(
    options: WaitTimeoutOptions = {},
  ): Promise<FileChooser> {
    const needsEnable = this.#fileChooserDeferreds.size === 0;
    const {timeout = this._timeoutSettings.timeout()} = options;
    const deferred = Deferred.create<FileChooser>({
      message: `Waiting for \`FileChooser\` failed: ${timeout}ms exceeded`,
      timeout,
    });

    if (options.signal) {
      options.signal.addEventListener(
        'abort',
        () => {
          deferred.reject(options.signal?.reason);
        },
        {once: true},
      );
    }

    this.#fileChooserDeferreds.add(deferred);
    let enablePromise: Promise<void> | undefined;
    if (needsEnable) {
      enablePromise = this.#primaryTargetClient.send(
        'Page.setInterceptFileChooserDialog',
        {
          enabled: true,
        },
      );
    }
    try {
      const [result] = await Promise.all([
        deferred.valueOrThrow(),
        enablePromise,
      ]);
      return result;
    } catch (error) {
      this.#fileChooserDeferreds.delete(deferred);
      throw error;
    }
  }