@@ -25,6 +25,7 @@ import {
2525import { ExpectError , isJestError } from './matcherHint' ;
2626import {
2727 computeMatcherTitleSuffix ,
28+ defaultDeadlineForMatcher ,
2829 toBeAttached ,
2930 toBeChecked ,
3031 toBeDisabled ,
@@ -60,13 +61,47 @@ import { toHaveScreenshot, toMatchSnapshot } from './toMatchSnapshot';
6061import {
6162 expect as expectLibrary ,
6263} from '../common/expectBundle' ;
63- import { currentTestInfo } from '../common/globals' ;
6464import { filteredStackTrace } from '../util' ;
65- import { TestInfoImpl } from '../worker/testInfo' ;
6665
6766import type { ExpectMatcherStateInternal } from './matchers' ;
6867import type { Expect } from '../../types/test' ;
69- import type { TestStepInfoImpl } from '../worker/testInfo' ;
68+ import type { TestInfoImpl , TestStepInfoImpl } from '../worker/testInfo' ;
69+
70+ export type ExpectConfig = {
71+ testInfo ?: TestInfoImpl ;
72+ timeout ?: number ;
73+ toHaveScreenshot ?: {
74+ threshold ?: number ;
75+ maxDiffPixels ?: number ;
76+ maxDiffPixelRatio ?: number ;
77+ animations ?: 'allow' | 'disabled' ;
78+ caret ?: 'hide' | 'initial' ;
79+ scale ?: 'css' | 'device' ;
80+ stylePath ?: string | Array < string > ;
81+ pathTemplate ?: string ;
82+ } ;
83+ toMatchAriaSnapshot ?: {
84+ pathTemplate ?: string ;
85+ children ?: 'contain' | 'equal' | 'deep-equal' ;
86+ } ;
87+ toMatchSnapshot ?: {
88+ threshold ?: number ;
89+ maxDiffPixels ?: number ;
90+ maxDiffPixelRatio ?: number ;
91+ } ;
92+ toPass ?: {
93+ timeout ?: number ;
94+ intervals ?: Array < number > ;
95+ } ;
96+ } ;
97+
98+ let currentConfig : ExpectConfig = { } ;
99+ export function setExpectConfig ( config : ExpectConfig ) {
100+ currentConfig = config ;
101+ }
102+ export function expectConfig ( ) : ExpectConfig {
103+ return currentConfig ;
104+ }
70105
71106type ExpectMessage = string | { message ?: string } ;
72107
@@ -158,7 +193,6 @@ function createExpect(info: ExpectMetaInfo, prefix: string[], userMatchers: Reco
158193// Rely on sync call sequence to seed each matcher call with the context.
159194type MatcherCallContext = {
160195 expectInfo : ExpectMetaInfo ;
161- testInfo : TestInfoImpl | null ;
162196 step ?: TestStepInfoImpl ;
163197} ;
164198
@@ -184,7 +218,7 @@ function wrapPlaywrightMatcherToPassNiceThis(matcher: any) {
184218 return function ( this : any , ...args : any [ ] ) {
185219 const { isNot, promise, utils } = this ;
186220 const context = takeMatcherCallContext ( ) ;
187- const timeout = context ?. expectInfo . timeout ?? context ?. testInfo ?. _projectInternal ?. expect ? .timeout ?? defaultExpectTimeout ;
221+ const timeout = context ?. expectInfo . timeout ?? expectConfig ( ) . timeout ?? defaultExpectTimeout ;
188222 const newThis : ExpectMatcherStateInternal = {
189223 isNot,
190224 promise,
@@ -297,8 +331,8 @@ class ExpectMetaInfoProxyHandler implements ProxyHandler<any> {
297331 matcher = ( ...args : any [ ] ) => pollMatcher ( resolvedMatcherName , this . _info , this . _prefix , ...args ) ;
298332 }
299333 return ( ...args : any [ ] ) => {
300- const testInfo = currentTestInfo ( ) ;
301- setMatcherCallContext ( { expectInfo : this . _info , testInfo } ) ;
334+ const testInfo = expectConfig ( ) . testInfo ;
335+ setMatcherCallContext ( { expectInfo : this . _info } ) ;
302336 if ( ! testInfo )
303337 return matcher . call ( target , ...args ) ;
304338
@@ -350,7 +384,7 @@ class ExpectMetaInfoProxyHandler implements ProxyHandler<any> {
350384 } ;
351385
352386 try {
353- setMatcherCallContext ( { expectInfo : this . _info , testInfo , step : step . info } ) ;
387+ setMatcherCallContext ( { expectInfo : this . _info , step : step . info } ) ;
354388 const callback = ( ) => matcher . call ( target , ...args ) ;
355389 const result = currentZone ( ) . with ( 'stepZone' , step ) . run ( callback ) ;
356390 if ( result instanceof Promise )
@@ -365,13 +399,13 @@ class ExpectMetaInfoProxyHandler implements ProxyHandler<any> {
365399}
366400
367401async function pollMatcher ( qualifiedMatcherName : string , info : ExpectMetaInfo , prefix : string [ ] , ...args : any [ ] ) {
368- const testInfo = currentTestInfo ( ) ;
402+ const config = expectConfig ( ) ;
369403 const poll = info . poll ! ;
370- const timeout = poll . timeout ?? info . timeout ?? testInfo ?. _projectInternal ?. expect ? .timeout ?? defaultExpectTimeout ;
371- const { deadline, timeoutMessage } = testInfo ? testInfo . _deadlineForMatcher ( timeout ) : TestInfoImpl . _defaultDeadlineForMatcher ( timeout ) ;
404+ const timeout = poll . timeout ?? info . timeout ?? config . timeout ?? defaultExpectTimeout ;
405+ const { deadline, timeoutMessage } = config . testInfo ? config . testInfo . _deadlineForMatcher ( timeout ) : defaultDeadlineForMatcher ( timeout ) ;
372406
373407 const result = await pollAgainstDeadline < Error | undefined > ( async ( ) => {
374- if ( testInfo && currentTestInfo ( ) !== testInfo )
408+ if ( config && expectConfig ( ) !== config )
375409 return { continuePolling : false , result : undefined } ;
376410
377411 const innerInfo : ExpectMetaInfo = {
0 commit comments