http-snapshotter 0.6.1-beta.2 → 0.6.2
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 +25 -0
- package/index.d.ts +22 -0
- package/index.js +61 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -230,3 +230,28 @@ resetSnapshotIgnoreRules();
|
|
|
230
230
|
**Behavior varies by mode:**
|
|
231
231
|
- `SNAPSHOT=update/append`: Ignored requests make real network calls but don't create snapshots
|
|
232
232
|
- `SNAPSHOT=read`: Ignored requests throw an error (tests shouldn't make real network calls)
|
|
233
|
+
|
|
234
|
+
## Passthrough requests from snapshots
|
|
235
|
+
|
|
236
|
+
If a request should explicitly be allowed to hit the real network in every mode, including
|
|
237
|
+
`SNAPSHOT=read`, use `attachSnapshotPassthroughRules()` instead:
|
|
238
|
+
|
|
239
|
+
```js
|
|
240
|
+
import {
|
|
241
|
+
attachSnapshotPassthroughRules,
|
|
242
|
+
resetSnapshotPassthroughRules,
|
|
243
|
+
} from "http-snapshotter";
|
|
244
|
+
|
|
245
|
+
attachSnapshotPassthroughRules((request) => {
|
|
246
|
+
const url = new URL(request.url);
|
|
247
|
+
return url.hostname === "portal.sso.eu-west-1.amazonaws.com"
|
|
248
|
+
&& url.pathname === "/federation/credentials";
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
resetSnapshotPassthroughRules();
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Behavior:**
|
|
255
|
+
- Requests matching passthrough rules always make real network calls
|
|
256
|
+
- Requests matching passthrough rules never create or read snapshots
|
|
257
|
+
- Passthrough rules take precedence over ignore rules
|
package/index.d.ts
CHANGED
|
@@ -125,6 +125,28 @@ export function defaultSnapshotIgnoreRules(_request: Request): boolean;
|
|
|
125
125
|
export function attachSnapshotIgnoreRules(func: (req: Request) => boolean): void;
|
|
126
126
|
/** Reset snapshot ignore rules to default (no requests ignored) */
|
|
127
127
|
export function resetSnapshotIgnoreRules(): void;
|
|
128
|
+
/**
|
|
129
|
+
* Default snapshot passthrough rules - by default no requests bypass snapshotting
|
|
130
|
+
* @param {Request} _request
|
|
131
|
+
* @returns {boolean}
|
|
132
|
+
*/
|
|
133
|
+
export function defaultSnapshotPassthroughRules(_request: Request): boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Attach snapshot passthrough rules function
|
|
136
|
+
*
|
|
137
|
+
* Use this when a request should explicitly bypass snapshotting and always be allowed to hit
|
|
138
|
+
* the real network, regardless of SNAPSHOT mode.
|
|
139
|
+
*
|
|
140
|
+
* Passthrough rules take precedence over ignore rules.
|
|
141
|
+
*
|
|
142
|
+
* WARNING: Attaching a function on a per-test basis may not be concurrent safe. i.e. If your tests
|
|
143
|
+
* run sequentially, then it is safe. But if your test runner runs test suites concurrently,
|
|
144
|
+
* then it is better to attach a function only once ever.
|
|
145
|
+
* @param {(req: Request) => boolean} func
|
|
146
|
+
*/
|
|
147
|
+
export function attachSnapshotPassthroughRules(func: (req: Request) => boolean): void;
|
|
148
|
+
/** Reset snapshot passthrough rules to default (no requests bypass snapshotting) */
|
|
149
|
+
export function resetSnapshotPassthroughRules(): void;
|
|
128
150
|
/**
|
|
129
151
|
* Start the interceptor
|
|
130
152
|
* @param {object} opts
|
package/index.js
CHANGED
|
@@ -179,6 +179,15 @@ function defaultSnapshotIgnoreRules(_request) {
|
|
|
179
179
|
return false;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Default snapshot passthrough rules - by default no requests bypass snapshotting
|
|
184
|
+
* @param {Request} _request
|
|
185
|
+
* @returns {boolean}
|
|
186
|
+
*/
|
|
187
|
+
function defaultSnapshotPassthroughRules(_request) {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
|
|
182
191
|
// Dynamically changeable props
|
|
183
192
|
/**
|
|
184
193
|
* @type {(req: Request) => Promise<{ filePrefix: string, fileSuffixKey: string }>}
|
|
@@ -190,6 +199,10 @@ let snapshotSubDirectory = '';
|
|
|
190
199
|
* @type {(req: Request) => boolean}
|
|
191
200
|
*/
|
|
192
201
|
let snapshotIgnoreRules = defaultSnapshotIgnoreRules;
|
|
202
|
+
/**
|
|
203
|
+
* @type {(req: Request) => boolean}
|
|
204
|
+
*/
|
|
205
|
+
let snapshotPassthroughRules = defaultSnapshotPassthroughRules;
|
|
193
206
|
|
|
194
207
|
/**
|
|
195
208
|
* @typedef SnapshotFileInfo
|
|
@@ -674,6 +687,28 @@ function resetSnapshotIgnoreRules() {
|
|
|
674
687
|
snapshotIgnoreRules = defaultSnapshotIgnoreRules;
|
|
675
688
|
}
|
|
676
689
|
|
|
690
|
+
/**
|
|
691
|
+
* Attach snapshot passthrough rules function
|
|
692
|
+
*
|
|
693
|
+
* Use this when a request should explicitly bypass snapshotting and always be allowed to hit
|
|
694
|
+
* the real network, regardless of SNAPSHOT mode.
|
|
695
|
+
*
|
|
696
|
+
* Passthrough rules take precedence over ignore rules.
|
|
697
|
+
*
|
|
698
|
+
* WARNING: Attaching a function on a per-test basis may not be concurrent safe. i.e. If your tests
|
|
699
|
+
* run sequentially, then it is safe. But if your test runner runs test suites concurrently,
|
|
700
|
+
* then it is better to attach a function only once ever.
|
|
701
|
+
* @param {(req: Request) => boolean} func
|
|
702
|
+
*/
|
|
703
|
+
function attachSnapshotPassthroughRules(func) {
|
|
704
|
+
snapshotPassthroughRules = func;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/** Reset snapshot passthrough rules to default (no requests bypass snapshotting) */
|
|
708
|
+
function resetSnapshotPassthroughRules() {
|
|
709
|
+
snapshotPassthroughRules = defaultSnapshotPassthroughRules;
|
|
710
|
+
}
|
|
711
|
+
|
|
677
712
|
/**
|
|
678
713
|
* Start the interceptor
|
|
679
714
|
* @param {object} opts
|
|
@@ -701,9 +736,16 @@ function start({
|
|
|
701
736
|
|
|
702
737
|
const cache = /** @type {WeakMap<Request, SnapshotFileInfo>} */ (new WeakMap());
|
|
703
738
|
const ignoredRequests = /** @type {WeakSet<Request>} */ (new WeakSet());
|
|
739
|
+
const passthroughRequests = /** @type {WeakSet<Request>} */ (new WeakSet());
|
|
704
740
|
|
|
705
741
|
//@ts-ignore
|
|
706
742
|
interceptor.on('request', async ({ request, controller }) => {
|
|
743
|
+
const shouldPassthroughSnapshot = snapshotPassthroughRules(request);
|
|
744
|
+
if (shouldPassthroughSnapshot) {
|
|
745
|
+
passthroughRequests.add(request);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
|
|
707
749
|
// Check if request should be ignored from snapshotting using ignore rules
|
|
708
750
|
const shouldIgnoreSnapshot = snapshotIgnoreRules(request);
|
|
709
751
|
|
|
@@ -739,19 +781,22 @@ function start({
|
|
|
739
781
|
'response',
|
|
740
782
|
/** @type {(params: { request: Request, response: Response }) => Promise<void>} */
|
|
741
783
|
async ({ request, response }) => {
|
|
784
|
+
const shouldPassthroughSnapshot = passthroughRequests.has(request);
|
|
742
785
|
// Check if this request was marked to ignore snapshots
|
|
743
786
|
const shouldIgnoreSnapshot = ignoredRequests.has(request);
|
|
744
|
-
|
|
745
|
-
const snapshotFileInfo =
|
|
787
|
+
|
|
788
|
+
const snapshotFileInfo = shouldPassthroughSnapshot
|
|
789
|
+
? null
|
|
790
|
+
: (cache.get(request) || (await getSnapshotFileInfo(request)));
|
|
746
791
|
cache.delete(request);
|
|
747
|
-
|
|
748
|
-
const
|
|
749
|
-
|
|
750
|
-
fileName,
|
|
751
|
-
fileSuffixKey,
|
|
752
|
-
} = snapshotFileInfo;
|
|
792
|
+
|
|
793
|
+
const fileName = snapshotFileInfo?.fileName;
|
|
794
|
+
const fileSuffixKey = snapshotFileInfo?.fileSuffixKey;
|
|
753
795
|
if (LOG_REQ) {
|
|
754
796
|
const summary = `----------\n${request.method} ${request.url}\n${
|
|
797
|
+
shouldPassthroughSnapshot
|
|
798
|
+
? 'passed through by passthrough rules'
|
|
799
|
+
:
|
|
755
800
|
shouldIgnoreSnapshot
|
|
756
801
|
? 'ignored from snapshotting by ignore rules'
|
|
757
802
|
: `Would use file name: ${fileName}`
|
|
@@ -776,12 +821,14 @@ function start({
|
|
|
776
821
|
});
|
|
777
822
|
}
|
|
778
823
|
}
|
|
779
|
-
if (!
|
|
824
|
+
if (!shouldPassthroughSnapshot
|
|
825
|
+
&& !shouldIgnoreSnapshot
|
|
826
|
+
&& (SNAPSHOT === 'update' || (SNAPSHOT === 'append' && !readFiles.has(fileName)))) {
|
|
780
827
|
if (!dirCreatePromise) {
|
|
781
828
|
dirCreatePromise = fs.mkdir( /** @type {string} */(snapshotDirectory), { recursive: true });
|
|
782
829
|
}
|
|
783
830
|
await dirCreatePromise;
|
|
784
|
-
await saveSnapshot(request, response, snapshotFileInfo);
|
|
831
|
+
await saveSnapshot(request, response, /** @type {SnapshotFileInfo} */ (snapshotFileInfo));
|
|
785
832
|
}
|
|
786
833
|
},
|
|
787
834
|
);
|
|
@@ -806,6 +853,9 @@ module.exports = {
|
|
|
806
853
|
defaultSnapshotIgnoreRules,
|
|
807
854
|
attachSnapshotIgnoreRules,
|
|
808
855
|
resetSnapshotIgnoreRules,
|
|
856
|
+
defaultSnapshotPassthroughRules,
|
|
857
|
+
attachSnapshotPassthroughRules,
|
|
858
|
+
resetSnapshotPassthroughRules,
|
|
809
859
|
start,
|
|
810
860
|
stop,
|
|
811
|
-
};
|
|
861
|
+
};
|