@playwright/test 1.31.2 → 1.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/lib/cli.js +12 -34
  2. package/lib/common/compilationCache.js +4 -2
  3. package/lib/common/configLoader.js +4 -1
  4. package/lib/common/fixtures.js +31 -2
  5. package/lib/common/globals.js +9 -0
  6. package/lib/common/process.js +15 -3
  7. package/lib/common/testType.js +2 -1
  8. package/lib/common/transform.js +0 -1
  9. package/lib/index.js +95 -56
  10. package/lib/isomorphic/folders.js +25 -0
  11. package/lib/isomorphic/teleReceiver.js +368 -0
  12. package/lib/matchers/expect.js +35 -16
  13. package/lib/matchers/matchers.js +48 -48
  14. package/lib/matchers/toBeTruthy.js +1 -1
  15. package/lib/matchers/toEqual.js +1 -4
  16. package/lib/matchers/toMatchSnapshot.js +3 -4
  17. package/lib/matchers/toMatchText.js +1 -1
  18. package/lib/plugins/vitePlugin.js +3 -2
  19. package/lib/reporters/base.js +6 -9
  20. package/lib/reporters/html.js +7 -2
  21. package/lib/reporters/json.js +2 -2
  22. package/lib/reporters/junit.js +2 -2
  23. package/lib/reporters/teleEmitter.js +209 -0
  24. package/lib/runner/dispatcher.js +15 -2
  25. package/lib/runner/loadUtils.js +168 -96
  26. package/lib/runner/loaderHost.js +2 -2
  27. package/lib/runner/processHost.js +16 -4
  28. package/lib/runner/reporters.js +3 -2
  29. package/lib/runner/runner.js +9 -1
  30. package/lib/runner/taskRunner.js +6 -8
  31. package/lib/runner/tasks.js +55 -46
  32. package/lib/runner/testGroups.js +15 -10
  33. package/lib/runner/uiMode.js +279 -0
  34. package/lib/runner/workerHost.js +7 -6
  35. package/lib/store.js +99 -0
  36. package/lib/util.js +23 -39
  37. package/lib/worker/fixtureRunner.js +3 -3
  38. package/lib/worker/testInfo.js +8 -3
  39. package/lib/worker/timeoutManager.js +11 -5
  40. package/lib/worker/workerMain.js +6 -3
  41. package/package.json +2 -2
  42. package/types/component.d.ts +1 -1
  43. package/types/reporterPrivate.ts +22 -0
  44. package/types/test.d.ts +18 -22
  45. package/types/testReporter.d.ts +5 -1
  46. package/lib/common/profiler.js +0 -53
@@ -0,0 +1,368 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.baseFullConfig = exports.TeleTestCase = exports.TeleSuite = exports.TeleReporterReceiver = void 0;
7
+ exports.parseRegexPatterns = parseRegexPatterns;
8
+ exports.serializeRegexPatterns = serializeRegexPatterns;
9
+ /**
10
+ * Copyright (c) Microsoft Corporation.
11
+ *
12
+ * Licensed under the Apache License, Version 2.0 (the "License");
13
+ * you may not use this file except in compliance with the License.
14
+ * You may obtain a copy of the License at
15
+ *
16
+ * http://www.apache.org/licenses/LICENSE-2.0
17
+ *
18
+ * Unless required by applicable law or agreed to in writing, software
19
+ * distributed under the License is distributed on an "AS IS" BASIS,
20
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
+ * See the License for the specific language governing permissions and
22
+ * limitations under the License.
23
+ */
24
+
25
+ class TeleReporterReceiver {
26
+ constructor(reporter) {
27
+ this._rootSuite = void 0;
28
+ this._reporter = void 0;
29
+ this._tests = new Map();
30
+ this._rootSuite = new TeleSuite('', 'root');
31
+ this._reporter = reporter;
32
+ }
33
+ dispatch(message) {
34
+ const {
35
+ method,
36
+ params
37
+ } = message;
38
+ if (method === 'onBegin') {
39
+ this._onBegin(params.config, params.projects);
40
+ return;
41
+ }
42
+ if (method === 'onTestBegin') {
43
+ this._onTestBegin(params.testId, params.result);
44
+ return;
45
+ }
46
+ if (method === 'onTestEnd') {
47
+ this._onTestEnd(params.testId, params.result);
48
+ return;
49
+ }
50
+ if (method === 'onStepBegin') {
51
+ this._onStepBegin(params.testId, params.resultId, params.step);
52
+ return;
53
+ }
54
+ if (method === 'onStepEnd') {
55
+ this._onStepEnd(params.testId, params.resultId, params.step);
56
+ return;
57
+ }
58
+ if (method === 'onError') {
59
+ this._onError(params.error);
60
+ return;
61
+ }
62
+ if (method === 'onStdIO') {
63
+ this._onStdIO(params.type, params.testId, params.resultId, params.data, params.isBase64);
64
+ return;
65
+ }
66
+ if (method === 'onEnd') {
67
+ this._onEnd(params.result);
68
+ return;
69
+ }
70
+ }
71
+ _onBegin(config, projects) {
72
+ var _this$_reporter$onBeg, _this$_reporter;
73
+ const removeMissing = config.listOnly;
74
+ for (const project of projects) {
75
+ let projectSuite = this._rootSuite.suites.find(suite => suite.project().id === project.id);
76
+ if (!projectSuite) {
77
+ projectSuite = new TeleSuite(project.name, 'project');
78
+ this._rootSuite.suites.push(projectSuite);
79
+ projectSuite.parent = this._rootSuite;
80
+ }
81
+ const p = this._parseProject(project);
82
+ projectSuite.project = () => p;
83
+ this._mergeSuitesInto(project.suites, projectSuite, removeMissing);
84
+ }
85
+ (_this$_reporter$onBeg = (_this$_reporter = this._reporter).onBegin) === null || _this$_reporter$onBeg === void 0 ? void 0 : _this$_reporter$onBeg.call(_this$_reporter, this._parseConfig(config), this._rootSuite);
86
+ }
87
+ _onTestBegin(testId, payload) {
88
+ var _this$_reporter$onTes, _this$_reporter2;
89
+ const test = this._tests.get(testId);
90
+ const testResult = test._createTestResult(payload.id);
91
+ testResult.retry = payload.retry;
92
+ testResult.workerIndex = payload.workerIndex;
93
+ testResult.parallelIndex = payload.parallelIndex;
94
+ testResult.startTime = new Date(payload.startTime);
95
+ (_this$_reporter$onTes = (_this$_reporter2 = this._reporter).onTestBegin) === null || _this$_reporter$onTes === void 0 ? void 0 : _this$_reporter$onTes.call(_this$_reporter2, test, testResult);
96
+ }
97
+ _onTestEnd(testId, payload) {
98
+ var _this$_reporter$onTes2, _this$_reporter3;
99
+ const test = this._tests.get(testId);
100
+ const result = test.resultsMap.get(payload.id);
101
+ result.duration = payload.duration;
102
+ result.status = payload.status;
103
+ result.errors = payload.errors;
104
+ result.attachments = payload.attachments;
105
+ (_this$_reporter$onTes2 = (_this$_reporter3 = this._reporter).onTestEnd) === null || _this$_reporter$onTes2 === void 0 ? void 0 : _this$_reporter$onTes2.call(_this$_reporter3, test, result);
106
+ }
107
+ _onStepBegin(testId, resultId, payload) {
108
+ var _this$_reporter$onSte, _this$_reporter4;
109
+ const test = this._tests.get(testId);
110
+ const result = test.resultsMap.get(resultId);
111
+ const step = {
112
+ titlePath: () => [],
113
+ title: payload.title,
114
+ category: payload.category,
115
+ location: payload.location,
116
+ startTime: new Date(payload.startTime),
117
+ duration: 0,
118
+ steps: []
119
+ };
120
+ // TODO: implement nested steps.
121
+ result.stepMap.set(payload.id, step);
122
+ result.stepStack[result.stepStack.length - 1].steps.push(step);
123
+ result.stepStack.push(step);
124
+ (_this$_reporter$onSte = (_this$_reporter4 = this._reporter).onStepBegin) === null || _this$_reporter$onSte === void 0 ? void 0 : _this$_reporter$onSte.call(_this$_reporter4, test, result, step);
125
+ }
126
+ _onStepEnd(testId, resultId, payload) {
127
+ var _this$_reporter$onSte2, _this$_reporter5;
128
+ const test = this._tests.get(testId);
129
+ const result = test.resultsMap.get(resultId);
130
+ const step = result.stepMap.get(payload.id);
131
+ const i = result.stepStack.indexOf(step);
132
+ if (i !== -1) result.stepStack.splice(i, 1);
133
+ step.duration = payload.duration;
134
+ step.error = payload.error;
135
+ (_this$_reporter$onSte2 = (_this$_reporter5 = this._reporter).onStepEnd) === null || _this$_reporter$onSte2 === void 0 ? void 0 : _this$_reporter$onSte2.call(_this$_reporter5, test, result, step);
136
+ }
137
+ _onError(error) {
138
+ var _this$_reporter$onErr, _this$_reporter6;
139
+ (_this$_reporter$onErr = (_this$_reporter6 = this._reporter).onError) === null || _this$_reporter$onErr === void 0 ? void 0 : _this$_reporter$onErr.call(_this$_reporter6, error);
140
+ }
141
+ _onStdIO(type, testId, resultId, data, isBase64) {
142
+ var _this$_reporter$onStd, _this$_reporter7, _this$_reporter$onStd2, _this$_reporter8;
143
+ const chunk = isBase64 ? Buffer.from(data, 'base64') : data;
144
+ const test = testId ? this._tests.get(testId) : undefined;
145
+ const result = test && resultId ? test.resultsMap.get(resultId) : undefined;
146
+ if (type === 'stdout') (_this$_reporter$onStd = (_this$_reporter7 = this._reporter).onStdOut) === null || _this$_reporter$onStd === void 0 ? void 0 : _this$_reporter$onStd.call(_this$_reporter7, chunk, test, result);else (_this$_reporter$onStd2 = (_this$_reporter8 = this._reporter).onStdErr) === null || _this$_reporter$onStd2 === void 0 ? void 0 : _this$_reporter$onStd2.call(_this$_reporter8, chunk, test, result);
147
+ }
148
+ _onEnd(result) {
149
+ var _this$_reporter$onEnd, _this$_reporter9;
150
+ (_this$_reporter$onEnd = (_this$_reporter9 = this._reporter).onEnd) === null || _this$_reporter$onEnd === void 0 ? void 0 : _this$_reporter$onEnd.call(_this$_reporter9, result);
151
+ }
152
+ _parseConfig(config) {
153
+ const fullConfig = baseFullConfig;
154
+ fullConfig.rootDir = config.rootDir;
155
+ fullConfig.configFile = config.configFile;
156
+ return fullConfig;
157
+ }
158
+ _parseProject(project) {
159
+ return {
160
+ id: project.id,
161
+ metadata: project.metadata,
162
+ name: project.name,
163
+ outputDir: project.outputDir,
164
+ repeatEach: project.repeatEach,
165
+ retries: project.retries,
166
+ testDir: project.testDir,
167
+ testIgnore: parseRegexPatterns(project.testIgnore),
168
+ testMatch: parseRegexPatterns(project.testMatch),
169
+ timeout: project.timeout,
170
+ grep: parseRegexPatterns(project.grep),
171
+ grepInvert: parseRegexPatterns(project.grepInvert),
172
+ dependencies: project.dependencies,
173
+ snapshotDir: project.snapshotDir,
174
+ use: {}
175
+ };
176
+ }
177
+ _mergeSuitesInto(jsonSuites, parent, removeMissing) {
178
+ for (const jsonSuite of jsonSuites) {
179
+ let targetSuite = parent.suites.find(s => s.title === jsonSuite.title);
180
+ if (!targetSuite) {
181
+ targetSuite = new TeleSuite(jsonSuite.title, jsonSuite.type);
182
+ targetSuite.parent = parent;
183
+ parent.suites.push(targetSuite);
184
+ }
185
+ targetSuite.location = jsonSuite.location;
186
+ targetSuite._fileId = jsonSuite.fileId;
187
+ targetSuite._parallelMode = jsonSuite.parallelMode;
188
+ this._mergeSuitesInto(jsonSuite.suites, targetSuite, removeMissing);
189
+ this._mergeTestsInto(jsonSuite.tests, targetSuite, removeMissing);
190
+ }
191
+ if (removeMissing) {
192
+ const suiteMap = new Map(parent.suites.map(p => [p.title, p]));
193
+ parent.suites = jsonSuites.map(s => suiteMap.get(s.title)).filter(Boolean);
194
+ }
195
+ }
196
+ _mergeTestsInto(jsonTests, parent, removeMissing) {
197
+ for (const jsonTest of jsonTests) {
198
+ let targetTest = parent.tests.find(s => s.title === jsonTest.title);
199
+ if (!targetTest) {
200
+ targetTest = new TeleTestCase(jsonTest.testId, jsonTest.title, jsonTest.location);
201
+ targetTest.parent = parent;
202
+ parent.tests.push(targetTest);
203
+ this._tests.set(targetTest.id, targetTest);
204
+ }
205
+ this._updateTest(jsonTest, targetTest);
206
+ }
207
+ if (removeMissing) {
208
+ const testMap = new Map(parent.tests.map(p => [p.title, p]));
209
+ parent.tests = jsonTests.map(s => testMap.get(s.title)).filter(Boolean);
210
+ }
211
+ }
212
+ _updateTest(payload, test) {
213
+ test.id = payload.testId;
214
+ test.expectedStatus = payload.expectedStatus;
215
+ test.timeout = payload.timeout;
216
+ test.location = payload.location;
217
+ test.annotations = payload.annotations;
218
+ test.retries = payload.retries;
219
+ return test;
220
+ }
221
+ }
222
+ exports.TeleReporterReceiver = TeleReporterReceiver;
223
+ class TeleSuite {
224
+ constructor(title, type) {
225
+ this.title = void 0;
226
+ this.location = void 0;
227
+ this.parent = void 0;
228
+ this._requireFile = '';
229
+ this.suites = [];
230
+ this.tests = [];
231
+ this._timeout = void 0;
232
+ this._retries = void 0;
233
+ this._fileId = void 0;
234
+ this._parallelMode = 'default';
235
+ this._type = void 0;
236
+ this.title = title;
237
+ this._type = type;
238
+ }
239
+ allTests() {
240
+ const result = [];
241
+ const visit = suite => {
242
+ for (const entry of [...suite.suites, ...suite.tests]) {
243
+ if (entry instanceof TeleSuite) visit(entry);else result.push(entry);
244
+ }
245
+ };
246
+ visit(this);
247
+ return result;
248
+ }
249
+ titlePath() {
250
+ const titlePath = this.parent ? this.parent.titlePath() : [];
251
+ // Ignore anonymous describe blocks.
252
+ if (this.title || this._type !== 'describe') titlePath.push(this.title);
253
+ return titlePath;
254
+ }
255
+ project() {
256
+ return undefined;
257
+ }
258
+ }
259
+ exports.TeleSuite = TeleSuite;
260
+ class TeleTestCase {
261
+ constructor(id, title, location) {
262
+ this.title = void 0;
263
+ this.fn = () => {};
264
+ this.results = [];
265
+ this.location = void 0;
266
+ this.parent = void 0;
267
+ this.expectedStatus = 'passed';
268
+ this.timeout = 0;
269
+ this.annotations = [];
270
+ this.retries = 0;
271
+ this.repeatEachIndex = 0;
272
+ this.id = void 0;
273
+ this.resultsMap = new Map();
274
+ this.id = id;
275
+ this.title = title;
276
+ this.location = location;
277
+ }
278
+ titlePath() {
279
+ const titlePath = this.parent ? this.parent.titlePath() : [];
280
+ titlePath.push(this.title);
281
+ return titlePath;
282
+ }
283
+ outcome() {
284
+ const nonSkipped = this.results.filter(result => result.status !== 'skipped' && result.status !== 'interrupted');
285
+ if (!nonSkipped.length) return 'skipped';
286
+ if (nonSkipped.every(result => result.status === this.expectedStatus)) return 'expected';
287
+ if (nonSkipped.some(result => result.status === this.expectedStatus)) return 'flaky';
288
+ return 'unexpected';
289
+ }
290
+ ok() {
291
+ const status = this.outcome();
292
+ return status === 'expected' || status === 'flaky' || status === 'skipped';
293
+ }
294
+ _clearResults() {
295
+ this.results = [];
296
+ this.resultsMap.clear();
297
+ }
298
+ _createTestResult(id) {
299
+ this._clearResults();
300
+ const result = {
301
+ retry: this.results.length,
302
+ parallelIndex: -1,
303
+ workerIndex: -1,
304
+ duration: -1,
305
+ startTime: new Date(),
306
+ stdout: [],
307
+ stderr: [],
308
+ attachments: [],
309
+ status: 'skipped',
310
+ steps: [],
311
+ errors: [],
312
+ stepMap: new Map(),
313
+ stepStack: []
314
+ };
315
+ result.stepStack.push(result);
316
+ this.results.push(result);
317
+ this.resultsMap.set(id, result);
318
+ return result;
319
+ }
320
+ }
321
+ exports.TeleTestCase = TeleTestCase;
322
+ const baseFullConfig = {
323
+ forbidOnly: false,
324
+ fullyParallel: false,
325
+ globalSetup: null,
326
+ globalTeardown: null,
327
+ globalTimeout: 0,
328
+ grep: /.*/,
329
+ grepInvert: null,
330
+ maxFailures: 0,
331
+ metadata: {},
332
+ preserveOutput: 'always',
333
+ projects: [],
334
+ reporter: [[process.env.CI ? 'dot' : 'list']],
335
+ reportSlowTests: {
336
+ max: 5,
337
+ threshold: 15000
338
+ },
339
+ configFile: '',
340
+ rootDir: '',
341
+ quiet: false,
342
+ shard: null,
343
+ updateSnapshots: 'missing',
344
+ version: '',
345
+ workers: 0,
346
+ webServer: null
347
+ };
348
+ exports.baseFullConfig = baseFullConfig;
349
+ function serializeRegexPatterns(patterns) {
350
+ if (!Array.isArray(patterns)) patterns = [patterns];
351
+ return patterns.map(s => {
352
+ if (typeof s === 'string') return {
353
+ s
354
+ };
355
+ return {
356
+ r: {
357
+ source: s.source,
358
+ flags: s.flags
359
+ }
360
+ };
361
+ });
362
+ }
363
+ function parseRegexPatterns(patterns) {
364
+ return patterns.map(p => {
365
+ if (p.s) return p.s;
366
+ return new RegExp(p.r.source, p.r.flags);
367
+ });
368
+ }
@@ -5,13 +5,11 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.printReceivedStringContainExpectedSubstring = exports.printReceivedStringContainExpectedResult = exports.expect = void 0;
7
7
  var _utils = require("playwright-core/lib/utils");
8
- var _path = _interopRequireDefault(require("path"));
9
8
  var _matchers = require("./matchers");
10
9
  var _toMatchSnapshot = require("./toMatchSnapshot");
11
10
  var _globals = require("../common/globals");
12
11
  var _util = require("../util");
13
12
  var _expectBundle = require("../common/expectBundle");
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
13
  /**
16
14
  * Copyright Microsoft Corporation. All rights reserved.
17
15
  *
@@ -40,6 +38,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
40
38
  // Format substring but do not enclose in double quote marks.
41
39
  // The replacement is compatible with pretty-format package.
42
40
  const printSubstring = val => val.replace(/"|\\/g, '\\$&');
41
+ let lastCallId = 0;
43
42
  const printReceivedStringContainExpectedSubstring = (received, start, length // not end
44
43
  ) => (0, _expectBundle.RECEIVED_COLOR)('"' + printSubstring(received.slice(0, start)) + (0, _expectBundle.INVERTED_COLOR)(printSubstring(received.slice(start, start + length))) + printSubstring(received.slice(start + length)) + '"');
45
44
  exports.printReceivedStringContainExpectedSubstring = printReceivedStringContainExpectedSubstring;
@@ -102,7 +101,8 @@ class ExpectMetaInfoProxyHandler {
102
101
  isSoft,
103
102
  isPoll,
104
103
  generator,
105
- isNot: false
104
+ isNot: false,
105
+ nameTokens: []
106
106
  };
107
107
  if (typeof messageOrOptions === 'string') {
108
108
  this._info.message = messageOrOptions;
@@ -114,6 +114,7 @@ class ExpectMetaInfoProxyHandler {
114
114
  }
115
115
  get(target, matcherName, receiver) {
116
116
  let matcher = Reflect.get(target, matcherName, receiver);
117
+ if (typeof matcherName !== 'string') return matcher;
117
118
  if (matcher === undefined) throw new Error(`expect: Property '${matcherName}' not found.`);
118
119
  if (typeof matcher !== 'function') {
119
120
  if (matcherName === 'not') this._info.isNot = !this._info.isNot;
@@ -128,23 +129,23 @@ class ExpectMetaInfoProxyHandler {
128
129
  return (...args) => {
129
130
  const testInfo = (0, _globals.currentTestInfo)();
130
131
  if (!testInfo) return matcher.call(target, ...args);
131
- const stackTrace = (0, _util.captureStackTrace)();
132
- const stackLines = stackTrace.frameTexts;
133
- const frame = stackTrace.frames[0];
132
+ const rawStack = (0, _utils.captureRawStack)();
133
+ const stackFrames = (0, _util.filteredStackTrace)(rawStack);
134
134
  const customMessage = this._info.message || '';
135
135
  const defaultTitle = `expect${this._info.isPoll ? '.poll' : ''}${this._info.isSoft ? '.soft' : ''}${this._info.isNot ? '.not' : ''}.${matcherName}`;
136
+ const wallTime = Date.now();
136
137
  const step = testInfo._addStep({
137
- location: frame && frame.file ? {
138
- file: _path.default.resolve(process.cwd(), frame.file),
139
- line: frame.line || 0,
140
- column: frame.column || 0
141
- } : undefined,
138
+ location: stackFrames[0],
142
139
  category: 'expect',
143
140
  title: (0, _util.trimLongString)(customMessage || defaultTitle, 1024),
144
141
  canHaveChildren: true,
145
- forceNoParent: false
142
+ forceNoParent: false,
143
+ wallTime
146
144
  });
147
145
  testInfo.currentStep = step;
146
+ const generateTraceEvent = matcherName !== 'poll' && matcherName !== 'toPass';
147
+ const callId = ++lastCallId;
148
+ if (generateTraceEvent) testInfo._traceEvents.push((0, _utils.createBeforeActionTraceEventForExpect)(`expect@${callId}`, defaultTitle, args[0], stackFrames));
148
149
  const reportStepError = jestError => {
149
150
  const message = jestError.message;
150
151
  if (customMessage) {
@@ -156,19 +157,37 @@ class ExpectMetaInfoProxyHandler {
156
157
  // if there's a newline after the matcher text, then remove it as well.
157
158
  if (uselessMatcherLineIndex + 1 < messageLines.length && messageLines[uselessMatcherLineIndex + 1].trim() === '') messageLines.splice(uselessMatcherLineIndex, 2);else messageLines.splice(uselessMatcherLineIndex, 1);
158
159
  }
159
- const newMessage = ['Error: ' + customMessage, '', ...messageLines].join('\n');
160
+ const newMessage = [customMessage, '', ...messageLines].join('\n');
160
161
  jestError.message = newMessage;
161
- jestError.stack = newMessage + '\n' + stackLines.join('\n');
162
+ jestError.stack = jestError.name + ': ' + newMessage + '\n' + (0, _util.stringifyStackFrames)(stackFrames).join('\n');
162
163
  }
163
164
  const serializerError = (0, _util.serializeError)(jestError);
165
+ if (generateTraceEvent) {
166
+ const error = {
167
+ name: jestError.name,
168
+ message: jestError.message,
169
+ stack: jestError.stack
170
+ };
171
+ testInfo._traceEvents.push((0, _utils.createAfterActionTraceEventForExpect)(`expect@${callId}`, error));
172
+ }
164
173
  step.complete({
165
174
  error: serializerError
166
175
  });
167
176
  if (this._info.isSoft) testInfo._failWithError(serializerError, false /* isHardError */);else throw jestError;
168
177
  };
178
+ const finalizer = () => {
179
+ if (generateTraceEvent) testInfo._traceEvents.push((0, _utils.createAfterActionTraceEventForExpect)(`expect@${callId}`));
180
+ step.complete({});
181
+ };
169
182
  try {
170
- const result = matcher.call(target, ...args);
171
- if (result instanceof Promise) return result.then(() => step.complete({})).catch(reportStepError);else step.complete({});
183
+ const expectZone = {
184
+ title: defaultTitle,
185
+ wallTime
186
+ };
187
+ const result = _utils.zones.run('expectZone', expectZone, () => {
188
+ return matcher.call(target, ...args);
189
+ });
190
+ if (result instanceof Promise) return result.then(() => finalizer()).catch(reportStepError);else finalizer();
172
191
  } catch (e) {
173
192
  reportStepError(e);
174
193
  }