Skip to content

chore(protocol): make timeout a protocol-level field#41712

Open
Skn0tt wants to merge 4 commits into
mainfrom
skn0tt-protocol-timeout-field
Open

chore(protocol): make timeout a protocol-level field#41712
Skn0tt wants to merge 4 commits into
mainfrom
skn0tt-protocol-timeout-field

Conversation

@Skn0tt

@Skn0tt Skn0tt commented Jul 9, 2026

Copy link
Copy Markdown
Member

Follows #41141, which made signal a protocol-level field. This does the same for timeout: every message carries it on Metadata, computed once on the client and read from progress.timeout on the server, instead of each method declaring its own timeout: float.

Metadata:
  timeout: float  # 👈 0 means "no timeout"

0 is the sentinel for "no deadline", matching what ProgressController.run already does. It's required on sendMessageToServer so the 0 is spelled out where it's genuinely meant, rather than hidden behind a ?? 0.

Most of the diff is mechanical - spec deletions plus regenerated channels/validator, staged separately for review.

Follows #41141, which made signal a protocol-level field. This does the
same for timeout: every message carries it on Metadata, computed once on
the client and read from progress.timeout on the server, instead of each
method declaring its own timeout: float. 0 is the sentinel for no deadline.
@Skn0tt Skn0tt requested a review from dgozman July 9, 2026 14:31
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

…ut-field

# Conflicts:
#	packages/playwright-core/src/client/channels.d.ts
#	packages/playwright-core/src/server/channels.d.ts
#	packages/protocol/src/validator.ts
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Comment thread utils/generate_channels.js Outdated
addScheme(`${derived}${titleCase(methodName)}ErrorDetails`, `tType('${errorDetailsName}')`);
}
channels_ts.push(` ${methodName}(params: ${paramsName}, ${isDispatcher ? `progress: Progress` : `signal: AbortSignal | undefined`}): Promise<${resultName}>;`);
channels_ts.push(` ${methodName}(params: ${paramsName}, ${isDispatcher ? `progress: Progress` : `options?: CommandOptions`}): Promise<${resultName}>;`);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are options now optional? Let's make them mandatory (like we had with the signal), so every caller thinks about it?


async uncheck(options: channels.ElementHandleUncheckOptions & TimeoutOptions = {}) {
return await this._elementChannel.uncheck({ ...options, timeout: this._frame._timeout(options) }, options.signal);
return await this._elementChannel.uncheck({ ...options }, { signal: options.signal, timeout: this._frame._timeout(options) });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make all the helper methods like this._frame._timeout(options) handle both timeout and signal - this way the code will be much easier everywhere.

Comment thread utils/generate_channels.js Outdated
export type { Binary, Channel, ${structNames.join(', ')} } from '@protocol/structs';
`];
` + (target === 'Dispatcher' ? '' : `
export type CommandOptions = { signal?: AbortSignal, timeout?: number };

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make both properties required: { signal: AbortSignal | undefined, timeout: number } to ensure all callers doing the right thing?

Make signal and timeout required fields on the generated CommandOptions
struct, and pass them explicitly at every channel call site. Internal
calls that opt out of a deadline use timeout: 0 as the disabled sentinel.
@github-actions

Copy link
Copy Markdown
Contributor

Test results for "MCP"

2 failed
❌ [chrome] › mcp/annotate.spec.ts:57 › should capture multiple screenshots in one annotation @mcp-windows-latest-chrome
❌ [chromium] › mcp/annotate.spec.ts:110 › should abort annotation when last screenshot is removed @mcp-ubuntu-latest-chromium

7758 passed, 1249 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

Test results for "tests 1"

3 flaky ⚠️ [chromium-library] › library/popup.spec.ts:260 › should not throw when click closes popup `@chromium-ubuntu-22.04-arm-node20`
⚠️ [chromium-library] › library/video.spec.ts:717 › screencast › should work with video+trace `@chromium-ubuntu-22.04-arm-node20`
⚠️ [firefox-library] › library/inspector/cli-codegen-3.spec.ts:259 › cli codegen › should generate frame locators (4) `@firefox-ubuntu-22.04-node20`

49521 passed, 1161 skipped


Merge workflow run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants