A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/microsoft/playwright/commit/4b64c47a251e11e6634ef7265ea4d13ebf1f6df6 below:

use explicit matcher call context (#34620) · microsoft/playwright@4b64c47 · GitHub

@@ -110,13 +110,13 @@ function createMatchers(actual: unknown, info: ExpectMetaInfo, prefix: string[])

110 110

return new Proxy(expectLibrary(actual), new ExpectMetaInfoProxyHandler(info, prefix));

111 111

}

112 112 113 -

const getCustomMatchersSymbol = Symbol('get custom matchers');

113 +

const userMatchersSymbol = Symbol('userMatchers');

114 114 115 115

function qualifiedMatcherName(qualifier: string[], matcherName: string) {

116 116

return qualifier.join(':') + '$' + matcherName;

117 117

}

118 118 119 -

function createExpect(info: ExpectMetaInfo, prefix: string[], customMatchers: Record<string, Function>) {

119 +

function createExpect(info: ExpectMetaInfo, prefix: string[], userMatchers: Record<string, Function>) {

120 120

const expectInstance: Expect<{}> = new Proxy(expectLibrary, {

121 121

apply: function(target: any, thisArg: any, argumentsList: [unknown, ExpectMessage?]) {

122 122

const [actual, messageOrOptions] = argumentsList;

@@ -130,7 +130,7 @@ function createExpect(info: ExpectMetaInfo, prefix: string[], customMatchers: Re

130 130

return createMatchers(actual, newInfo, prefix);

131 131

},

132 132 133 -

get: function(target: any, property: string | typeof getCustomMatchersSymbol) {

133 +

get: function(target: any, property: string | typeof userMatchersSymbol) {

134 134

if (property === 'configure')

135 135

return configure;

136 136

@@ -139,27 +139,14 @@ function createExpect(info: ExpectMetaInfo, prefix: string[], customMatchers: Re

139 139

const qualifier = [...prefix, createGuid()];

140 140 141 141

const wrappedMatchers: any = {};

142 -

const extendedMatchers: any = { ...customMatchers };

143 142

for (const [name, matcher] of Object.entries(matchers)) {

144 -

wrappedMatchers[name] = function(...args: any[]) {

145 -

const { isNot, promise, utils } = this;

146 -

const newThis: ExpectMatcherState = {

147 -

isNot,

148 -

promise,

149 -

utils,

150 -

timeout: currentExpectTimeout()

151 -

};

152 -

(newThis as any).equals = throwUnsupportedExpectMatcherError;

153 -

return (matcher as any).call(newThis, ...args);

154 -

};

143 +

wrappedMatchers[name] = wrapPlaywrightMatcherToPassNiceThis(matcher);

155 144

const key = qualifiedMatcherName(qualifier, name);

156 145

wrappedMatchers[key] = wrappedMatchers[name];

157 146

Object.defineProperty(wrappedMatchers[key], 'name', { value: name });

158 -

extendedMatchers[name] = wrappedMatchers[key];

159 147

}

160 148

expectLibrary.extend(wrappedMatchers);

161 - 162 -

return createExpect(info, qualifier, extendedMatchers);

149 +

return createExpect(info, qualifier, { ...userMatchers, ...matchers });

163 150

};

164 151

}

165 152

@@ -169,8 +156,8 @@ function createExpect(info: ExpectMetaInfo, prefix: string[], customMatchers: Re

169 156

};

170 157

}

171 158 172 -

if (property === getCustomMatchersSymbol)

173 -

return customMatchers;

159 +

if (property === userMatchersSymbol)

160 +

return userMatchers;

174 161 175 162

if (property === 'poll') {

176 163

return (actual: unknown, messageOrOptions?: ExpectMessage & { timeout?: number, intervals?: number[] }) => {

@@ -197,12 +184,56 @@ function createExpect(info: ExpectMetaInfo, prefix: string[], customMatchers: Re

197 184

newInfo.poll!.intervals = configuration._poll.intervals ?? newInfo.poll!.intervals;

198 185

}

199 186

}

200 -

return createExpect(newInfo, prefix, customMatchers);

187 +

return createExpect(newInfo, prefix, userMatchers);

201 188

};

202 189 203 190

return expectInstance;

204 191

}

205 192 193 +

// Expect wraps matchers, so there is no way to pass this information to the raw Playwright matcher.

194 +

// Rely on sync call sequence to seed each matcher call with the context.

195 +

type MatcherCallContext = {

196 +

expectInfo: ExpectMetaInfo;

197 +

testInfo: TestInfoImpl | null;

198 +

};

199 + 200 +

let matcherCallContext: MatcherCallContext | undefined;

201 + 202 +

function setMatcherCallContext(context: MatcherCallContext) {

203 +

matcherCallContext = context;

204 +

}

205 + 206 +

function takeMatcherCallContext(): MatcherCallContext {

207 +

try {

208 +

return matcherCallContext!;

209 +

} finally {

210 +

matcherCallContext = undefined;

211 +

}

212 +

}

213 + 214 +

type ExpectMatcherStateInternal = ExpectMatcherState & {

215 +

_context: MatcherCallContext | undefined;

216 +

};

217 + 218 +

const defaultExpectTimeout = 5000;

219 + 220 +

function wrapPlaywrightMatcherToPassNiceThis(matcher: any) {

221 +

return function(this: any, ...args: any[]) {

222 +

const { isNot, promise, utils } = this;

223 +

const context = takeMatcherCallContext();

224 +

const timeout = context.expectInfo.timeout ?? context.testInfo?._projectInternal?.expect?.timeout ?? defaultExpectTimeout;

225 +

const newThis: ExpectMatcherStateInternal = {

226 +

isNot,

227 +

promise,

228 +

utils,

229 +

timeout,

230 +

_context: context,

231 +

};

232 +

(newThis as any).equals = throwUnsupportedExpectMatcherError;

233 +

return matcher.call(newThis, ...args);

234 +

};

235 +

}

236 + 206 237

function throwUnsupportedExpectMatcherError() {

207 238

throw new Error('It looks like you are using custom expect matchers that are not compatible with Playwright. See https://aka.ms/playwright/expect-compatibility');

208 239

}

@@ -299,8 +330,7 @@ class ExpectMetaInfoProxyHandler implements ProxyHandler<any> {

299 330

}

300 331

return (...args: any[]) => {

301 332

const testInfo = currentTestInfo();

302 -

// We assume that the matcher will read the current expect timeout the first thing.

303 -

setCurrentExpectConfigureTimeout(this._info.timeout);

333 +

setMatcherCallContext({ expectInfo: this._info, testInfo });

304 334

if (!testInfo)

305 335

return matcher.call(target, ...args);

306 336

@@ -362,7 +392,7 @@ class ExpectMetaInfoProxyHandler implements ProxyHandler<any> {

362 392

async function pollMatcher(qualifiedMatcherName: string, info: ExpectMetaInfo, prefix: string[], ...args: any[]) {

363 393

const testInfo = currentTestInfo();

364 394

const poll = info.poll!;

365 -

const timeout = poll.timeout ?? currentExpectTimeout();

395 +

const timeout = poll.timeout ?? info.timeout ?? testInfo?._projectInternal?.expect?.timeout ?? defaultExpectTimeout;

366 396

const { deadline, timeoutMessage } = testInfo ? testInfo._deadlineForMatcher(timeout) : TestInfoImpl._defaultDeadlineForMatcher(timeout);

367 397 368 398

const result = await pollAgainstDeadline<Error|undefined>(async () => {

@@ -398,22 +428,6 @@ async function pollMatcher(qualifiedMatcherName: string, info: ExpectMetaInfo, p

398 428

}

399 429

}

400 430 401 -

let currentExpectConfigureTimeout: number | undefined;

402 - 403 -

function setCurrentExpectConfigureTimeout(timeout: number | undefined) {

404 -

currentExpectConfigureTimeout = timeout;

405 -

}

406 - 407 -

function currentExpectTimeout() {

408 -

if (currentExpectConfigureTimeout !== undefined)

409 -

return currentExpectConfigureTimeout;

410 -

const testInfo = currentTestInfo();

411 -

let defaultExpectTimeout = testInfo?._projectInternal?.expect?.timeout;

412 -

if (typeof defaultExpectTimeout === 'undefined')

413 -

defaultExpectTimeout = 5000;

414 -

return defaultExpectTimeout;

415 -

}

416 - 417 431

function computeArgsSuffix(matcherName: string, args: any[]) {

418 432

let value = '';

419 433

if (matcherName === 'toHaveScreenshot')

@@ -426,7 +440,7 @@ export const expect: Expect<{}> = createExpect({}, [], {}).extend(customMatchers

426 440

export function mergeExpects(...expects: any[]) {

427 441

let merged = expect;

428 442

for (const e of expects) {

429 -

const internals = e[getCustomMatchersSymbol];

443 +

const internals = e[userMatchersSymbol];

430 444

if (!internals) // non-playwright expects mutate the global expect, so we don't need to do anything special

431 445

continue;

432 446

merged = merged.extend(internals);


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4