Repository: microsoft/playwright
File: packages/playwright/src/worker/testInfo.ts (TypeScript)

Code before:
    const shouldPause = (this._workerParams.pauseAtEnd && !this._isFailure()) || (this._workerParams.pauseOnError && this._isFailure());
    if (shouldPause) {
      const location = (this._isFailure() ? this._errorLocation() : await this._testEndLocation()) ?? { file: this.file, line: this.line, column: this.column };
      this._emitErrors();
      this._onTestPaused({ testId: this.testId });
      await this._runAsStep({ title: this._isFailure() ? 'Paused on Error' : 'Paused at End', category: 'test.step', location }, async () => {
        await this._interruptedPromise;
      });
    }
    await this._onDidFinishTestFunctionCallback?.();
  }

  _emitErrors() {
    const errors = this.errors.slice(this._reportedError);
    this._reportedError = this.errors.length;
    if (errors.length)
      this._onError({ testId: this.testId, errors });
  }

  _errorLocation(): Location | undefined {
    if (this.error?.stack)
      return filteredStackTrace(this.error.stack.split('\n'))[0];
  }

  async _testEndLocation() {
    const source = await fs.promises.readFile(this.file, 'utf-8');
    return findTestEndPosition(source, this);
  }

  // ------------ TestInfo methods ------------

  async attach(name: string, options: { path?: string, body?: string | Buffer, contentType?: string } = {}) {
    const step = this._addStep({
      title: `Attach ${escapeWithQuotes(name, '"')}`,
      category: 'test.attach',
    });
    this._attach(
        await normalizeAndSaveAttachment(this.outputPath(), name, options),
        step.stepId
    );
    step.complete({});
  }

  _attach(attachment: TestInfo['attachments'][0], stepId: string | undefined) {
    const index = this._attachmentsPush(attachment) - 1;

    let step = stepId ? this._stepMap.get(stepId) : undefined;
    if (!!step?.group)
      step = undefined;

    if (step) {

Review comment (bug):
Let's `try/catch` this, we don't want to fail due to fs or babel problems.

Code after:
    const shouldPause = (this._workerParams.pauseAtEnd && !this._isFailure()) || (this._workerParams.pauseOnError && this._isFailure());
    if (shouldPause) {
      const location = (this._isFailure() ? this._errorLocation() : await this._testEndLocation()) ?? { file: this.file, line: this.line, column: this.column };
      this._emitErrors();
      this._onTestPaused({ testId: this.testId });
      await this._runAsStep({ title: this._isFailure() ? 'Paused on Error' : 'Paused at End', category: 'test.step', location }, async () => {
        await this._interruptedPromise;
      });
    }
    await this._onDidFinishTestFunctionCallback?.();
  }

  _emitErrors() {
    const errors = this.errors.slice(this._reportedErrorCount);
    this._reportedErrorCount = Math.max(this._reportedErrorCount, this.errors.length);
    if (errors.length)
      this._onErrors({ testId: this.testId, errors });
  }

  private _errorLocation(): Location | undefined {
    if (this.error?.stack)
      return filteredStackTrace(this.error.stack.split('\n'))[0];
  }

  private async _testEndLocation(): Promise<Location | undefined> {
    try {
      const source = await fs.promises.readFile(this.file, 'utf-8');
      return findTestEndLocation(source, { file: this.file, line: this.line, column: this.column });
    } catch {}
  }

  // ------------ TestInfo methods ------------

  async attach(name: string, options: { path?: string, body?: string | Buffer, contentType?: string } = {}) {
    const step = this._addStep({
      title: `Attach ${escapeWithQuotes(name, '"')}`,
      category: 'test.attach',
    });
    this._attach(
        await normalizeAndSaveAttachment(this.outputPath(), name, options),
        step.stepId
    );
    step.complete({});
  }

  _attach(attachment: TestInfo['attachments'][0], stepId: string | undefined) {
    const index = this._attachmentsPush(attachment) - 1;

    let step = stepId ? this._stepMap.get(stepId) : undefined;
    if (!!step?.group)
      step = undefined;