You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Feature]: Add arbitrary annotations to test steps #42387
Similar to how TestInfo provides an annotations property that can be accessed and pushed to, do the same for TestStepInfo so this also applies to individual test steps. (TestInfo already returns these properties for steps, but the TypeScript compiler presumes they don't exist. There may also be discrepancies in what is sent to Playwright reports.)
Example
In order to satisfy the TypeScript compiler, the following declaration file is currently required (a PR would make this redundant):
import{test}from'declarationFile';test.describe('Annotated test suite',{},()=>{test('Annotated test case',async({},testInfo)=>{testInfo.annotations.push({type: 'summary',description: 'This annotation will appear at the test case level.',});awaittest.step('Annotated test step',async(stepInfo)=>{stepInfo.annotations.push({type: 'expected-result',description: 'Step passes with no errors.',});});});});
Motivation
Some enterprise-grade automation database solutions expect that each step in a test case has an associated "expected result", which is essentially a second title. Explicitly adding annotations to TestStepInfo will ensure that this, but also any other metadata about an individual step can be documented and handled using fixtures and hooks etc.
Hi, I'm the Playwright bot and I took a first look at this.
The runtime already supports this — TestStepInfo carries a live annotations array, and stepInfo.annotations.push(...) flows all the way through to the reporters and trace. What's missing is only the public TypeScript type and the docs, so the compiler doesn't know the property exists (hence your declare module workaround). So this is a valid, well-scoped request: expose an already-implemented property rather than build anything new.
Where I see it in the source (tip-of-tree, 1.63.0-next)
TestStepInfoImpl already has annotations: TestAnnotation[] and pushes to it — packages/playwright/src/worker/testInfo.ts:674 (also used for step.skip).
Step end ships those annotations to reporters: annotations: step.info.annotations in the StepEndPayload — testInfo.ts:358 — and into the trace via appendAfterActionForStep(..., step.info.annotations) (testInfo.ts:365).
The gap: the TestStepInfo interface in packages/playwright/types/test.d.ts doesn't declare annotations, and there's no entry in docs/src/test-api/class-teststepinfo.md. The type is generated from the docs, so documenting the property is what closes the loop.
So your example works today at runtime — the annotation reaches the report; it just doesn't type-check without the shim. The change here would be documenting annotations on TestStepInfo (in docs/src/api/), which regenerates the type and makes the workaround redundant.
One open design question for the maintainers: whether step-level annotations should also roll up into testInfo.annotations / the test-case annotations, or stay attached only to the step. Today they stay on the step.
Activity
github-actions commentedon Aug 25, 2026
Hi, I'm the Playwright bot and I took a first look at this.
The runtime already supports this —
TestStepInfocarries a liveannotationsarray, andstepInfo.annotations.push(...)flows all the way through to the reporters and trace. What's missing is only the public TypeScript type and the docs, so the compiler doesn't know the property exists (hence yourdeclare moduleworkaround). So this is a valid, well-scoped request: expose an already-implemented property rather than build anything new.Where I see it in the source (tip-of-tree, 1.63.0-next)
TestStepInfoImplalready hasannotations: TestAnnotation[]and pushes to it —packages/playwright/src/worker/testInfo.ts:674(also used forstep.skip).annotations: step.info.annotationsin theStepEndPayload—testInfo.ts:358— and into the trace viaappendAfterActionForStep(..., step.info.annotations)(testInfo.ts:365).step.annotations:teleEmitter.ts:332,chromeTrace.ts:218,merge.ts:552,html.ts:666.TestStepInfointerface inpackages/playwright/types/test.d.tsdoesn't declareannotations, and there's no entry indocs/src/test-api/class-teststepinfo.md. The type is generated from the docs, so documenting the property is what closes the loop.So your example works today at runtime — the annotation reaches the report; it just doesn't type-check without the shim. The change here would be documenting
annotationsonTestStepInfo(indocs/src/api/), which regenerates the type and makes the workaround redundant.One open design question for the maintainers: whether step-level annotations should also roll up into
testInfo.annotations/ the test-case annotations, or stay attached only to the step. Today they stay on the step.Triaged by the Playwright bot - agent run