@describe-me/core 0.5.0-next.3 → 0.5.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.
- package/README.md +3 -0
- package/dist/manifest-diagnostics.d.ts +4 -3
- package/dist/manifest-diagnostics.js +5 -3
- package/dist/recorder.d.ts +4 -2
- package/dist/recorder.js +44 -12
- package/dist/types.d.ts +17 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,9 @@ Most people never install this package directly — `@describe-me/react` and
|
|
|
14
14
|
pnpm add -D @describe-me/core
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
All describe-me packages must be on the same version
|
|
18
|
+
([Add it to your project](https://github.com/grzehub/describe-me#add-it-to-your-project)).
|
|
19
|
+
|
|
17
20
|
## Usage
|
|
18
21
|
|
|
19
22
|
`step()` names a phase of a test. The DOM is captured after the body resolves,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type Manifest, type ManifestDiagnostics } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* List what the manifest could not document: anonymous components, named ones
|
|
4
|
-
* without props, assets that will not load, font families that nothing loads
|
|
5
|
-
*
|
|
6
|
-
* run and the viewer shows it in the header, so
|
|
4
|
+
* without props, assets that will not load, font families that nothing loads,
|
|
5
|
+
* hosts that frames load stylesheets from and problems in the project's setup.
|
|
6
|
+
* The reporter prints it after a run and the viewer shows it in the header, so
|
|
7
|
+
* both agree on what is missing.
|
|
7
8
|
*/
|
|
8
9
|
export declare function manifestDiagnostics(manifest: Manifest): ManifestDiagnostics;
|
|
@@ -5,9 +5,10 @@ function isHostElement(name) {
|
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* List what the manifest could not document: anonymous components, named ones
|
|
8
|
-
* without props, assets that will not load, font families that nothing loads
|
|
9
|
-
*
|
|
10
|
-
* run and the viewer shows it in the header, so
|
|
8
|
+
* without props, assets that will not load, font families that nothing loads,
|
|
9
|
+
* hosts that frames load stylesheets from and problems in the project's setup.
|
|
10
|
+
* The reporter prints it after a run and the viewer shows it in the header, so
|
|
11
|
+
* both agree on what is missing.
|
|
11
12
|
*/
|
|
12
13
|
export function manifestDiagnostics(manifest) {
|
|
13
14
|
const anonymous = [];
|
|
@@ -33,5 +34,6 @@ export function manifestDiagnostics(manifest) {
|
|
|
33
34
|
assetsMissing: manifest.assetsMissing ?? [],
|
|
34
35
|
fontsMissing: manifest.fontsMissing ?? [],
|
|
35
36
|
remoteStylesheets: manifest.remoteStylesheets ?? [],
|
|
37
|
+
setupWarnings: manifest.setupWarnings ?? [],
|
|
36
38
|
};
|
|
37
39
|
}
|
package/dist/recorder.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ type Teardown = () => void;
|
|
|
7
7
|
* `beforeInteraction()`, `setComponent()` and `onTeardown()`.
|
|
8
8
|
*/
|
|
9
9
|
declare class Recorder {
|
|
10
|
+
/** Which contract this recorder follows, so another copy of core can refuse it. */
|
|
11
|
+
readonly protocol = 1;
|
|
10
12
|
private slots;
|
|
11
13
|
private currentGeneration;
|
|
12
14
|
private inFlight;
|
|
@@ -27,8 +29,8 @@ declare class Recorder {
|
|
|
27
29
|
get generation(): number;
|
|
28
30
|
/**
|
|
29
31
|
* Choose when the render frame is taken, from the next render capture on.
|
|
30
|
-
* The setup files call it with the plugin's options.
|
|
31
|
-
*
|
|
32
|
+
* The setup files call it with the plugin's options. A `pending` selector
|
|
33
|
+
* the DOM rejects falls back to `'lazy'` with a warning.
|
|
32
34
|
*/
|
|
33
35
|
configure(options: RecorderOptions): void;
|
|
34
36
|
/**
|
package/dist/recorder.js
CHANGED
|
@@ -5,16 +5,18 @@ import { realTimers } from './real-timers.js';
|
|
|
5
5
|
import { serializeDocument } from './serialize-document.js';
|
|
6
6
|
import { settle } from './settle.js';
|
|
7
7
|
import { ANONYMOUS_COMPONENT, } from './types.js';
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Bump it whenever the contract between the recorder and the adapters or setup
|
|
10
|
+
* files changes: a method or property added, removed or changed in meaning.
|
|
11
|
+
*/
|
|
12
|
+
const RECORDER_PROTOCOL = 1;
|
|
13
|
+
function isValidSelector(selector) {
|
|
13
14
|
try {
|
|
14
15
|
document.querySelector(selector);
|
|
16
|
+
return true;
|
|
15
17
|
}
|
|
16
18
|
catch {
|
|
17
|
-
|
|
19
|
+
return false;
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
@@ -24,6 +26,8 @@ function assertValidSelector(selector) {
|
|
|
24
26
|
* `beforeInteraction()`, `setComponent()` and `onTeardown()`.
|
|
25
27
|
*/
|
|
26
28
|
class Recorder {
|
|
29
|
+
/** Which contract this recorder follows, so another copy of core can refuse it. */
|
|
30
|
+
protocol = RECORDER_PROTOCOL;
|
|
27
31
|
// One per capture, in call order, so a frame sits where it was asked for.
|
|
28
32
|
slots = [];
|
|
29
33
|
currentGeneration = 0;
|
|
@@ -60,13 +64,17 @@ class Recorder {
|
|
|
60
64
|
}
|
|
61
65
|
/**
|
|
62
66
|
* Choose when the render frame is taken, from the next render capture on.
|
|
63
|
-
* The setup files call it with the plugin's options.
|
|
64
|
-
*
|
|
67
|
+
* The setup files call it with the plugin's options. A `pending` selector
|
|
68
|
+
* the DOM rejects falls back to `'lazy'` with a warning.
|
|
65
69
|
*/
|
|
66
70
|
configure(options) {
|
|
67
71
|
const renderFrame = options.renderFrame ?? 'eager';
|
|
68
|
-
if (typeof renderFrame === 'object'
|
|
69
|
-
|
|
72
|
+
if (typeof renderFrame === 'object' &&
|
|
73
|
+
typeof document !== 'undefined' &&
|
|
74
|
+
!isValidSelector(renderFrame.pending)) {
|
|
75
|
+
console.warn(`describe-me: renderFrame.pending is not a valid CSS selector: "${renderFrame.pending}". Render frames fall back to 'lazy'.`);
|
|
76
|
+
this.renderFrame = 'lazy';
|
|
77
|
+
return;
|
|
70
78
|
}
|
|
71
79
|
this.renderFrame = renderFrame;
|
|
72
80
|
}
|
|
@@ -227,6 +235,21 @@ class Recorder {
|
|
|
227
235
|
}
|
|
228
236
|
}
|
|
229
237
|
const RECORDER_KEY = Symbol.for('describe-me.recorder');
|
|
238
|
+
function protocolOf(existing) {
|
|
239
|
+
if (typeof existing !== 'object' || existing === null) {
|
|
240
|
+
return undefined;
|
|
241
|
+
}
|
|
242
|
+
const candidate = existing;
|
|
243
|
+
if (typeof candidate.protocol === 'number') {
|
|
244
|
+
return candidate.protocol;
|
|
245
|
+
}
|
|
246
|
+
// 0.5.0 did not stamp its recorder. It is the first version with `flush()`,
|
|
247
|
+
// and its contract is protocol 1.
|
|
248
|
+
if (typeof candidate.flush === 'function') {
|
|
249
|
+
return 1;
|
|
250
|
+
}
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
230
253
|
/**
|
|
231
254
|
* The adapter and the setup file may receive two copies of this module: Vite
|
|
232
255
|
* pre-bundles the adapter together with its own copy of core, while a linked
|
|
@@ -237,7 +260,16 @@ const RECORDER_KEY = Symbol.for('describe-me.recorder');
|
|
|
237
260
|
*/
|
|
238
261
|
function sharedRecorder() {
|
|
239
262
|
const scope = globalThis;
|
|
240
|
-
scope[RECORDER_KEY]
|
|
241
|
-
|
|
263
|
+
const existing = scope[RECORDER_KEY];
|
|
264
|
+
if (existing === undefined) {
|
|
265
|
+
const created = new Recorder();
|
|
266
|
+
scope[RECORDER_KEY] = created;
|
|
267
|
+
return created;
|
|
268
|
+
}
|
|
269
|
+
const found = protocolOf(existing);
|
|
270
|
+
if (found !== RECORDER_PROTOCOL) {
|
|
271
|
+
throw new Error(`describe-me: all describe-me packages must be on the same version. Another copy of @describe-me/core created the test recorder (protocol ${found ?? 'none'}, expected ${RECORDER_PROTOCOL}). Install @describe-me/core, @describe-me/react, @describe-me/vitest and describe-me at one version.`);
|
|
272
|
+
}
|
|
273
|
+
return existing;
|
|
242
274
|
}
|
|
243
275
|
export const recorder = sharedRecorder();
|
package/dist/types.d.ts
CHANGED
|
@@ -157,8 +157,17 @@ export interface ComponentDoc {
|
|
|
157
157
|
file: string;
|
|
158
158
|
props: PropDoc[];
|
|
159
159
|
}
|
|
160
|
+
/** The package that wrote a manifest. */
|
|
161
|
+
export interface ManifestGenerator {
|
|
162
|
+
/** The package name, e.g. `@describe-me/vitest`. */
|
|
163
|
+
name: string;
|
|
164
|
+
/** Its version, e.g. `0.5.1`. */
|
|
165
|
+
version: string;
|
|
166
|
+
}
|
|
160
167
|
export interface Manifest {
|
|
161
168
|
version: 1;
|
|
169
|
+
/** The package and version that wrote the manifest. Absent in manifests written before 0.5.1. */
|
|
170
|
+
generator?: ManifestGenerator;
|
|
162
171
|
generatedAt: string;
|
|
163
172
|
root: string;
|
|
164
173
|
modules: ManifestModule[];
|
|
@@ -186,6 +195,12 @@ export interface Manifest {
|
|
|
186
195
|
* manifests written before 0.5, which counts as empty.
|
|
187
196
|
*/
|
|
188
197
|
remoteStylesheets?: RemoteStylesheet[];
|
|
198
|
+
/**
|
|
199
|
+
* Problems the plugin found in the project's setup, one sentence each.
|
|
200
|
+
* Absent when there are none and in manifests written before 0.5.1, which
|
|
201
|
+
* counts as empty.
|
|
202
|
+
*/
|
|
203
|
+
setupWarnings?: string[];
|
|
189
204
|
}
|
|
190
205
|
/** A font family that the captured CSS uses but no `@font-face`, font stylesheet or preview head loads. */
|
|
191
206
|
export interface FontMissing {
|
|
@@ -223,4 +238,6 @@ export interface ManifestDiagnostics {
|
|
|
223
238
|
fontsMissing: FontMissing[];
|
|
224
239
|
/** Hosts that frames load stylesheets from. */
|
|
225
240
|
remoteStylesheets: RemoteStylesheet[];
|
|
241
|
+
/** Problems in the project's setup that can make tests fail. */
|
|
242
|
+
setupWarnings: string[];
|
|
226
243
|
}
|