playwright 1.50.0 → 1.50.1

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.
@@ -161,8 +161,7 @@ class FullProjectInternal {
161
161
  this.teardown = void 0;
162
162
  this.fullConfig = fullConfig;
163
163
  const testDir = takeFirst(pathResolve(configDir, projectConfig.testDir), pathResolve(configDir, config.testDir), fullConfig.configDir);
164
- const defaultSnapshotPathTemplate = '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}';
165
- this.snapshotPathTemplate = takeFirst(projectConfig.snapshotPathTemplate, config.snapshotPathTemplate, defaultSnapshotPathTemplate);
164
+ this.snapshotPathTemplate = takeFirst(projectConfig.snapshotPathTemplate, config.snapshotPathTemplate);
166
165
  this.project = {
167
166
  grep: takeFirst(projectConfig.grep, config.grep, defaultGrep),
168
167
  grepInvert: takeFirst(projectConfig.grepInvert, config.grepInvert, null),
@@ -206,7 +206,7 @@ function validateConfig(file, config) {
206
206
  if (!('current' in config.shard) || typeof config.shard.current !== 'number' || config.shard.current < 1 || config.shard.current > config.shard.total) throw (0, _util.errorWithFile)(file, `config.shard.current must be a positive number, not greater than config.shard.total`);
207
207
  }
208
208
  if ('updateSnapshots' in config && config.updateSnapshots !== undefined) {
209
- if (typeof config.updateSnapshots !== 'string' || !['all', 'none', 'missing'].includes(config.updateSnapshots)) throw (0, _util.errorWithFile)(file, `config.updateSnapshots must be one of "all", "none" or "missing"`);
209
+ if (typeof config.updateSnapshots !== 'string' || !['all', 'changed', 'missing', 'none'].includes(config.updateSnapshots)) throw (0, _util.errorWithFile)(file, `config.updateSnapshots must be one of "all", "changed", "missing" or "none"`);
210
210
  }
211
211
  if ('workers' in config && config.workers !== undefined) {
212
212
  if (typeof config.workers === 'number' && config.workers <= 0) throw (0, _util.errorWithFile)(file, `config.workers must be a positive number`);else if (typeof config.workers === 'string' && !config.workers.endsWith('%')) throw (0, _util.errorWithFile)(file, `config.workers must be a number or percentage`);
@@ -250,6 +250,8 @@ class ExpectMetaInfoProxyHandler {
250
250
  const jestError = (0, _matcherHint.isJestError)(e) ? e : null;
251
251
  const error = jestError ? new _matcherHint.ExpectError(jestError, customMessage, stackFrames) : e;
252
252
  if (jestError !== null && jestError !== void 0 && jestError.matcherResult.suggestedRebaseline) {
253
+ // NOTE: this is a workaround for the fact that we can't pass the suggested rebaseline
254
+ // for passing matchers. See toMatchAriaSnapshot for a counterpart.
253
255
  step.complete({
254
256
  suggestedRebaseline: jestError === null || jestError === void 0 ? void 0 : jestError.matcherResult.suggestedRebaseline
255
257
  });
@@ -30,7 +30,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
30
30
  */
31
31
 
32
32
  async function toMatchAriaSnapshot(receiver, expectedParam, options = {}) {
33
- var _options$timeout;
33
+ var _testInfo$_projectInt;
34
34
  const matcherName = 'toMatchAriaSnapshot';
35
35
  const testInfo = (0, _globals.currentTestInfo)();
36
36
  if (!testInfo) throw new Error(`toMatchAriaSnapshot() must be called during the test`);
@@ -41,17 +41,23 @@ async function toMatchAriaSnapshot(receiver, expectedParam, options = {}) {
41
41
  expected: ''
42
42
  };
43
43
  const updateSnapshots = testInfo.config.updateSnapshots;
44
+ const pathTemplate = (_testInfo$_projectInt = testInfo._projectInternal.expect) === null || _testInfo$_projectInt === void 0 || (_testInfo$_projectInt = _testInfo$_projectInt.toMatchAriaSnapshot) === null || _testInfo$_projectInt === void 0 ? void 0 : _testInfo$_projectInt.pathTemplate;
45
+ const defaultTemplate = '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{ext}';
44
46
  const matcherOptions = {
45
47
  isNot: this.isNot,
46
48
  promise: this.promise
47
49
  };
48
50
  let expected;
51
+ let timeout;
49
52
  let expectedPath;
50
53
  if ((0, _utils.isString)(expectedParam)) {
54
+ var _options$timeout;
51
55
  expected = expectedParam;
56
+ timeout = (_options$timeout = options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : this.timeout;
52
57
  } else {
58
+ var _expectedParam$timeou;
53
59
  if (expectedParam !== null && expectedParam !== void 0 && expectedParam.name) {
54
- expectedPath = testInfo.snapshotPath((0, _util.sanitizeFilePathBeforeExtension)(expectedParam.name));
60
+ expectedPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [(0, _util.sanitizeFilePathBeforeExtension)(expectedParam.name)]);
55
61
  } else {
56
62
  let snapshotNames = testInfo[snapshotNamesSymbol];
57
63
  if (!snapshotNames) {
@@ -61,9 +67,10 @@ async function toMatchAriaSnapshot(receiver, expectedParam, options = {}) {
61
67
  testInfo[snapshotNamesSymbol] = snapshotNames;
62
68
  }
63
69
  const fullTitleWithoutSpec = [...testInfo.titlePath.slice(1), ++snapshotNames.anonymousSnapshotIndex].join(' ');
64
- expectedPath = testInfo.snapshotPath((0, _utils.sanitizeForFilePath)((0, _util.trimLongString)(fullTitleWithoutSpec)) + '.yml');
70
+ expectedPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [(0, _utils.sanitizeForFilePath)((0, _util.trimLongString)(fullTitleWithoutSpec)) + '.yml']);
65
71
  }
66
72
  expected = await _fs.default.promises.readFile(expectedPath, 'utf8').catch(() => '');
73
+ timeout = (_expectedParam$timeou = expectedParam === null || expectedParam === void 0 ? void 0 : expectedParam.timeout) !== null && _expectedParam$timeou !== void 0 ? _expectedParam$timeou : this.timeout;
67
74
  }
68
75
  const generateMissingBaseline = updateSnapshots === 'missing' && !expected;
69
76
  if (generateMissingBaseline) {
@@ -79,7 +86,6 @@ async function toMatchAriaSnapshot(receiver, expectedParam, options = {}) {
79
86
  expected = `- none "Generating new baseline"`;
80
87
  }
81
88
  }
82
- const timeout = (_options$timeout = options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : this.timeout;
83
89
  expected = unshift(expected);
84
90
  const {
85
91
  matches: pass,
@@ -138,6 +144,14 @@ async function toMatchAriaSnapshot(receiver, expectedParam, options = {}) {
138
144
  };
139
145
  } else {
140
146
  const suggestedRebaseline = `\`\n${(0, _utils.escapeTemplateString)(indent(typedReceived.regex, '{indent} '))}\n{indent}\``;
147
+ if (updateSnapshots === 'missing') {
148
+ const message = 'A snapshot is not provided, generating new baseline.';
149
+ testInfo._hasNonRetriableError = true;
150
+ testInfo._failWithError(new Error(message));
151
+ }
152
+ // TODO: ideally, we should return "pass: true" here because this matcher passes
153
+ // when regenerating baselines. However, we can only access suggestedRebaseline in case
154
+ // of an error, so we fail here and workaround it in the expect implementation.
141
155
  return {
142
156
  pass: false,
143
157
  message: () => '',
@@ -102,7 +102,8 @@ class SnapshotHelper {
102
102
  outputBasePath = testInfo._getOutputPath(sanitizedName);
103
103
  this.attachmentBaseName = sanitizedName;
104
104
  }
105
- this.expectedPath = testInfo.snapshotPath(...expectedPathSegments);
105
+ const defaultTemplate = '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}';
106
+ this.expectedPath = testInfo._resolveSnapshotPath(configOptions.pathTemplate, defaultTemplate, expectedPathSegments);
106
107
  this.legacyExpectedPath = (0, _util.addSuffixToFilePath)(outputBasePath, '-expected');
107
108
  this.previousPath = (0, _util.addSuffixToFilePath)(outputBasePath, '-previous');
108
109
  this.actualPath = (0, _util.addSuffixToFilePath)(outputBasePath, '-actual');
package/lib/program.js CHANGED
@@ -269,7 +269,7 @@ async function mergeReports(reportDir, opts) {
269
269
  function overridesFromOptions(options) {
270
270
  const shardPair = options.shard ? options.shard.split('/').map(t => parseInt(t, 10)) : undefined;
271
271
  let updateSnapshots;
272
- if (['all', 'changed', 'missing', 'none'].includes(options.updateSnapshots)) updateSnapshots = options.updateSnapshots;else updateSnapshots = 'updateSnapshots' in options ? 'changed' : 'missing';
272
+ if (['all', 'changed', 'missing', 'none'].includes(options.updateSnapshots)) updateSnapshots = options.updateSnapshots;else updateSnapshots = 'updateSnapshots' in options ? 'changed' : undefined;
273
273
  const overrides = {
274
274
  forbidOnly: options.forbidOnly ? true : undefined,
275
275
  fullyParallel: options.fullyParallel ? true : undefined,
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.addSuggestedRebaseline = addSuggestedRebaseline;
7
7
  exports.applySuggestedRebaselines = applySuggestedRebaselines;
8
+ exports.clearSuggestedRebaselines = clearSuggestedRebaselines;
8
9
  var _path = _interopRequireDefault(require("path"));
9
10
  var _fs = _interopRequireDefault(require("fs"));
10
11
  var _babelBundle = require("../transform/babelBundle");
@@ -36,6 +37,9 @@ function addSuggestedRebaseline(location, suggestedRebaseline) {
36
37
  code: suggestedRebaseline
37
38
  });
38
39
  }
40
+ function clearSuggestedRebaselines() {
41
+ suggestedRebaselines.clear();
42
+ }
39
43
  async function applySuggestedRebaselines(config, reporter) {
40
44
  if (config.config.updateSnapshots === 'none') return;
41
45
  if (!suggestedRebaselines.size) return;
@@ -267,6 +267,9 @@ function createLoadTask(mode, options) {
267
267
  function createApplyRebaselinesTask() {
268
268
  return {
269
269
  title: 'apply rebaselines',
270
+ setup: async () => {
271
+ (0, _rebase.clearSuggestedRebaselines)();
272
+ },
270
273
  teardown: async ({
271
274
  config,
272
275
  reporter
@@ -383,15 +383,20 @@ class TestInfoImpl {
383
383
  const fullTitleWithoutSpec = this.titlePath.slice(1).join(' ');
384
384
  return (0, _utils.sanitizeForFilePath)((0, _util.trimLongString)(fullTitleWithoutSpec));
385
385
  }
386
- snapshotPath(...pathSegments) {
386
+ _resolveSnapshotPath(template, defaultTemplate, pathSegments) {
387
387
  const subPath = _path.default.join(...pathSegments);
388
388
  const parsedSubPath = _path.default.parse(subPath);
389
389
  const relativeTestFilePath = _path.default.relative(this.project.testDir, this._requireFile);
390
390
  const parsedRelativeTestFilePath = _path.default.parse(relativeTestFilePath);
391
391
  const projectNamePathSegment = (0, _utils.sanitizeForFilePath)(this.project.name);
392
- const snapshotPath = (this._projectInternal.snapshotPathTemplate || '').replace(/\{(.)?testDir\}/g, '$1' + this.project.testDir).replace(/\{(.)?snapshotDir\}/g, '$1' + this.project.snapshotDir).replace(/\{(.)?snapshotSuffix\}/g, this.snapshotSuffix ? '$1' + this.snapshotSuffix : '').replace(/\{(.)?testFileDir\}/g, '$1' + parsedRelativeTestFilePath.dir).replace(/\{(.)?platform\}/g, '$1' + process.platform).replace(/\{(.)?projectName\}/g, projectNamePathSegment ? '$1' + projectNamePathSegment : '').replace(/\{(.)?testName\}/g, '$1' + this._fsSanitizedTestName()).replace(/\{(.)?testFileName\}/g, '$1' + parsedRelativeTestFilePath.base).replace(/\{(.)?testFilePath\}/g, '$1' + relativeTestFilePath).replace(/\{(.)?arg\}/g, '$1' + _path.default.join(parsedSubPath.dir, parsedSubPath.name)).replace(/\{(.)?ext\}/g, parsedSubPath.ext ? '$1' + parsedSubPath.ext : '');
392
+ const actualTemplate = template || this._projectInternal.snapshotPathTemplate || defaultTemplate;
393
+ const snapshotPath = actualTemplate.replace(/\{(.)?testDir\}/g, '$1' + this.project.testDir).replace(/\{(.)?snapshotDir\}/g, '$1' + this.project.snapshotDir).replace(/\{(.)?snapshotSuffix\}/g, this.snapshotSuffix ? '$1' + this.snapshotSuffix : '').replace(/\{(.)?testFileDir\}/g, '$1' + parsedRelativeTestFilePath.dir).replace(/\{(.)?platform\}/g, '$1' + process.platform).replace(/\{(.)?projectName\}/g, projectNamePathSegment ? '$1' + projectNamePathSegment : '').replace(/\{(.)?testName\}/g, '$1' + this._fsSanitizedTestName()).replace(/\{(.)?testFileName\}/g, '$1' + parsedRelativeTestFilePath.base).replace(/\{(.)?testFilePath\}/g, '$1' + relativeTestFilePath).replace(/\{(.)?arg\}/g, '$1' + _path.default.join(parsedSubPath.dir, parsedSubPath.name)).replace(/\{(.)?ext\}/g, parsedSubPath.ext ? '$1' + parsedSubPath.ext : '');
393
394
  return _path.default.normalize(_path.default.resolve(this._configInternal.configDir, snapshotPath));
394
395
  }
396
+ snapshotPath(...pathSegments) {
397
+ const legacyTemplate = '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}';
398
+ return this._resolveSnapshotPath(undefined, legacyTemplate, pathSegments);
399
+ }
395
400
  skip(...args) {
396
401
  this._modifier('skip', args);
397
402
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright",
3
- "version": "1.50.0",
3
+ "version": "1.50.1",
4
4
  "description": "A high-level API to automate web browsers",
5
5
  "repository": {
6
6
  "type": "git",
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "license": "Apache-2.0",
58
58
  "dependencies": {
59
- "playwright-core": "1.50.0"
59
+ "playwright-core": "1.50.1"
60
60
  },
61
61
  "optionalDependencies": {
62
62
  "fsevents": "2.3.2"
package/types/test.d.ts CHANGED
@@ -214,6 +214,27 @@ interface TestProject<TestArgs = {}, WorkerArgs = {}> {
214
214
  * [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot).
215
215
  */
216
216
  stylePath?: string|Array<string>;
217
+
218
+ /**
219
+ * A template controlling location of the screenshots. See
220
+ * [testProject.snapshotPathTemplate](https://playwright.dev/docs/api/class-testproject#test-project-snapshot-path-template)
221
+ * for details.
222
+ */
223
+ pathTemplate?: string;
224
+ };
225
+
226
+ /**
227
+ * Configuration for the
228
+ * [expect(locator).toMatchAriaSnapshot([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-match-aria-snapshot-2)
229
+ * method.
230
+ */
231
+ toMatchAriaSnapshot?: {
232
+ /**
233
+ * A template controlling location of the aria snapshots. See
234
+ * [testProject.snapshotPathTemplate](https://playwright.dev/docs/api/class-testproject#test-project-snapshot-path-template)
235
+ * for details.
236
+ */
237
+ pathTemplate?: string;
217
238
  };
218
239
 
219
240
  /**
@@ -404,10 +425,14 @@ interface TestProject<TestArgs = {}, WorkerArgs = {}> {
404
425
 
405
426
  /**
406
427
  * This option configures a template controlling location of snapshots generated by
407
- * [expect(page).toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
428
+ * [expect(page).toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1),
429
+ * [expect(locator).toMatchAriaSnapshot([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-match-aria-snapshot-2)
408
430
  * and
409
431
  * [expect(value).toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
410
432
  *
433
+ * You can configure templates for each assertion separately in
434
+ * [testConfig.expect](https://playwright.dev/docs/api/class-testconfig#test-config-expect).
435
+ *
411
436
  * **Usage**
412
437
  *
413
438
  * ```js
@@ -416,7 +441,19 @@ interface TestProject<TestArgs = {}, WorkerArgs = {}> {
416
441
  *
417
442
  * export default defineConfig({
418
443
  * testDir: './tests',
444
+ *
445
+ * // Single template for all assertions
419
446
  * snapshotPathTemplate: '{testDir}/__screenshots__/{testFilePath}/{arg}{ext}',
447
+ *
448
+ * // Assertion-specific templates
449
+ * expect: {
450
+ * toHaveScreenshot: {
451
+ * pathTemplate: '{testDir}/__screenshots__{/projectName}/{testFilePath}/{arg}{ext}',
452
+ * },
453
+ * toMatchAriaSnapshot: {
454
+ * pathTemplate: '{testDir}/__snapshots__/{testFilePath}/{arg}{ext}',
455
+ * },
456
+ * },
420
457
  * });
421
458
  * ```
422
459
  *
@@ -447,27 +484,27 @@ interface TestProject<TestArgs = {}, WorkerArgs = {}> {
447
484
  * ```
448
485
  *
449
486
  * The list of supported tokens:
450
- * - `{arg}` - Relative snapshot path **without extension**. These come from the arguments passed to the
451
- * `toHaveScreenshot()` and `toMatchSnapshot()` calls; if called without arguments, this will be an auto-generated
452
- * snapshot name.
487
+ * - `{arg}` - Relative snapshot path **without extension**. This comes from the arguments passed to
488
+ * `toHaveScreenshot()`, `toMatchAriaSnapshot()` or `toMatchSnapshot()`; if called without arguments, this will be
489
+ * an auto-generated snapshot name.
453
490
  * - Value: `foo/bar/baz`
454
- * - `{ext}` - snapshot extension (with dots)
491
+ * - `{ext}` - Snapshot extension (with the leading dot).
455
492
  * - Value: `.png`
456
493
  * - `{platform}` - The value of `process.platform`.
457
494
  * - `{projectName}` - Project's file-system-sanitized name, if any.
458
495
  * - Value: `''` (empty string).
459
496
  * - `{snapshotDir}` - Project's
460
- * [testConfig.snapshotDir](https://playwright.dev/docs/api/class-testconfig#test-config-snapshot-dir).
497
+ * [testProject.snapshotDir](https://playwright.dev/docs/api/class-testproject#test-project-snapshot-dir).
461
498
  * - Value: `/home/playwright/tests` (since `snapshotDir` is not provided in config, it defaults to `testDir`)
462
499
  * - `{testDir}` - Project's
463
- * [testConfig.testDir](https://playwright.dev/docs/api/class-testconfig#test-config-test-dir).
464
- * - Value: `/home/playwright/tests` (absolute path is since `testDir` is resolved relative to directory with
500
+ * [testProject.testDir](https://playwright.dev/docs/api/class-testproject#test-project-test-dir).
501
+ * - Value: `/home/playwright/tests` (absolute path since `testDir` is resolved relative to directory with
465
502
  * config)
466
503
  * - `{testFileDir}` - Directories in relative path from `testDir` to **test file**.
467
504
  * - Value: `page`
468
505
  * - `{testFileName}` - Test file name with extension.
469
506
  * - Value: `page-click.spec.ts`
470
- * - `{testFilePath}` - Relative path from `testDir` to **test file**
507
+ * - `{testFilePath}` - Relative path from `testDir` to **test file**.
471
508
  * - Value: `page/page-click.spec.ts`
472
509
  * - `{testName}` - File-system-sanitized test title, including parent describes but excluding file name.
473
510
  * - Value: `suite-test-should-work`
@@ -991,6 +1028,27 @@ interface TestConfig<TestArgs = {}, WorkerArgs = {}> {
991
1028
  * [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
992
1029
  */
993
1030
  threshold?: number;
1031
+
1032
+ /**
1033
+ * A template controlling location of the screenshots. See
1034
+ * [testConfig.snapshotPathTemplate](https://playwright.dev/docs/api/class-testconfig#test-config-snapshot-path-template)
1035
+ * for details.
1036
+ */
1037
+ pathTemplate?: string;
1038
+ };
1039
+
1040
+ /**
1041
+ * Configuration for the
1042
+ * [expect(locator).toMatchAriaSnapshot([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-match-aria-snapshot-2)
1043
+ * method.
1044
+ */
1045
+ toMatchAriaSnapshot?: {
1046
+ /**
1047
+ * A template controlling location of the aria snapshots. See
1048
+ * [testConfig.snapshotPathTemplate](https://playwright.dev/docs/api/class-testconfig#test-config-snapshot-path-template)
1049
+ * for details.
1050
+ */
1051
+ pathTemplate?: string;
994
1052
  };
995
1053
 
996
1054
  /**
@@ -1468,10 +1526,14 @@ interface TestConfig<TestArgs = {}, WorkerArgs = {}> {
1468
1526
 
1469
1527
  /**
1470
1528
  * This option configures a template controlling location of snapshots generated by
1471
- * [expect(page).toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
1529
+ * [expect(page).toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1),
1530
+ * [expect(locator).toMatchAriaSnapshot([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-match-aria-snapshot-2)
1472
1531
  * and
1473
1532
  * [expect(value).toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
1474
1533
  *
1534
+ * You can configure templates for each assertion separately in
1535
+ * [testConfig.expect](https://playwright.dev/docs/api/class-testconfig#test-config-expect).
1536
+ *
1475
1537
  * **Usage**
1476
1538
  *
1477
1539
  * ```js
@@ -1480,7 +1542,19 @@ interface TestConfig<TestArgs = {}, WorkerArgs = {}> {
1480
1542
  *
1481
1543
  * export default defineConfig({
1482
1544
  * testDir: './tests',
1545
+ *
1546
+ * // Single template for all assertions
1483
1547
  * snapshotPathTemplate: '{testDir}/__screenshots__/{testFilePath}/{arg}{ext}',
1548
+ *
1549
+ * // Assertion-specific templates
1550
+ * expect: {
1551
+ * toHaveScreenshot: {
1552
+ * pathTemplate: '{testDir}/__screenshots__{/projectName}/{testFilePath}/{arg}{ext}',
1553
+ * },
1554
+ * toMatchAriaSnapshot: {
1555
+ * pathTemplate: '{testDir}/__snapshots__/{testFilePath}/{arg}{ext}',
1556
+ * },
1557
+ * },
1484
1558
  * });
1485
1559
  * ```
1486
1560
  *
@@ -1511,27 +1585,27 @@ interface TestConfig<TestArgs = {}, WorkerArgs = {}> {
1511
1585
  * ```
1512
1586
  *
1513
1587
  * The list of supported tokens:
1514
- * - `{arg}` - Relative snapshot path **without extension**. These come from the arguments passed to the
1515
- * `toHaveScreenshot()` and `toMatchSnapshot()` calls; if called without arguments, this will be an auto-generated
1516
- * snapshot name.
1588
+ * - `{arg}` - Relative snapshot path **without extension**. This comes from the arguments passed to
1589
+ * `toHaveScreenshot()`, `toMatchAriaSnapshot()` or `toMatchSnapshot()`; if called without arguments, this will be
1590
+ * an auto-generated snapshot name.
1517
1591
  * - Value: `foo/bar/baz`
1518
- * - `{ext}` - snapshot extension (with dots)
1592
+ * - `{ext}` - Snapshot extension (with the leading dot).
1519
1593
  * - Value: `.png`
1520
1594
  * - `{platform}` - The value of `process.platform`.
1521
1595
  * - `{projectName}` - Project's file-system-sanitized name, if any.
1522
1596
  * - Value: `''` (empty string).
1523
1597
  * - `{snapshotDir}` - Project's
1524
- * [testConfig.snapshotDir](https://playwright.dev/docs/api/class-testconfig#test-config-snapshot-dir).
1598
+ * [testProject.snapshotDir](https://playwright.dev/docs/api/class-testproject#test-project-snapshot-dir).
1525
1599
  * - Value: `/home/playwright/tests` (since `snapshotDir` is not provided in config, it defaults to `testDir`)
1526
1600
  * - `{testDir}` - Project's
1527
- * [testConfig.testDir](https://playwright.dev/docs/api/class-testconfig#test-config-test-dir).
1528
- * - Value: `/home/playwright/tests` (absolute path is since `testDir` is resolved relative to directory with
1601
+ * [testProject.testDir](https://playwright.dev/docs/api/class-testproject#test-project-test-dir).
1602
+ * - Value: `/home/playwright/tests` (absolute path since `testDir` is resolved relative to directory with
1529
1603
  * config)
1530
1604
  * - `{testFileDir}` - Directories in relative path from `testDir` to **test file**.
1531
1605
  * - Value: `page`
1532
1606
  * - `{testFileName}` - Test file name with extension.
1533
1607
  * - Value: `page-click.spec.ts`
1534
- * - `{testFilePath}` - Relative path from `testDir` to **test file**
1608
+ * - `{testFilePath}` - Relative path from `testDir` to **test file**.
1535
1609
  * - Value: `page/page-click.spec.ts`
1536
1610
  * - `{testName}` - File-system-sanitized test title, including parent describes but excluding file name.
1537
1611
  * - Value: `suite-test-should-work`
@@ -8685,20 +8759,22 @@ interface LocatorAssertions {
8685
8759
  /**
8686
8760
  * Asserts that the target element matches the given [accessibility snapshot](https://playwright.dev/docs/aria-snapshots).
8687
8761
  *
8762
+ * Snapshot is stored in a separate `.yml` file in a location configured by `expect.toMatchAriaSnapshot.pathTemplate`
8763
+ * and/or `snapshotPathTemplate` properties in the configuration file.
8764
+ *
8688
8765
  * **Usage**
8689
8766
  *
8690
8767
  * ```js
8691
8768
  * await expect(page.locator('body')).toMatchAriaSnapshot();
8692
- * await expect(page.locator('body')).toMatchAriaSnapshot({ name: 'snapshot' });
8693
- * await expect(page.locator('body')).toMatchAriaSnapshot({ path: '/path/to/snapshot.yml' });
8769
+ * await expect(page.locator('body')).toMatchAriaSnapshot({ name: 'body.yml' });
8694
8770
  * ```
8695
8771
  *
8696
8772
  * @param options
8697
8773
  */
8698
8774
  toMatchAriaSnapshot(options?: {
8699
8775
  /**
8700
- * Name of the snapshot to store in the snapshot (screenshot) folder corresponding to this test. Generates sequential
8701
- * names if not specified.
8776
+ * Name of the snapshot to store in the snapshot folder corresponding to this test. Generates sequential names if not
8777
+ * specified.
8702
8778
  */
8703
8779
  name?: string;
8704
8780