Repository: microsoft/playwright
File: packages/playwright/src/mcp/test/testContext.ts (TypeScript)

Code before:
      if (status !== 'passed')
        return { output: testRunnerAndScreen.output.join('\n'), status };
    } finally {
      releaseStdio();
    }

    let status: FullResultStatus | 'paused' = 'passed';

    const cleanup = async () => {
      claimStdio();
      try {
        const result = await testRunner.runGlobalTeardown();
        if (status === 'passed')
          status = result.status;
      } finally {
        releaseStdio();
      }
    };

    try {
      const reporter = new Multiplexer([
        new ListReporter({ configDir, screen, includeTestId: true }),
        {
          version: () => 'v2',
          onTestPaused() {
            return new Promise(() => {}); // stall
          }
        }
      ]);
      status = await Promise.race([
        testRunner.runTests(reporter, params).then(result => result.status),
        testRunnerAndScreen.waitForTestPaused().then(() => 'paused' as const),
      ]);

      if (status === 'paused') {
        const response = await testRunnerAndScreen.sendMessageToPausedTest!({ request: { initialize: { clientInfo: this._clientInfo } } });
        if (response.error)
          throw new Error(response.error.message);
        testRunnerAndScreen.output.push(response.response.initialize!.pausedMessage);
        return { output: testRunnerAndScreen.output.join('\n'), status };
      }
    } catch (e) {
      status = 'failed';
      testRunnerAndScreen.output.push(String(e));
      await cleanup();
      return { output: testRunnerAndScreen.output.join('\n'), status };
    }

    await cleanup();
    return { output: testRunnerAndScreen.output.join('\n'), status };
  }

Review comment (suggestion):
I don't quite get this part. Why do we need to stall here? Let's make reporter's `onTestPaused()` not called when running in a test runner mode for now.

Code after:
        return { output: testRunnerAndScreen.output.join('\n'), status };
    } finally {
      releaseStdio();
    }

    let status: FullResultStatus | 'paused' = 'passed';

    const cleanup = async () => {
      claimStdio();
      try {
        const result = await testRunner.runGlobalTeardown();
        if (status === 'passed')
          status = result.status;
      } finally {
        releaseStdio();
      }
    };

    try {
      const reporter = new ListReporter({ configDir, screen, includeTestId: true });
      status = await Promise.race([
        testRunner.runTests(reporter, params).then(result => result.status),
        testRunnerAndScreen.waitForTestPaused().then(() => 'paused' as const),
      ]);

      if (status === 'paused') {
        const response = await testRunnerAndScreen.sendMessageToPausedTest!({ request: { initialize: { clientInfo: this._clientInfo } } });
        if (response.error)
          throw new Error(response.error.message);
        testRunnerAndScreen.output.push(response.response.initialize!.pausedMessage);
        return { output: testRunnerAndScreen.output.join('\n'), status };
      }
    } catch (e) {
      status = 'failed';
      testRunnerAndScreen.output.push(String(e));
      await cleanup();
      return { output: testRunnerAndScreen.output.join('\n'), status };
    }

    await cleanup();
    return { output: testRunnerAndScreen.output.join('\n'), status };
  }

  async close() {
    await this._cleanupTestRunner().catch(logUnhandledError);
  }

  async sendMessageToPausedTest(request: BrowserMCPRequest): Promise<BrowserMCPResponse> {
    const sendMessage = this._testRunnerAndScreen?.sendMessageToPausedTest;
    if (!sendMessage)
      throw new Error('Must setup test before interacting with the page');