diff --git a/packages/playwright-core/src/server/dispatchers/dispatcher.ts b/packages/playwright-core/src/server/dispatchers/dispatcher.ts index 1cf7edeb70ac2..3bb60565fa7c5 100644 --- a/packages/playwright-core/src/server/dispatchers/dispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/dispatcher.ts @@ -312,7 +312,7 @@ export class DispatcherConnection { return; } if (method === '__abort__') { - await this._activeProgressControllers.get(`call@${params.id}`)?.abort(new AbortError(undefined, { cause: params.reason })); + await this._activeProgressControllers.get(`call@${params.id}`)?.abort(new AbortError(params.reason)); return; } if (!dispatcher) { diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index 44de2e8249066..20ae2660de8f9 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -16,7 +16,6 @@ */ import yaml from 'yaml'; -import { assertionAbortedMessage } from '@isomorphic/abortSignal'; import { parseAriaSnapshotUnsafe } from '@isomorphic/ariaSnapshot'; import { isInvalidSelectorError } from '@isomorphic/selectorParser'; import { ManualPromise } from '@isomorphic/manualPromise'; @@ -29,7 +28,7 @@ import { makeWaitForNextTask } from '@utils/task'; import { createGuid } from '@utils/crypto'; import { BrowserContext } from './browserContext'; import * as dom from './dom'; -import { TimeoutError, AbortError, isTargetClosedError } from './errors'; +import { TimeoutError, isTargetClosedError } from './errors'; import { prepareFilesForUpload } from './fileUploadUtils'; import { FrameSelectors } from './frameSelectors'; import { helper } from './helper'; @@ -1545,8 +1544,6 @@ export class Frame extends SdkObject { progress.log(e.message); if (e instanceof TimeoutError) details.timedOut = true; - if (e instanceof AbortError) - details.customErrorMessage = assertionAbortedMessage(e.cause); throw new ExpectError(details); } } diff --git a/packages/playwright-core/src/server/progress.ts b/packages/playwright-core/src/server/progress.ts index 8e97ce83aa083..78d3298257238 100644 --- a/packages/playwright-core/src/server/progress.ts +++ b/packages/playwright-core/src/server/progress.ts @@ -62,14 +62,16 @@ export class ProgressController { }); } - async abort(error: Error) { + const logMessage = `operation was aborted: ${error.message}`; if (this._state === 'running') { + this.metadata.log.push(logMessage); (error as any)[kAbortErrorSymbol] = true; this._state = { error }; this._forceAbortPromise.reject(error); this._controller.abort(error); } else if (this._state === 'before') { + this.metadata.log.push(logMessage); (error as any)[kAbortErrorSymbol] = true; this._pendingAbortError = error; } diff --git a/tests/page/expect-timeout.spec.ts b/tests/page/expect-timeout.spec.ts index 6615cbbc46a89..6753716a1c25b 100644 --- a/tests/page/expect-timeout.spec.ts +++ b/tests/page/expect-timeout.spec.ts @@ -133,11 +133,12 @@ test('should fail like a timeout when the signal is aborted mid-assertion', asyn Locator: locator('span') Expected: visible -Error: The assertion was aborted: stop it +Error: element(s) not found Call log: - Expect "toBeVisible" with timeout 5000ms - - waiting for locator('span')`); + - waiting for locator('span') + - operation was aborted: stop it`); }); test('should fail like a timeout when toHaveText is aborted mid-assertion', async ({ page }) => { diff --git a/tests/page/page-click.spec.ts b/tests/page/page-click.spec.ts index 8649e738ac1e8..30416d9dd3a5b 100644 --- a/tests/page/page-click.spec.ts +++ b/tests/page/page-click.spec.ts @@ -1368,11 +1368,11 @@ it('should abort via signal', async ({ page }) => { // Give the action time to start and emit call log entries before aborting. await page.waitForTimeout(500); - const reason = new Error('Aborted by user'); + const reason = new Error('foo bar'); controller.abort(reason); const error = await promise; - expect(error.message).toContain('The operation was aborted'); - expect(error.message).toContain(`Call log:`); + expect(error.message).toContain('locator.click: foo bar'); + expect(error.message).toMatch(/Call log:[\s\S]*operation was aborted: foo bar/); expect(error.name).toBe('AbortError'); expect(error.cause).toBe(reason); }); @@ -1384,6 +1384,7 @@ it('should throw an Error when aborted in-flight with a string reason', async ({ controller.abort('aborted by user'); const error = await promise.catch(e => e); expect(error).toBeInstanceOf(Error); + expect(error.message).toContain('locator.click: aborted by user'); expect(error.name).toBe('AbortError'); expect(error.cause).toBe('aborted by user'); });