@web/test-runner-commands 0.6.1 → 0.6.4
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.
- package/browser/commands.d.ts +23 -1
- package/browser/commands.mjs +2 -0
- package/dist/emulateMediaPlugin.d.ts +1 -0
- package/dist/emulateMediaPlugin.d.ts.map +1 -1
- package/dist/emulateMediaPlugin.js.map +1 -1
- package/dist/snapshotPlugin.d.ts.map +1 -1
- package/dist/snapshotPlugin.js +44 -5
- package/dist/snapshotPlugin.js.map +1 -1
- package/package.json +8 -5
- package/src/emulateMediaPlugin.ts +1 -0
- package/src/snapshotPlugin.ts +54 -6
package/browser/commands.d.ts
CHANGED
|
@@ -26,7 +26,29 @@ export function setViewport(viewport: Viewport): Promise<void>;
|
|
|
26
26
|
* Emulates browser media, such as screen/print or color scheme, to be used in
|
|
27
27
|
* CSS media queries.
|
|
28
28
|
*
|
|
29
|
-
* The
|
|
29
|
+
* The `forcedColors` property is Playwright-only API that does not work in WebKit.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* await emulateMedia({
|
|
34
|
+
* colorScheme: 'dark',
|
|
35
|
+
* reducedMotion: 'reduce',
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* await emulateMedia({
|
|
42
|
+
* media: 'print',
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* await emulateMedia({
|
|
49
|
+
* forcedColors: 'active',
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
30
52
|
*/
|
|
31
53
|
export function emulateMedia(media: Media): Promise<void>;
|
|
32
54
|
|
package/browser/commands.mjs
CHANGED
|
@@ -3,6 +3,7 @@ export interface Media {
|
|
|
3
3
|
media?: 'screen' | 'print';
|
|
4
4
|
colorScheme?: 'dark' | 'light' | 'no-preference';
|
|
5
5
|
reducedMotion?: 'reduce' | 'no-preference';
|
|
6
|
+
forcedColors?: 'active' | 'none';
|
|
6
7
|
}
|
|
7
8
|
export declare function emulateMediaPlugin(): TestRunnerPlugin;
|
|
8
9
|
//# sourceMappingURL=emulateMediaPlugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emulateMediaPlugin.d.ts","sourceRoot":"","sources":["../src/emulateMediaPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIzD,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,eAAe,CAAC;IACjD,aAAa,CAAC,EAAE,QAAQ,GAAG,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"emulateMediaPlugin.d.ts","sourceRoot":"","sources":["../src/emulateMediaPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIzD,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,eAAe,CAAC;IACjD,aAAa,CAAC,EAAE,QAAQ,GAAG,eAAe,CAAC;IAC3C,YAAY,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CAClC;AAuBD,wBAAgB,kBAAkB,IAAI,gBAAgB,CA0CrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emulateMediaPlugin.js","sourceRoot":"","sources":["../src/emulateMediaPlugin.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"emulateMediaPlugin.js","sourceRoot":"","sources":["../src/emulateMediaPlugin.ts"],"names":[],"mappings":";;;AAWA,SAAS,QAAQ,CAAC,OAAgB;IAChC,OAAO,OAAO,IAAI,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC;AACxD,CAAC;AAED,SAAS,aAAa,CAAC,OAAgB;IACrC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAE9E,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,EAAE;QACjE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;KAC9C;IAED,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,IAAI,CAAC,CAAC,OAAO,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC,EAAE;QAC7E,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;KACpD;IAED,IAAI,OAAO,CAAC,aAAa,IAAI,IAAI,IAAI,CAAC,CAAC,OAAO,OAAO,CAAC,aAAa,KAAK,QAAQ,CAAC,EAAE;QACjF,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;KACtD;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,kBAAkB;IAChC,OAAO;QACL,IAAI,EAAE,uBAAuB;QAE7B,KAAK,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAChD,IAAI,OAAO,KAAK,eAAe,EAAE;gBAC/B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE;oBAC3B,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;iBACvD;gBAED,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE;oBACxC,MAAM,IAAI,GAAI,OAAO,CAAC,OAA0B,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBACrE,MAAM,QAAQ,GAAG,EAAE,CAAC;oBAEpB,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,EAAE;wBAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;qBAC7E;oBACD,IAAI,OAAO,CAAC,aAAa,IAAI,IAAI,EAAE;wBACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;qBACjF;oBAED,MAAM,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;oBAE1C,IAAI,OAAO,CAAC,KAAK,EAAE;wBACjB,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;qBAC5C;oBAED,OAAO,IAAI,CAAC;iBACb;gBAED,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE;oBACzC,MAAM,IAAI,GAAI,OAAO,CAAC,OAA8B,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBACzE,MAAM,IAAI,CAAC,YAAY,CAAC,OAAc,CAAC,CAAC;oBACxC,OAAO,IAAI,CAAC;iBACb;gBAED,MAAM,IAAI,KAAK,CACb,sDAAsD,OAAO,CAAC,OAAO,CAAC,IAAI,GAAG,CAC9E,CAAC;aACH;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AA1CD,gDA0CC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshotPlugin.d.ts","sourceRoot":"","sources":["../src/snapshotPlugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"snapshotPlugin.d.ts","sourceRoot":"","sources":["../src/snapshotPlugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAyBzD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAuHD,MAAM,WAAW,oBAAoB;IACnC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,oBAAoB,GAAG,gBAAgB,CAoD9E"}
|
package/dist/snapshotPlugin.js
CHANGED
|
@@ -43,6 +43,7 @@ function getSnapshotPath(testFile) {
|
|
|
43
43
|
class SnapshotStore {
|
|
44
44
|
constructor() {
|
|
45
45
|
this.snapshots = new Map();
|
|
46
|
+
this.sessionToSnapshotPath = new Map();
|
|
46
47
|
this.readOperations = new Map();
|
|
47
48
|
}
|
|
48
49
|
async get(testFilePath) {
|
|
@@ -52,9 +53,10 @@ class SnapshotStore {
|
|
|
52
53
|
// something else is already reading, wait for it
|
|
53
54
|
await ((_a = this.readOperations.get(snapshotPath)) === null || _a === void 0 ? void 0 : _a.promise);
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
+
const cachedContent = this.snapshots.get(snapshotPath);
|
|
57
|
+
if (cachedContent) {
|
|
56
58
|
// return from cache
|
|
57
|
-
return
|
|
59
|
+
return cachedContent;
|
|
58
60
|
}
|
|
59
61
|
const promiseObj = { resolve: () => { }, promise: Promise.resolve() };
|
|
60
62
|
promiseObj.promise = new Promise(resolve => {
|
|
@@ -71,7 +73,7 @@ class SnapshotStore {
|
|
|
71
73
|
this.readOperations.delete(snapshotPath);
|
|
72
74
|
return content;
|
|
73
75
|
}
|
|
74
|
-
async saveSnapshot(testFilePath, name, updatedSnapshot) {
|
|
76
|
+
async saveSnapshot(sessionId, testFilePath, name, updatedSnapshot) {
|
|
75
77
|
const snapshotPath = getSnapshotPath(testFilePath);
|
|
76
78
|
const nameStr = JSON.stringify(name);
|
|
77
79
|
const startMarker = `snapshots[${nameStr}]`;
|
|
@@ -79,7 +81,7 @@ class SnapshotStore {
|
|
|
79
81
|
const replacement = updatedSnapshot
|
|
80
82
|
? `${startMarker} = \n\`${updatedSnapshot}\`;\n${endMarker}`
|
|
81
83
|
: '';
|
|
82
|
-
const content = await this.get(
|
|
84
|
+
const content = await this.get(testFilePath);
|
|
83
85
|
let updatedContent;
|
|
84
86
|
const startIndex = content.indexOf(startMarker);
|
|
85
87
|
if (startIndex !== -1) {
|
|
@@ -96,7 +98,21 @@ class SnapshotStore {
|
|
|
96
98
|
// add new snapshot
|
|
97
99
|
updatedContent = `${content}${replacement}`;
|
|
98
100
|
}
|
|
101
|
+
if (updatedContent === content) {
|
|
102
|
+
// snapshot did not actually change, avoid marking snapshot as dirty
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
this.sessionToSnapshotPath.set(sessionId, snapshotPath);
|
|
99
106
|
this.snapshots.set(snapshotPath, updatedContent);
|
|
107
|
+
}
|
|
108
|
+
getSnapshotPathForSession(sessionId) {
|
|
109
|
+
return this.sessionToSnapshotPath.get(sessionId);
|
|
110
|
+
}
|
|
111
|
+
async writeSnapshot(snapshotPath) {
|
|
112
|
+
const updatedContent = this.snapshots.get(snapshotPath);
|
|
113
|
+
if (!updatedContent) {
|
|
114
|
+
throw new Error('Unexpected error while writing snapshots, could not find snapshot content.');
|
|
115
|
+
}
|
|
100
116
|
if (updatedContent.includes('/* end snapshot')) {
|
|
101
117
|
// update or create snapshot
|
|
102
118
|
const fileDir = path_1.default.dirname(snapshotPath);
|
|
@@ -114,8 +130,31 @@ class SnapshotStore {
|
|
|
114
130
|
function snapshotPlugin(config) {
|
|
115
131
|
const updateSnapshots = config && config.updateSnapshots;
|
|
116
132
|
const snapshots = new SnapshotStore();
|
|
133
|
+
const writePromises = new Set();
|
|
117
134
|
return {
|
|
118
135
|
name: 'file-commands',
|
|
136
|
+
serverStart({ webSockets }) {
|
|
137
|
+
webSockets.on('message', async ({ data }) => {
|
|
138
|
+
const { type, sessionId } = data;
|
|
139
|
+
if (type === 'wtr-session-finished') {
|
|
140
|
+
if (typeof sessionId !== 'string') {
|
|
141
|
+
throw new Error('Missing session id in wtr-session-finished event');
|
|
142
|
+
}
|
|
143
|
+
const snapshotPath = snapshots.getSnapshotPathForSession(sessionId);
|
|
144
|
+
if (!snapshotPath) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const writePromise = snapshots.writeSnapshot(snapshotPath);
|
|
148
|
+
writePromises.add(writePromise);
|
|
149
|
+
await writePromise;
|
|
150
|
+
writePromises.delete(writePromise);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
},
|
|
154
|
+
async serverStop() {
|
|
155
|
+
// ensure all write operations are finished
|
|
156
|
+
await Promise.all([...writePromises]);
|
|
157
|
+
},
|
|
119
158
|
async executeCommand({ command, payload, session }) {
|
|
120
159
|
if (command === 'get-snapshot-config') {
|
|
121
160
|
return { updateSnapshots };
|
|
@@ -128,7 +167,7 @@ function snapshotPlugin(config) {
|
|
|
128
167
|
if (!isSaveSnapshotPayload(payload)) {
|
|
129
168
|
throw new Error('Invalid save snapshot payload');
|
|
130
169
|
}
|
|
131
|
-
await snapshots.saveSnapshot(session.testFile, payload.name, payload.content);
|
|
170
|
+
await snapshots.saveSnapshot(session.id, session.testFile, payload.name, payload.content);
|
|
132
171
|
return true;
|
|
133
172
|
}
|
|
134
173
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshotPlugin.js","sourceRoot":"","sources":["../src/snapshotPlugin.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"snapshotPlugin.js","sourceRoot":"","sources":["../src/snapshotPlugin.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@web/test-runner-commands",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
"homepage": "https://github.com/modernweb-dev/web/tree/master/packages/test-runner-commands",
|
|
16
16
|
"main": "browser/commands.mjs",
|
|
17
17
|
"exports": {
|
|
18
|
-
".":
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./browser/commands.d.ts",
|
|
20
|
+
"default": "./browser/commands.mjs"
|
|
21
|
+
},
|
|
19
22
|
"./plugins": {
|
|
20
23
|
"import": "./plugins.mjs",
|
|
21
24
|
"require": "./dist/index.js"
|
|
@@ -45,13 +48,13 @@
|
|
|
45
48
|
"commands"
|
|
46
49
|
],
|
|
47
50
|
"dependencies": {
|
|
48
|
-
"@web/test-runner-core": "^0.10.
|
|
51
|
+
"@web/test-runner-core": "^0.10.27",
|
|
49
52
|
"mkdirp": "^1.0.4"
|
|
50
53
|
},
|
|
51
54
|
"devDependencies": {
|
|
52
55
|
"@web/test-runner-chrome": "^0.10.2",
|
|
53
|
-
"@web/test-runner-playwright": "^0.8.
|
|
54
|
-
"@web/test-runner-webdriver": "^0.5.
|
|
56
|
+
"@web/test-runner-playwright": "^0.8.9",
|
|
57
|
+
"@web/test-runner-webdriver": "^0.5.1",
|
|
55
58
|
"mocha": "^8.2.1"
|
|
56
59
|
}
|
|
57
60
|
}
|
|
@@ -6,6 +6,7 @@ export interface Media {
|
|
|
6
6
|
media?: 'screen' | 'print';
|
|
7
7
|
colorScheme?: 'dark' | 'light' | 'no-preference';
|
|
8
8
|
reducedMotion?: 'reduce' | 'no-preference';
|
|
9
|
+
forcedColors?: 'active' | 'none';
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
function isObject(payload: unknown): payload is Record<string, unknown> {
|
package/src/snapshotPlugin.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
2
|
import { TestRunnerPlugin } from '@web/test-runner-core';
|
|
3
|
+
import { ServerStartParams } from '@web/dev-server-core';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import fs from 'fs';
|
|
5
6
|
import { promisify } from 'util';
|
|
@@ -46,6 +47,7 @@ function getSnapshotPath(testFile: string) {
|
|
|
46
47
|
|
|
47
48
|
class SnapshotStore {
|
|
48
49
|
private snapshots = new Map<string, string>();
|
|
50
|
+
private sessionToSnapshotPath = new Map<string, string>();
|
|
49
51
|
private readOperations = new Map<string, { promise: Promise<void>; resolve: () => void }>();
|
|
50
52
|
|
|
51
53
|
async get(testFilePath: string): Promise<string> {
|
|
@@ -56,9 +58,10 @@ class SnapshotStore {
|
|
|
56
58
|
await this.readOperations.get(snapshotPath)?.promise;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
const cachedContent = this.snapshots.get(snapshotPath);
|
|
62
|
+
if (cachedContent) {
|
|
60
63
|
// return from cache
|
|
61
|
-
return
|
|
64
|
+
return cachedContent;
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
const promiseObj = { resolve: () => {}, promise: Promise.resolve() };
|
|
@@ -66,7 +69,6 @@ class SnapshotStore {
|
|
|
66
69
|
promiseObj.resolve = resolve;
|
|
67
70
|
});
|
|
68
71
|
this.readOperations.set(testFilePath, promiseObj);
|
|
69
|
-
|
|
70
72
|
// store in cache
|
|
71
73
|
const content = (await fileExists(snapshotPath))
|
|
72
74
|
? await readFile(snapshotPath, 'utf-8')
|
|
@@ -79,7 +81,12 @@ class SnapshotStore {
|
|
|
79
81
|
return content;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
async saveSnapshot(
|
|
84
|
+
async saveSnapshot(
|
|
85
|
+
sessionId: string,
|
|
86
|
+
testFilePath: string,
|
|
87
|
+
name: string,
|
|
88
|
+
updatedSnapshot: string,
|
|
89
|
+
) {
|
|
83
90
|
const snapshotPath = getSnapshotPath(testFilePath);
|
|
84
91
|
const nameStr = JSON.stringify(name);
|
|
85
92
|
const startMarker = `snapshots[${nameStr}]`;
|
|
@@ -88,7 +95,7 @@ class SnapshotStore {
|
|
|
88
95
|
? `${startMarker} = \n\`${updatedSnapshot}\`;\n${endMarker}`
|
|
89
96
|
: '';
|
|
90
97
|
|
|
91
|
-
const content = await this.get(
|
|
98
|
+
const content = await this.get(testFilePath);
|
|
92
99
|
let updatedContent: string;
|
|
93
100
|
|
|
94
101
|
const startIndex = content.indexOf(startMarker);
|
|
@@ -107,8 +114,24 @@ class SnapshotStore {
|
|
|
107
114
|
// add new snapshot
|
|
108
115
|
updatedContent = `${content}${replacement}`;
|
|
109
116
|
}
|
|
117
|
+
if (updatedContent === content) {
|
|
118
|
+
// snapshot did not actually change, avoid marking snapshot as dirty
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
110
121
|
|
|
122
|
+
this.sessionToSnapshotPath.set(sessionId, snapshotPath);
|
|
111
123
|
this.snapshots.set(snapshotPath, updatedContent);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
getSnapshotPathForSession(sessionId: string) {
|
|
127
|
+
return this.sessionToSnapshotPath.get(sessionId);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async writeSnapshot(snapshotPath: string) {
|
|
131
|
+
const updatedContent = this.snapshots.get(snapshotPath);
|
|
132
|
+
if (!updatedContent) {
|
|
133
|
+
throw new Error('Unexpected error while writing snapshots, could not find snapshot content.');
|
|
134
|
+
}
|
|
112
135
|
if (updatedContent.includes('/* end snapshot')) {
|
|
113
136
|
// update or create snapshot
|
|
114
137
|
const fileDir = path.dirname(snapshotPath);
|
|
@@ -130,10 +153,35 @@ export interface SnapshotPluginConfig {
|
|
|
130
153
|
export function snapshotPlugin(config?: SnapshotPluginConfig): TestRunnerPlugin {
|
|
131
154
|
const updateSnapshots = config && config.updateSnapshots;
|
|
132
155
|
const snapshots = new SnapshotStore();
|
|
156
|
+
const writePromises = new Set<Promise<void>>();
|
|
133
157
|
|
|
134
158
|
return {
|
|
135
159
|
name: 'file-commands',
|
|
136
160
|
|
|
161
|
+
serverStart({ webSockets }: ServerStartParams) {
|
|
162
|
+
webSockets!.on('message', async ({ data }) => {
|
|
163
|
+
const { type, sessionId } = data;
|
|
164
|
+
if (type === 'wtr-session-finished') {
|
|
165
|
+
if (typeof sessionId !== 'string') {
|
|
166
|
+
throw new Error('Missing session id in wtr-session-finished event');
|
|
167
|
+
}
|
|
168
|
+
const snapshotPath = snapshots.getSnapshotPathForSession(sessionId);
|
|
169
|
+
if (!snapshotPath) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const writePromise = snapshots.writeSnapshot(snapshotPath);
|
|
173
|
+
writePromises.add(writePromise);
|
|
174
|
+
await writePromise;
|
|
175
|
+
writePromises.delete(writePromise);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
async serverStop() {
|
|
181
|
+
// ensure all write operations are finished
|
|
182
|
+
await Promise.all([...writePromises]);
|
|
183
|
+
},
|
|
184
|
+
|
|
137
185
|
async executeCommand({ command, payload, session }) {
|
|
138
186
|
if (command === 'get-snapshot-config') {
|
|
139
187
|
return { updateSnapshots };
|
|
@@ -149,7 +197,7 @@ export function snapshotPlugin(config?: SnapshotPluginConfig): TestRunnerPlugin
|
|
|
149
197
|
throw new Error('Invalid save snapshot payload');
|
|
150
198
|
}
|
|
151
199
|
|
|
152
|
-
await snapshots.saveSnapshot(session.testFile, payload.name, payload.content);
|
|
200
|
+
await snapshots.saveSnapshot(session.id, session.testFile, payload.name, payload.content);
|
|
153
201
|
return true;
|
|
154
202
|
}
|
|
155
203
|
},
|