@playwright/test 1.37.0-alpha-aug-7-2023 → 1.37.0-alpha-aug-8-2023

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.
@@ -51,8 +51,12 @@ class TeleReporterReceiver {
51
51
  this._onConfigure(params.config);
52
52
  return;
53
53
  }
54
+ if (method === 'onProject') {
55
+ this._onProject(params.project);
56
+ return;
57
+ }
54
58
  if (method === 'onBegin') {
55
- this._onBegin(params.projects);
59
+ this._onBegin();
56
60
  return;
57
61
  }
58
62
  if (method === 'onTestBegin') {
@@ -92,35 +96,35 @@ class TeleReporterReceiver {
92
96
  this._config = this._parseConfig(config);
93
97
  this._reporter.onConfigure(this._config);
94
98
  }
95
- _onBegin(projects) {
96
- var _this$_reporter$onBeg, _this$_reporter;
97
- for (const project of projects) {
98
- let projectSuite = this._rootSuite.suites.find(suite => suite.project().id === project.id);
99
- if (!projectSuite) {
100
- projectSuite = new TeleSuite(project.name, 'project');
101
- this._rootSuite.suites.push(projectSuite);
102
- projectSuite.parent = this._rootSuite;
103
- }
104
- const p = this._parseProject(project);
105
- projectSuite.project = () => p;
106
- this._mergeSuitesInto(project.suites, projectSuite);
99
+ _onProject(project) {
100
+ let projectSuite = this._rootSuite.suites.find(suite => suite.project().id === project.id);
101
+ if (!projectSuite) {
102
+ projectSuite = new TeleSuite(project.name, 'project');
103
+ this._rootSuite.suites.push(projectSuite);
104
+ projectSuite.parent = this._rootSuite;
105
+ }
106
+ const p = this._parseProject(project);
107
+ projectSuite.project = () => p;
108
+ this._mergeSuitesInto(project.suites, projectSuite);
107
109
 
108
- // Remove deleted tests when listing. Empty suites will be auto-filtered
109
- // in the UI layer.
110
- if (this._listOnly) {
111
- const testIds = new Set();
112
- const collectIds = suite => {
113
- suite.tests.map(t => t.testId).forEach(testId => testIds.add(testId));
114
- suite.suites.forEach(collectIds);
115
- };
116
- project.suites.forEach(collectIds);
117
- const filterTests = suite => {
118
- suite.tests = suite.tests.filter(t => testIds.has(t.id));
119
- suite.suites.forEach(filterTests);
120
- };
121
- filterTests(projectSuite);
122
- }
110
+ // Remove deleted tests when listing. Empty suites will be auto-filtered
111
+ // in the UI layer.
112
+ if (this._listOnly) {
113
+ const testIds = new Set();
114
+ const collectIds = suite => {
115
+ suite.tests.map(t => t.testId).forEach(testId => testIds.add(testId));
116
+ suite.suites.forEach(collectIds);
117
+ };
118
+ project.suites.forEach(collectIds);
119
+ const filterTests = suite => {
120
+ suite.tests = suite.tests.filter(t => testIds.has(t.id));
121
+ suite.suites.forEach(filterTests);
122
+ };
123
+ filterTests(projectSuite);
123
124
  }
125
+ }
126
+ _onBegin() {
127
+ var _this$_reporter$onBeg, _this$_reporter;
124
128
  (_this$_reporter$onBeg = (_this$_reporter = this._reporter).onBegin) === null || _this$_reporter$onBeg === void 0 ? void 0 : _this$_reporter$onBeg.call(_this$_reporter, this._rootSuite);
125
129
  }
126
130
  _onTestBegin(testId, payload) {
@@ -35,7 +35,7 @@ class SnapshotHelper {
35
35
  var _mime$getType;
36
36
  this.testInfo = void 0;
37
37
  this.snapshotName = void 0;
38
- this.expectedPath = void 0;
38
+ this.legacyExpectedPath = void 0;
39
39
  this.previousPath = void 0;
40
40
  this.snapshotPath = void 0;
41
41
  this.actualPath = void 0;
@@ -102,7 +102,7 @@ class SnapshotHelper {
102
102
  this.snapshotPath = snapshotPathResolver(...inputPathSegments);
103
103
  const inputFile = testInfo._getOutputPath(...inputPathSegments);
104
104
  const outputFile = testInfo._getOutputPath(...outputPathSegments);
105
- this.expectedPath = (0, _util.addSuffixToFilePath)(inputFile, '-expected');
105
+ this.legacyExpectedPath = (0, _util.addSuffixToFilePath)(inputFile, '-expected');
106
106
  this.previousPath = (0, _util.addSuffixToFilePath)(outputFile, '-previous');
107
107
  this.actualPath = (0, _util.addSuffixToFilePath)(outputFile, '-actual');
108
108
  this.diffPath = (0, _util.addSuffixToFilePath)(outputFile, '-diff');
@@ -181,13 +181,15 @@ class SnapshotHelper {
181
181
  if (diffError) output.push(indent(diffError, ' '));
182
182
  if (log !== null && log !== void 0 && log.length) output.push((0, _util.callLogText)(log));else output.push('');
183
183
  if (expected !== undefined) {
184
- writeFileSync(this.expectedPath, expected);
184
+ // Copy the expectation inside the `test-results/` folder for backwards compatibility,
185
+ // so that one can upload `test-results/` directory and have all the data inside.
186
+ writeFileSync(this.legacyExpectedPath, expected);
185
187
  this.testInfo.attachments.push({
186
188
  name: (0, _util.addSuffixToFilePath)(this.snapshotName, '-expected'),
187
189
  contentType: this.mimeType,
188
- path: this.expectedPath
190
+ path: this.snapshotPath
189
191
  });
190
- output.push(`Expected: ${_utilsBundle.colors.yellow(this.expectedPath)}`);
192
+ output.push(`Expected: ${_utilsBundle.colors.yellow(this.snapshotPath)}`);
191
193
  }
192
194
  if (previous !== undefined) {
193
195
  writeFileSync(this.previousPath, previous);
@@ -46,7 +46,7 @@ class BlobReporter extends _teleEmitter.TeleReporterEmitter {
46
46
  var _config$shard;
47
47
  const metadata = {
48
48
  version: currentBlobReportVersion,
49
- projectSuffix: process.env.PWTEST_BLOB_SUFFIX,
49
+ name: process.env.PWTEST_BLOB_REPORT_NAME,
50
50
  shard: (_config$shard = config.shard) !== null && _config$shard !== void 0 ? _config$shard : undefined
51
51
  };
52
52
  this._messages.push({
@@ -91,7 +91,7 @@ class BlobReporter extends _teleEmitter.TeleReporterEmitter {
91
91
  }
92
92
  _computeReportName(config) {
93
93
  let reportName = 'report';
94
- if (process.env.PWTEST_BLOB_SUFFIX) reportName += (0, _utils.sanitizeForFilePath)(process.env.PWTEST_BLOB_SUFFIX);
94
+ if (process.env.PWTEST_BLOB_REPORT_NAME) reportName += `-${(0, _utils.sanitizeForFilePath)(process.env.PWTEST_BLOB_REPORT_NAME)}`;
95
95
  if (config.shard) {
96
96
  const paddedNumber = `${config.shard.current}`.padStart(`${config.shard.total}`.length, '0');
97
97
  reportName += `-${paddedNumber}`;
@@ -187,6 +187,7 @@ class HtmlBuilder {
187
187
  const data = new Map();
188
188
  for (const projectJson of rawReports) {
189
189
  for (const file of projectJson.suites) {
190
+ var _projectJson$project$;
190
191
  const fileName = file.location.file;
191
192
  const fileId = file.fileId;
192
193
  let fileEntry = data.get(fileId);
@@ -211,7 +212,7 @@ class HtmlBuilder {
211
212
  testFileSummary
212
213
  } = fileEntry;
213
214
  const testEntries = [];
214
- this._processJsonSuite(file, fileId, projectJson.project.name, [], testEntries);
215
+ this._processJsonSuite(file, fileId, projectJson.project.name, (_projectJson$project$ = projectJson.project.metadata) === null || _projectJson$project$ === void 0 ? void 0 : _projectJson$project$.reportName, [], testEntries);
215
216
  for (const test of testEntries) {
216
217
  testFile.tests.push(test.testCase);
217
218
  testFileSummary.tests.push(test.testCaseSummary);
@@ -304,12 +305,12 @@ class HtmlBuilder {
304
305
  _addDataFile(fileName, data) {
305
306
  this._dataZipFile.addBuffer(Buffer.from(JSON.stringify(data)), fileName);
306
307
  }
307
- _processJsonSuite(suite, fileId, projectName, path, outTests) {
308
+ _processJsonSuite(suite, fileId, projectName, reportName, path, outTests) {
308
309
  const newPath = [...path, suite.title];
309
- suite.suites.map(s => this._processJsonSuite(s, fileId, projectName, newPath, outTests));
310
- suite.tests.forEach(t => outTests.push(this._createTestEntry(t, projectName, newPath)));
310
+ suite.suites.map(s => this._processJsonSuite(s, fileId, projectName, reportName, newPath, outTests));
311
+ suite.tests.forEach(t => outTests.push(this._createTestEntry(t, projectName, reportName, newPath)));
311
312
  }
312
- _createTestEntry(test, projectName, path) {
313
+ _createTestEntry(test, projectName, reportName, path) {
313
314
  const duration = test.results.reduce((a, r) => a + r.duration, 0);
314
315
  this._tests.set(test.testId, test);
315
316
  const location = test.location;
@@ -321,6 +322,7 @@ class HtmlBuilder {
321
322
  testId: test.testId,
322
323
  title: test.title,
323
324
  projectName,
325
+ reportName,
324
326
  location,
325
327
  duration,
326
328
  annotations: test.annotations,
@@ -333,6 +335,7 @@ class HtmlBuilder {
333
335
  testId: test.testId,
334
336
  title: test.title,
335
337
  projectName,
338
+ reportName,
336
339
  location,
337
340
  duration,
338
341
  annotations: test.annotations,
@@ -56,7 +56,7 @@ class JUnitReporter extends _empty.default {
56
56
  const duration = (0, _utils.monotonicTime)() - this.startTime;
57
57
  const children = [];
58
58
  for (const projectSuite of this.suite.suites) {
59
- for (const fileSuite of projectSuite.suites) children.push(this._buildTestSuite(projectSuite.title, fileSuite));
59
+ for (const fileSuite of projectSuite.suites) children.push(await this._buildTestSuite(projectSuite.title, fileSuite));
60
60
  }
61
61
  const tokens = [];
62
62
  const self = this;
@@ -78,27 +78,27 @@ class JUnitReporter extends _empty.default {
78
78
  if (this.outputFile) {
79
79
  (0, _utils.assert)(this.config.configFile || _path.default.isAbsolute(this.outputFile), 'Expected fully resolved path if not using config file.');
80
80
  const outputFile = this.config.configFile ? _path.default.resolve(_path.default.dirname(this.config.configFile), this.outputFile) : this.outputFile;
81
- _fs.default.mkdirSync(_path.default.dirname(outputFile), {
81
+ await _fs.default.promises.mkdir(_path.default.dirname(outputFile), {
82
82
  recursive: true
83
83
  });
84
- _fs.default.writeFileSync(outputFile, reportString);
84
+ await _fs.default.promises.writeFile(outputFile, reportString);
85
85
  } else {
86
86
  console.log(reportString);
87
87
  }
88
88
  }
89
- _buildTestSuite(projectName, suite) {
89
+ async _buildTestSuite(projectName, suite) {
90
90
  let tests = 0;
91
91
  let skipped = 0;
92
92
  let failures = 0;
93
93
  let duration = 0;
94
94
  const children = [];
95
- suite.allTests().forEach(test => {
95
+ for (const test of suite.allTests()) {
96
96
  ++tests;
97
97
  if (test.outcome() === 'skipped') ++skipped;
98
98
  if (!test.ok()) ++failures;
99
99
  for (const result of test.results) duration += result.duration;
100
- this._addTestCase(suite.title, test, children);
101
- });
100
+ await this._addTestCase(suite.title, test, children);
101
+ }
102
102
  this.totalTests += tests;
103
103
  this.totalSkipped += skipped;
104
104
  this.totalFailures += failures;
@@ -118,7 +118,7 @@ class JUnitReporter extends _empty.default {
118
118
  };
119
119
  return entry;
120
120
  }
121
- _addTestCase(suiteName, test, entries) {
121
+ async _addTestCase(suiteName, test, entries) {
122
122
  var _properties$children2;
123
123
  const entry = {
124
124
  name: 'testcase',
@@ -175,10 +175,13 @@ class JUnitReporter extends _empty.default {
175
175
  systemErr.push(...result.stderr.map(item => item.toString()));
176
176
  for (const attachment of result.attachments) {
177
177
  if (!attachment.path) continue;
178
+ const attachmentPath = _path.default.relative(this.config.rootDir, attachment.path);
178
179
  try {
179
- const attachmentPath = _path.default.relative(this.config.rootDir, attachment.path);
180
- if (_fs.default.existsSync(attachment.path)) systemOut.push(`\n[[ATTACHMENT|${attachmentPath}]]\n`);else systemErr.push(`\nWarning: attachment ${attachmentPath} is missing`);
181
- } catch (e) {}
180
+ await _fs.default.promises.access(attachment.path);
181
+ systemOut.push(`\n[[ATTACHMENT|${attachmentPath}]]\n`);
182
+ } catch {
183
+ systemErr.push(`\nWarning: attachment ${attachmentPath} is missing`);
184
+ }
182
185
  }
183
186
  }
184
187
  // Note: it is important to only produce a single system-out/system-err entry
@@ -73,7 +73,7 @@ async function extractAndParseReports(dir, shardFiles, stringPool, printStatus)
73
73
  printStatus(`extracting: ${(0, _util.relativeFilePath)(absolutePath)}`);
74
74
  const zipFile = new _utils.ZipFile(absolutePath);
75
75
  const entryNames = await zipFile.entries();
76
- for (const entryName of entryNames) {
76
+ for (const entryName of entryNames.sort()) {
77
77
  const content = await zipFile.read(entryName);
78
78
  if (entryName.endsWith('.jsonl')) {
79
79
  const parsedEvents = parseEvents(content);
@@ -82,6 +82,7 @@ async function extractAndParseReports(dir, shardFiles, stringPool, printStatus)
82
82
  // as a post-processing step.
83
83
  internalizer.traverse(parsedEvents);
84
84
  shardEvents.push({
85
+ file,
85
86
  metadata: findMetadata(parsedEvents, file),
86
87
  parsedEvents
87
88
  });
@@ -102,28 +103,47 @@ function findMetadata(events, file) {
102
103
  return metadata;
103
104
  }
104
105
  async function mergeEvents(dir, shardReportFiles, printStatus) {
106
+ const stringPool = new _stringInternPool.StringInternPool();
105
107
  const events = [];
106
108
  const configureEvents = [];
107
- const beginEvents = [];
109
+ const projectEvents = [];
108
110
  const endEvents = [];
109
- const stringPool = new _stringInternPool.StringInternPool();
110
- const shardEvents = await extractAndParseReports(dir, shardReportFiles, stringPool, printStatus);
111
- shardEvents.sort((a, b) => {
112
- var _a$metadata$shard$cur, _a$metadata$shard, _b$metadata$shard$cur, _b$metadata$shard;
111
+ const blobs = await extractAndParseReports(dir, shardReportFiles, stringPool, printStatus);
112
+ // Sort by (report name; shard; file name), so that salt generation below is deterministic when:
113
+ // - report names are unique;
114
+ // - report names are missing;
115
+ // - report names are clashing between shards.
116
+ blobs.sort((a, b) => {
117
+ var _a$metadata$name, _b$metadata$name, _a$metadata$shard$cur, _a$metadata$shard, _b$metadata$shard$cur, _b$metadata$shard;
118
+ const nameA = (_a$metadata$name = a.metadata.name) !== null && _a$metadata$name !== void 0 ? _a$metadata$name : '';
119
+ const nameB = (_b$metadata$name = b.metadata.name) !== null && _b$metadata$name !== void 0 ? _b$metadata$name : '';
120
+ if (nameA !== nameB) return nameA.localeCompare(nameB);
113
121
  const shardA = (_a$metadata$shard$cur = (_a$metadata$shard = a.metadata.shard) === null || _a$metadata$shard === void 0 ? void 0 : _a$metadata$shard.current) !== null && _a$metadata$shard$cur !== void 0 ? _a$metadata$shard$cur : 0;
114
122
  const shardB = (_b$metadata$shard$cur = (_b$metadata$shard = b.metadata.shard) === null || _b$metadata$shard === void 0 ? void 0 : _b$metadata$shard.current) !== null && _b$metadata$shard$cur !== void 0 ? _b$metadata$shard$cur : 0;
115
- return shardA - shardB;
123
+ if (shardA !== shardB) return shardA - shardB;
124
+ return a.file.localeCompare(b.file);
116
125
  });
117
- const allTestIds = new Set();
126
+ const saltSet = new Set();
118
127
  printStatus(`merging events`);
119
128
  for (const {
120
- parsedEvents
121
- } of shardEvents) {
129
+ file,
130
+ parsedEvents,
131
+ metadata
132
+ } of blobs) {
133
+ // Generate unique salt for each blob.
134
+ const sha1 = (0, _utils.calculateSha1)(metadata.name || _path.default.basename(file)).substring(0, 16);
135
+ let salt = sha1;
136
+ for (let i = 0; saltSet.has(salt); i++) salt = sha1 + '-' + i;
137
+ saltSet.add(salt);
138
+ new IdsPatcher(stringPool, metadata.name, salt).patchEvents(parsedEvents);
122
139
  for (const event of parsedEvents) {
123
- if (event.method === 'onConfigure') configureEvents.push(event);else if (event.method === 'onBegin') beginEvents.push(event);else if (event.method === 'onEnd') endEvents.push(event);else if (event.method === 'onBlobReportMetadata') new ProjectNamePatcher(allTestIds, stringPool, event.params.projectSuffix || '').patchEvents(parsedEvents);else events.push(event);
140
+ if (event.method === 'onConfigure') configureEvents.push(event);else if (event.method === 'onProject') projectEvents.push(event);else if (event.method === 'onEnd') endEvents.push(event);else if (event.method !== 'onBlobReportMetadata' && event.method !== 'onBegin') events.push(event);
124
141
  }
125
142
  }
126
- return [mergeConfigureEvents(configureEvents), mergeBeginEvents(beginEvents), ...events, mergeEndEvents(endEvents), {
143
+ return [mergeConfigureEvents(configureEvents), ...projectEvents, {
144
+ method: 'onBegin',
145
+ params: undefined
146
+ }, ...events, mergeEndEvents(endEvents), {
127
147
  method: 'onExit',
128
148
  params: undefined
129
149
  }];
@@ -150,23 +170,6 @@ function mergeConfigureEvents(configureEvents) {
150
170
  }
151
171
  };
152
172
  }
153
- function mergeBeginEvents(beginEvents) {
154
- if (!beginEvents.length) throw new Error('No begin events found');
155
- const projects = [];
156
- for (const event of beginEvents) {
157
- const shardProjects = event.params.projects;
158
- for (const shardProject of shardProjects) {
159
- const mergedProject = projects.find(p => p.id === shardProject.id);
160
- if (!mergedProject) projects.push(shardProject);else mergeJsonSuites(shardProject.suites, mergedProject);
161
- }
162
- }
163
- return {
164
- method: 'onBegin',
165
- params: {
166
- projects
167
- }
168
- };
169
- }
170
173
  function mergeConfigs(to, from) {
171
174
  return {
172
175
  ...to,
@@ -180,17 +183,6 @@ function mergeConfigs(to, from) {
180
183
  workers: to.workers + from.workers
181
184
  };
182
185
  }
183
- function mergeJsonSuites(jsonSuites, parent) {
184
- for (const jsonSuite of jsonSuites) {
185
- const existingSuite = parent.suites.find(s => s.title === jsonSuite.title);
186
- if (!existingSuite) {
187
- parent.suites.push(jsonSuite);
188
- } else {
189
- mergeJsonSuites(jsonSuite.suites, existingSuite);
190
- existingSuite.tests.push(...jsonSuite.tests);
191
- }
192
- }
193
- }
194
186
  function mergeEndEvents(endEvents) {
195
187
  const result = {
196
188
  status: 'passed'
@@ -213,12 +205,11 @@ async function sortedShardFiles(dir) {
213
205
  function printStatusToStdout(message) {
214
206
  process.stdout.write(`${message}\n`);
215
207
  }
216
- class ProjectNamePatcher {
217
- constructor(_allTestIds, _stringPool, _projectNameSuffix) {
218
- this._testIds = new Set();
219
- this._allTestIds = _allTestIds;
208
+ class IdsPatcher {
209
+ constructor(_stringPool, _reportName, _salt) {
220
210
  this._stringPool = _stringPool;
221
- this._projectNameSuffix = _projectNameSuffix;
211
+ this._reportName = _reportName;
212
+ this._salt = _salt;
222
213
  }
223
214
  patchEvents(events) {
224
215
  for (const event of events) {
@@ -227,8 +218,8 @@ class ProjectNamePatcher {
227
218
  params
228
219
  } = event;
229
220
  switch (method) {
230
- case 'onBegin':
231
- this._onBegin(params.config, params.projects);
221
+ case 'onProject':
222
+ this._onProject(params.project);
232
223
  continue;
233
224
  case 'onTestBegin':
234
225
  case 'onStepBegin':
@@ -241,39 +232,19 @@ class ProjectNamePatcher {
241
232
  continue;
242
233
  }
243
234
  }
244
- for (const testId of this._testIds) this._allTestIds.add(testId);
245
- }
246
- _onBegin(config, projects) {
247
- for (const project of projects) project.name += this._projectNameSuffix;
248
- this._updateProjectIds(projects);
249
- for (const project of projects) project.suites.forEach(suite => this._updateTestIds(suite));
250
235
  }
251
- _updateProjectIds(projects) {
252
- const usedNames = new Set();
253
- for (const p of projects) {
254
- for (let i = 0; i < projects.length; ++i) {
255
- const candidate = p.name + (i ? i : '');
256
- if (usedNames.has(candidate)) continue;
257
- p.id = candidate;
258
- usedNames.add(candidate);
259
- break;
260
- }
261
- }
236
+ _onProject(project) {
237
+ var _project$metadata;
238
+ project.metadata = (_project$metadata = project.metadata) !== null && _project$metadata !== void 0 ? _project$metadata : {};
239
+ project.metadata.reportName = this._reportName;
240
+ project.id = this._stringPool.internString(project.id + this._salt);
241
+ project.suites.forEach(suite => this._updateTestIds(suite));
262
242
  }
263
243
  _updateTestIds(suite) {
264
- suite.tests.forEach(test => {
265
- test.testId = this._mapTestId(test.testId);
266
- this._testIds.add(test.testId);
267
- });
244
+ suite.tests.forEach(test => test.testId = this._mapTestId(test.testId));
268
245
  suite.suites.forEach(suite => this._updateTestIds(suite));
269
246
  }
270
247
  _mapTestId(testId) {
271
- testId = testId + this._projectNameSuffix;
272
- // Consider a setup project running on each shard. In this case we'll have
273
- // the same testId (from setup project) in multiple blob reports.
274
- // To avoid reporters being confused by clashing test ids, we automatically
275
- // make them unique and produce a separate test from each blob.
276
- while (this._allTestIds.has(testId)) testId = testId + '1';
277
- return this._stringPool.internString(testId);
248
+ return this._stringPool.internString(testId + this._salt);
278
249
  }
279
250
  }
@@ -47,12 +47,16 @@ class TeleReporterEmitter {
47
47
  }
48
48
  onBegin(suite) {
49
49
  const projects = suite.suites.map(projectSuite => this._serializeProject(projectSuite));
50
- this._messageSink({
51
- method: 'onBegin',
50
+ for (const project of projects) this._messageSink({
51
+ method: 'onProject',
52
52
  params: {
53
- projects
53
+ project
54
54
  }
55
55
  });
56
+ this._messageSink({
57
+ method: 'onBegin',
58
+ params: undefined
59
+ });
56
60
  }
57
61
  onTestBegin(test, result) {
58
62
  result[idSymbol] = (0, _utils.createGuid)();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playwright/test",
3
- "version": "1.37.0-alpha-aug-7-2023",
3
+ "version": "1.37.0-alpha-aug-8-2023",
4
4
  "description": "A high-level API to automate web browsers",
5
5
  "repository": "github:Microsoft/playwright",
6
6
  "homepage": "https://playwright.dev",
@@ -41,7 +41,7 @@
41
41
  "license": "Apache-2.0",
42
42
  "dependencies": {
43
43
  "@types/node": "*",
44
- "playwright-core": "1.37.0-alpha-aug-7-2023"
44
+ "playwright-core": "1.37.0-alpha-aug-8-2023"
45
45
  },
46
46
  "optionalDependencies": {
47
47
  "fsevents": "2.3.2"
package/types/test.d.ts CHANGED
@@ -164,7 +164,7 @@ export interface FullProject<TestArgs = {}, WorkerArgs = {}> {
164
164
  * Filter to only run tests with a title matching one of the patterns. For example, passing `grep: /cart/` should only
165
165
  * run tests with "cart" in the title. Also available globally and in the [command line](https://playwright.dev/docs/test-cli) with the `-g`
166
166
  * option. The regular expression will be tested against the string that consists of the test file name,
167
- * `test.describe` name (if any) and the test name divided by spaces, e.g. `my-test.spec.ts my suite my test`.
167
+ * `test.describe` name (if any) and the test name divided by spaces, e.g. `my-test.spec.ts my-suite my-test`.
168
168
  *
169
169
  * `grep` option is also useful for [tagging tests](https://playwright.dev/docs/test-annotations#tag-tests).
170
170
  */
@@ -791,7 +791,9 @@ interface TestConfig {
791
791
 
792
792
  /**
793
793
  * Filter to only run tests with a title matching one of the patterns. For example, passing `grep: /cart/` should only
794
- * run tests with "cart" in the title. Also available in the [command line](https://playwright.dev/docs/test-cli) with the `-g` option.
794
+ * run tests with "cart" in the title. Also available in the [command line](https://playwright.dev/docs/test-cli) with the `-g` option. The
795
+ * regular expression will be tested against the string that consists of the test file name, `test.describe` name (if
796
+ * any) and the test name divided by spaces, e.g. `my-test.spec.ts my-suite my-test`.
795
797
  *
796
798
  * `grep` option is also useful for [tagging tests](https://playwright.dev/docs/test-annotations#tag-tests).
797
799
  *
@@ -1540,7 +1542,9 @@ export interface FullConfig<TestArgs = {}, WorkerArgs = {}> {
1540
1542
  globalTimeout: number;
1541
1543
  /**
1542
1544
  * Filter to only run tests with a title matching one of the patterns. For example, passing `grep: /cart/` should only
1543
- * run tests with "cart" in the title. Also available in the [command line](https://playwright.dev/docs/test-cli) with the `-g` option.
1545
+ * run tests with "cart" in the title. Also available in the [command line](https://playwright.dev/docs/test-cli) with the `-g` option. The
1546
+ * regular expression will be tested against the string that consists of the test file name, `test.describe` name (if
1547
+ * any) and the test name divided by spaces, e.g. `my-test.spec.ts my-suite my-test`.
1544
1548
  *
1545
1549
  * `grep` option is also useful for [tagging tests](https://playwright.dev/docs/test-annotations#tag-tests).
1546
1550
  *
@@ -6406,7 +6410,7 @@ interface TestProject {
6406
6410
  * Filter to only run tests with a title matching one of the patterns. For example, passing `grep: /cart/` should only
6407
6411
  * run tests with "cart" in the title. Also available globally and in the [command line](https://playwright.dev/docs/test-cli) with the `-g`
6408
6412
  * option. The regular expression will be tested against the string that consists of the test file name,
6409
- * `test.describe` name (if any) and the test name divided by spaces, e.g. `my-test.spec.ts my suite my test`.
6413
+ * `test.describe` name (if any) and the test name divided by spaces, e.g. `my-test.spec.ts my-suite my-test`.
6410
6414
  *
6411
6415
  * `grep` option is also useful for [tagging tests](https://playwright.dev/docs/test-annotations#tag-tests).
6412
6416
  */