Open
Description
🚀 Feature Request
I wish to support the following feature in config:
snapshotPathTemplate?: string | ((testInfo: TestInfo) => string)
OR
snapshotPathResolver?: (filename: string, testInfo: TestInfo) => string
snapshotPathResolver
should be invoked with the parsed snapshot path (=filename
) for further handling, returning the final path to be used.
Currently I am patching playwright to support this.
As you can see it is a very simple change.
diff --git a/node_modules/playwright/.DS_Store b/node_modules/playwright/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/node_modules/playwright/.DS_Store differ
diff --git a/node_modules/playwright/lib/common/config.js b/node_modules/playwright/lib/common/config.js
index 4b21d26..690c308 100644
--- a/node_modules/playwright/lib/common/config.js
+++ b/node_modules/playwright/lib/common/config.js
@@ -158,6 +158,7 @@ class FullProjectInternal {
const testDir = takeFirst(pathResolve(configDir, projectConfig.testDir), pathResolve(configDir, config.testDir), fullConfig.configDir);
const defaultSnapshotPathTemplate = '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}';
this.snapshotPathTemplate = takeFirst(projectConfig.snapshotPathTemplate, config.snapshotPathTemplate, defaultSnapshotPathTemplate);
+ this.snapshotPathResolver = takeFirst(projectConfig.snapshotPathResolver, config.snapshotPathResolver, p => p);
this.project = {
grep: takeFirst(projectConfig.grep, config.grep, defaultGrep),
grepInvert: takeFirst(projectConfig.grepInvert, config.grepInvert, null),
diff --git a/node_modules/playwright/lib/worker/testInfo.js b/node_modules/playwright/lib/worker/testInfo.js
index 5ed9668..61bce7f 100644
--- a/node_modules/playwright/lib/worker/testInfo.js
+++ b/node_modules/playwright/lib/worker/testInfo.js
@@ -386,7 +386,8 @@ class TestInfoImpl {
const parsedRelativeTestFilePath = _path.default.parse(relativeTestFilePath);
const projectNamePathSegment = (0, _utils.sanitizeForFilePath)(this.project.name);
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 : '');
- return _path.default.normalize(_path.default.resolve(this._configInternal.configDir, snapshotPath));
+ const resolvedSnapshotPath = this._projectInternal.snapshotPathResolver ? this._projectInternal.snapshotPathResolver(snapshotPath, this) : snapshotPath;
+ return _path.default.normalize(_path.default.resolve(this._configInternal.configDir, resolvedSnapshotPath));
}
skip(...args) {
this._modifier('skip', args);
Example
It should be used for fine grained runtime control over the snapshot path.
snapshotPathResolver: (file: string, testInfo: TestInfo) => {
if (CI) {
return file;
}
const { name, ext, dir } = path.parse(file);
const resolved = path.join(dir, `${name}.${process.platform}${ext}`);
if (existsSync(path.resolve(resolved))) {
console.warn(`Using local snapshot ${resolved}`);
return resolved;
}
return file;
}
Motivation
In a project I work on some snapshots fail on CI (a very little number) due to OS diffs and we do not want to handle 2 sets of snapshot for dev and for CI so I would like to snapshot locally against a different snapshot