diff --git a/docs/src/api/params.md b/docs/src/api/params.md index 127eaaea40..4423a01f77 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -1351,10 +1351,11 @@ Allows locating elements by their title. For example, this method will find the ``` -## test-config-snapshot-template-path +## test-config-snapshot-path-template - `type` ?<[string]> +* langs: js -This configuration option allows to set a string with template values for precise control over snapshot path location. +This option configures a template controlling location of snapshots generated by [`method: PageAssertions.toHaveScreenshot#1`] and [`method: ScreenshotAssertions.toMatchSnapshot#1`]. ```js tab=js-ts // playwright.config.ts @@ -1392,14 +1393,14 @@ test('should work', async ({ page }) => { The list of supported tokens: -* `{testDir}` - Project's `testDir`. +* `{testDir}` - Project's [`property: TestConfig.testDir`]. * Example: `tests/` -* `{snapshotDir}` - Project's `snapshotDir`. +* `{snapshotDir}` - Project's [`property: TestConfig.snapshotDir`]. * Example: `tests/` (since `snapshotDir` is not provided in config, it defaults to `testDir`) * `{platform}` - The value of `process.platform`. -* `{snapshotSuffix}` - The value of `testInfo.snapshotSuffix`. +* `{snapshotSuffix}` - The value of [`property: TestInfo.snapshotSuffix`]. * `{projectName}` - Project's sanitized name, if any. - * Example: `undefined`. + * Example: `''` (empty string). * `{testFileDir}` - Directories in relative path from `testDir` to **test file**. * Example: `page/` * `{testFileName}` - Test file name with extension. @@ -1434,5 +1435,5 @@ In this config: 1. First project **does not** have a name, so its snapshots will be stored in `/__screenshots__/example.spec.ts/...`. 1. Second project **does** have a name, so its snapshots will be stored in `/__screenshots__/chromium/example.spec.ts/..`. 1. Since `snapshotPathTemplate` resolves to relative path, it will be resolved relative to `configDir`. -1. Forward slashes `"/"` can be used as path separators regarding of the platform and work everywhere. +1. Forward slashes `"/"` can be used as path separators on any platform. diff --git a/docs/src/test-api/class-testconfig.md b/docs/src/test-api/class-testconfig.md index 772005e1f3..8ce46c2fe4 100644 --- a/docs/src/test-api/class-testconfig.md +++ b/docs/src/test-api/class-testconfig.md @@ -337,7 +337,7 @@ The directory for each test can be accessed by [`property: TestInfo.snapshotDir` This path will serve as the base directory for each test file snapshot directory. Setting `snapshotDir` to `'snapshots'`, the [`property: TestInfo.snapshotDir`] would resolve to `snapshots/a.spec.js-snapshots`. -## property: TestConfig.snapshotPathTemplate = %%-test-config-snapshot-template-path-%% +## property: TestConfig.snapshotPathTemplate = %%-test-config-snapshot-path-template-%% * since: v1.28 ## property: TestConfig.preserveOutput diff --git a/docs/src/test-api/class-testproject.md b/docs/src/test-api/class-testproject.md index 8210f28d07..5acda1ce41 100644 --- a/docs/src/test-api/class-testproject.md +++ b/docs/src/test-api/class-testproject.md @@ -178,7 +178,7 @@ The directory for each test can be accessed by [`property: TestInfo.snapshotDir` This path will serve as the base directory for each test file snapshot directory. Setting `snapshotDir` to `'snapshots'`, the [`property: TestInfo.snapshotDir`] would resolve to `snapshots/a.spec.js-snapshots`. -## property: TestProject.snapshotPathTemplate = %%-test-config-snapshot-template-path-%% +## property: TestProject.snapshotPathTemplate = %%-test-config-snapshot-path-template-%% * since: v1.28 ## property: TestProject.outputDir diff --git a/packages/playwright-test/src/loader.ts b/packages/playwright-test/src/loader.ts index 8526532b20..aa0137d195 100644 --- a/packages/playwright-test/src/loader.ts +++ b/packages/playwright-test/src/loader.ts @@ -277,7 +277,7 @@ export class Loader { const _setup = takeFirst(projectConfig.setup, []); const defaultSnapshotPathTemplate = '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}'; - const snapshotPathTemplate = takeFirst((projectConfig as any).snapshotPathTemplate, (config as any).snapshotPathTemplate, defaultSnapshotPathTemplate); + const snapshotPathTemplate = takeFirst(projectConfig.snapshotPathTemplate, config.snapshotPathTemplate, defaultSnapshotPathTemplate); return { _id: '', _fullConfig: fullConfig, @@ -294,7 +294,7 @@ export class Loader { _setup, _respectGitIgnore: respectGitIgnore, snapshotDir, - snapshotPathTemplate: snapshotPathTemplate, + snapshotPathTemplate, testIgnore: takeFirst(projectConfig.testIgnore, config.testIgnore, []), testMatch: takeFirst(projectConfig.testMatch, config.testMatch, '**/?(*.)@(spec|test).*'), timeout: takeFirst(projectConfig.timeout, config.timeout, defaultTimeout), diff --git a/packages/playwright-test/src/testInfo.ts b/packages/playwright-test/src/testInfo.ts index c7af65b7df..4ec64f2f95 100644 --- a/packages/playwright-test/src/testInfo.ts +++ b/packages/playwright-test/src/testInfo.ts @@ -245,12 +245,12 @@ export class TestInfoImpl implements TestInfo { .replace(/\{(.)?snapshotDir\}/g, '$1' + this.project.snapshotDir) .replace(/\{(.)?snapshotSuffix\}/g, this.snapshotSuffix ? '$1' + this.snapshotSuffix : '')) .replace(/\{(.)?platform\}/g, '$1' + process.platform) - .replace(/\{(.)?projectName\}/g, projectNamePathSegment ? '$1' + projectNamePathSegment : projectNamePathSegment) + .replace(/\{(.)?projectName\}/g, projectNamePathSegment ? '$1' + projectNamePathSegment : '') .replace(/\{(.)?testFileDir\}/g, '$1' + parsedRelativeTestFilePath.dir) .replace(/\{(.)?testFileName\}/g, '$1' + parsedRelativeTestFilePath.base) .replace(/\{(.)?testFilePath\}/g, '$1' + relativeTestFilePath) .replace(/\{(.)?arg\}/g, '$1' + path.join(parsedSubPath.dir, parsedSubPath.name)) - .replace(/\{(.)?ext\}/g, '$1' + parsedSubPath.ext); + .replace(/\{(.)?ext\}/g, parsedSubPath.ext ? '$1' + parsedSubPath.ext : ''); return path.normalize(snapshotPath); } diff --git a/packages/playwright-test/src/types.ts b/packages/playwright-test/src/types.ts index e4e2ae7a2b..d405a43cf1 100644 --- a/packages/playwright-test/src/types.ts +++ b/packages/playwright-test/src/types.ts @@ -70,6 +70,7 @@ export interface FullProjectInternal extends FullProjectPublic { _expect: Project['expect']; _respectGitIgnore: boolean; _setup: string | RegExp | (string | RegExp)[]; + snapshotPathTemplate: string; } export interface ReporterInternal extends Reporter { diff --git a/packages/playwright-test/types/test.d.ts b/packages/playwright-test/types/test.d.ts index 7a87c0ef4f..6410d1a052 100644 --- a/packages/playwright-test/types/test.d.ts +++ b/packages/playwright-test/types/test.d.ts @@ -215,84 +215,6 @@ export interface FullProject { * resolve to `snapshots/a.spec.js-snapshots`. */ snapshotDir: string; - /** - * This configuration option allows to set a string with template values for precise control over snapshot path location. - * - * ```js - * // playwright.config.ts - * import type { PlaywrightTestConfig } from '@playwright/test'; - * - * const config: PlaywrightTestConfig = { - * testDir: './tests', - * snapshotPathTemplate: '{testDir}/__screenshots__/{testFilePath}/{arg}{ext}', - * }; - * - * export default config; - * ``` - * - * The value might include some "tokens" that will be replaced with actual values during test execution. - * - * Consider the following file structure: - * - * ``` - * playwright.config.ts - * tests/ - * └── page/ - * └── page-click.spec.ts - * ``` - * - * And the following `page-click.spec.ts` that uses `toHaveScreenshot()` call: - * - * The list of supported tokens: - * - `{testDir}` - Project's `testDir`. - * - Example: `tests/` - * - `{snapshotDir}` - Project's `snapshotDir`. - * - Example: `tests/` (since `snapshotDir` is not provided in config, it defaults to `testDir`) - * - `{platform}` - The value of `process.platform`. - * - `{snapshotSuffix}` - The value of `testInfo.snapshotSuffix`. - * - `{projectName}` - Project's sanitized name, if any. - * - Example: `undefined`. - * - `{testFileDir}` - Directories in relative path from `testDir` to **test file**. - * - Example: `page/` - * - `{testFileName}` - Test file name with extension. - * - Example: `page-click.spec.ts` - * - `{testFilePath}` - Relative path from `testDir` to **test file** - * - Example: `page/page-click.spec.ts` - * - `{arg}` - Relative snapshot path **without extension**. These come from the arguments passed to the - * `toHaveScreenshot()` and `toMatchSnapshot()` calls; if called without arguments, this will be an auto-generated - * snapshot name. - * - Example: `foo/bar/baz` - * - `{ext}` - snapshot extension (with dots) - * - Example: `.png` - * - * Each token can be preceded with a single character that will be used **only if** this token has non-empty value. - * - * Consider the following config: - * - * ```js - * // playwright.config.ts - * import type { PlaywrightTestConfig } from '@playwright/test'; - * - * const config: PlaywrightTestConfig = { - * snapshotPathTemplate: '__screenshots__{/projectName}/{testFilePath}/{arg}{ext}', - * testMatch: 'example.spec.ts', - * projects: [ - * { use: { browserName: 'firefox' } }, - * { name: 'chromium', use: { browserName: 'chromium' } }, - * ], - * }; - * export default config; - * ``` - * - * In this config: - * 1. First project **does not** have a name, so its snapshots will be stored in - * `/__screenshots__/example.spec.ts/...`. - * 1. Second project **does** have a name, so its snapshots will be stored in - * `/__screenshots__/chromium/example.spec.ts/..`. - * 1. Since `snapshotPathTemplate` resolves to relative path, it will be resolved relative to `configDir`. - * 1. Forward slashes `"/"` can be used as path separators regarding of the platform and work everywhere. - */ - snapshotPathTemplate: string; /** * The output directory for files created during test execution. Defaults to `/test-results`. * @@ -848,7 +770,10 @@ interface TestConfig { snapshotDir?: string; /** - * This configuration option allows to set a string with template values for precise control over snapshot path location. + * This option configures a template controlling location of snapshots generated by + * [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1) + * and + * [screenshotAssertions.toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-screenshotassertions#screenshot-assertions-to-match-snapshot-1). * * ```js * // playwright.config.ts @@ -876,14 +801,16 @@ interface TestConfig { * And the following `page-click.spec.ts` that uses `toHaveScreenshot()` call: * * The list of supported tokens: - * - `{testDir}` - Project's `testDir`. + * - `{testDir}` - Project's [testConfig.testDir](https://playwright.dev/docs/api/class-testconfig#test-config-test-dir). * - Example: `tests/` - * - `{snapshotDir}` - Project's `snapshotDir`. + * - `{snapshotDir}` - Project's + * [testConfig.snapshotDir](https://playwright.dev/docs/api/class-testconfig#test-config-snapshot-dir). * - Example: `tests/` (since `snapshotDir` is not provided in config, it defaults to `testDir`) * - `{platform}` - The value of `process.platform`. - * - `{snapshotSuffix}` - The value of `testInfo.snapshotSuffix`. + * - `{snapshotSuffix}` - The value of + * [testInfo.snapshotSuffix](https://playwright.dev/docs/api/class-testinfo#test-info-snapshot-suffix). * - `{projectName}` - Project's sanitized name, if any. - * - Example: `undefined`. + * - Example: `''` (empty string). * - `{testFileDir}` - Directories in relative path from `testDir` to **test file**. * - Example: `page/` * - `{testFileName}` - Test file name with extension. @@ -922,7 +849,7 @@ interface TestConfig { * 1. Second project **does** have a name, so its snapshots will be stored in * `/__screenshots__/chromium/example.spec.ts/..`. * 1. Since `snapshotPathTemplate` resolves to relative path, it will be resolved relative to `configDir`. - * 1. Forward slashes `"/"` can be used as path separators regarding of the platform and work everywhere. + * 1. Forward slashes `"/"` can be used as path separators on any platform. */ snapshotPathTemplate?: string; @@ -4652,7 +4579,10 @@ interface TestProject { snapshotDir?: string; /** - * This configuration option allows to set a string with template values for precise control over snapshot path location. + * This option configures a template controlling location of snapshots generated by + * [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1) + * and + * [screenshotAssertions.toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-screenshotassertions#screenshot-assertions-to-match-snapshot-1). * * ```js * // playwright.config.ts @@ -4680,14 +4610,16 @@ interface TestProject { * And the following `page-click.spec.ts` that uses `toHaveScreenshot()` call: * * The list of supported tokens: - * - `{testDir}` - Project's `testDir`. + * - `{testDir}` - Project's [testConfig.testDir](https://playwright.dev/docs/api/class-testconfig#test-config-test-dir). * - Example: `tests/` - * - `{snapshotDir}` - Project's `snapshotDir`. + * - `{snapshotDir}` - Project's + * [testConfig.snapshotDir](https://playwright.dev/docs/api/class-testconfig#test-config-snapshot-dir). * - Example: `tests/` (since `snapshotDir` is not provided in config, it defaults to `testDir`) * - `{platform}` - The value of `process.platform`. - * - `{snapshotSuffix}` - The value of `testInfo.snapshotSuffix`. + * - `{snapshotSuffix}` - The value of + * [testInfo.snapshotSuffix](https://playwright.dev/docs/api/class-testinfo#test-info-snapshot-suffix). * - `{projectName}` - Project's sanitized name, if any. - * - Example: `undefined`. + * - Example: `''` (empty string). * - `{testFileDir}` - Directories in relative path from `testDir` to **test file**. * - Example: `page/` * - `{testFileName}` - Test file name with extension. @@ -4726,7 +4658,7 @@ interface TestProject { * 1. Second project **does** have a name, so its snapshots will be stored in * `/__screenshots__/chromium/example.spec.ts/..`. * 1. Since `snapshotPathTemplate` resolves to relative path, it will be resolved relative to `configDir`. - * 1. Forward slashes `"/"` can be used as path separators regarding of the platform and work everywhere. + * 1. Forward slashes `"/"` can be used as path separators on any platform. */ snapshotPathTemplate?: string; diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 129cc0b37e..68de70bc65 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -43,7 +43,6 @@ export interface FullProject { metadata: Metadata; name: string; snapshotDir: string; - snapshotPathTemplate: string; outputDir: string; repeatEach: number; retries: number;