@browsercore/testing 0.1.0 → 0.1.3
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
CHANGED
|
@@ -39,12 +39,13 @@ interoperability:
|
|
|
39
39
|
In short:
|
|
40
40
|
|
|
41
41
|
- **Golden packet testing** — load `.bin` captures recorded from real browsers
|
|
42
|
-
(Chrome 140,
|
|
43
|
-
ClientHellos, HTTP/2 SETTINGS/HEADERS frames, etc. against them.
|
|
42
|
+
(Chrome 140 (tls, http2), Firefox 128 (tls)) and compare our generated TLS
|
|
43
|
+
ClientHellos, HTTP/2 SETTINGS/HEADERS frames, etc. against them. Safari 18,
|
|
44
|
+
Edge 140, and Firefox 135 captures are not yet collected.
|
|
44
45
|
- **RFC compliance** — run focused test suites for TLS 1.3 (RFC 8446), HTTP/2
|
|
45
|
-
(RFC 9113), HTTP/1.1 (RFC 9110).
|
|
46
|
+
(RFC 9113), HTTP/1.1 (RFC 9110). These are currently stubs that throw.
|
|
46
47
|
- **Benchmarking** — measure handshake latency and request throughput at
|
|
47
|
-
p50/p95/p99.
|
|
48
|
+
p50/p95/p99. These are currently stubs that throw.
|
|
48
49
|
|
|
49
50
|
## Public API
|
|
50
51
|
|
|
@@ -60,13 +61,13 @@ import {
|
|
|
60
61
|
const result = compareAgainstGolden(myClientHello, "chrome-140:client-hello:1" as never);
|
|
61
62
|
console.log(result.matches);
|
|
62
63
|
|
|
63
|
-
// Run the TLS RFC compliance suite:
|
|
64
|
-
const tlsResult = runTlsCompliance();
|
|
65
|
-
console.log(tlsResult.pass);
|
|
64
|
+
// Run the TLS RFC compliance suite (stub — throws until implemented):
|
|
65
|
+
// const tlsResult = runTlsCompliance();
|
|
66
|
+
// console.log(tlsResult.pass);
|
|
66
67
|
|
|
67
|
-
// Benchmark a TLS handshake over 100 iterations:
|
|
68
|
-
const stats = benchmarkTlsHandshake(100);
|
|
69
|
-
console.log("p99:", stats.p99, "ms");
|
|
68
|
+
// Benchmark a TLS handshake over 100 iterations (stub — throws until implemented):
|
|
69
|
+
// const stats = benchmarkTlsHandshake(100);
|
|
70
|
+
// console.log("p99:", stats.p99, "ms");
|
|
70
71
|
```
|
|
71
72
|
|
|
72
73
|
## Types
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Test Category 9 — Compression.
|
|
3
3
|
*
|
|
4
|
-
* Verify gzip, brotli, deflate decoding behavior
|
|
5
|
-
* (
|
|
4
|
+
* Verify gzip, brotli, deflate decoding behavior matches the Node.js reference
|
|
5
|
+
* oracle (`nodeZlib`). The system under test is `@browsercore/compression`;
|
|
6
|
+
* `nodeZlib` is the spec reference for these primitive layers. See
|
|
7
|
+
* docs/TEST-SUITE.md ("Test Category 9 — Compression") for full acceptance
|
|
8
|
+
* criteria.
|
|
6
9
|
*/
|
|
7
10
|
export declare const CATEGORY_ID: "compression";
|
|
8
11
|
//# sourceMappingURL=compression.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../../src/categories/compression.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../../src/categories/compression.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,eAAO,MAAM,WAAW,eAA2B,CAAC"}
|
|
@@ -1,15 +1,63 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Test Category 9 — Compression.
|
|
3
3
|
*
|
|
4
|
-
* Verify gzip, brotli, deflate decoding behavior
|
|
5
|
-
* (
|
|
4
|
+
* Verify gzip, brotli, deflate decoding behavior matches the Node.js reference
|
|
5
|
+
* oracle (`nodeZlib`). The system under test is `@browsercore/compression`;
|
|
6
|
+
* `nodeZlib` is the spec reference for these primitive layers. See
|
|
7
|
+
* docs/TEST-SUITE.md ("Test Category 9 — Compression") for full acceptance
|
|
8
|
+
* criteria.
|
|
6
9
|
*/
|
|
7
|
-
import {
|
|
10
|
+
import { deflateRawSync } from "node:zlib";
|
|
11
|
+
import { describe, expect, it } from "vitest";
|
|
12
|
+
import { compression, UnsupportedEncodingError, } from "@browsercore/compression";
|
|
13
|
+
import { nodeZlib } from "../reference/node-reference.js";
|
|
8
14
|
import { TestCategory } from "../types.js";
|
|
9
15
|
export const CATEGORY_ID = TestCategory.Compression;
|
|
16
|
+
/** Deterministic payload: byte[i] = i % 256 (reproducible, never random). */
|
|
17
|
+
function detBuffer(length) {
|
|
18
|
+
const bytes = new Uint8Array(length);
|
|
19
|
+
for (let i = 0; i < length; i++) {
|
|
20
|
+
bytes[i] = i % 256;
|
|
21
|
+
}
|
|
22
|
+
return bytes;
|
|
23
|
+
}
|
|
10
24
|
describe(CATEGORY_ID, () => {
|
|
11
|
-
|
|
12
|
-
it
|
|
13
|
-
|
|
25
|
+
const payload = detBuffer(1024);
|
|
26
|
+
it("gzip decoding matches reference", () => {
|
|
27
|
+
const compressed = nodeZlib.gzip(payload);
|
|
28
|
+
const ours = compression.gunzip(compressed);
|
|
29
|
+
const theirs = nodeZlib.gunzip(compressed);
|
|
30
|
+
expect(ours).toEqual(theirs);
|
|
31
|
+
expect(ours).toEqual(payload);
|
|
32
|
+
});
|
|
33
|
+
it("brotli decoding matches reference", () => {
|
|
34
|
+
const compressed = nodeZlib.brotliCompress(payload);
|
|
35
|
+
const ours = compression.brotliDecompress(compressed);
|
|
36
|
+
const theirs = nodeZlib.brotliDecompress(compressed);
|
|
37
|
+
expect(ours).toEqual(theirs);
|
|
38
|
+
expect(ours).toEqual(payload);
|
|
39
|
+
});
|
|
40
|
+
it("deflate decoding matches reference (zlib-wrapped)", () => {
|
|
41
|
+
const compressed = nodeZlib.deflate(payload);
|
|
42
|
+
const ours = compression.inflate(compressed);
|
|
43
|
+
const theirs = nodeZlib.inflate(compressed);
|
|
44
|
+
expect(ours).toEqual(theirs);
|
|
45
|
+
expect(ours).toEqual(payload);
|
|
46
|
+
});
|
|
47
|
+
it("deflate decoding falls back to raw inflate", () => {
|
|
48
|
+
// A genuinely raw deflate stream (no zlib header) — inflateSync
|
|
49
|
+
// rejects it, so decompress() must fall back to raw inflate. Built
|
|
50
|
+
// with node:zlib's deflateRawSync, the only decoder that accepts it.
|
|
51
|
+
const raw = new Uint8Array(deflateRawSync(payload));
|
|
52
|
+
expect(compression.decompress(raw, "deflate")).toEqual(payload);
|
|
53
|
+
});
|
|
54
|
+
it("decompress() dispatches on the content-encoding token", () => {
|
|
55
|
+
expect(compression.decompress(nodeZlib.gzip(payload), "gzip")).toEqual(payload);
|
|
56
|
+
expect(compression.decompress(nodeZlib.deflate(payload), "deflate")).toEqual(payload);
|
|
57
|
+
expect(compression.decompress(nodeZlib.brotliCompress(payload), "br")).toEqual(payload);
|
|
58
|
+
});
|
|
59
|
+
it("decompress() rejects an unsupported encoding", () => {
|
|
60
|
+
expect(() => compression.decompress(payload, "zstd")).toThrow(UnsupportedEncodingError);
|
|
61
|
+
});
|
|
14
62
|
});
|
|
15
63
|
//# sourceMappingURL=compression.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compression.js","sourceRoot":"","sources":["../../src/categories/compression.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"compression.js","sourceRoot":"","sources":["../../src/categories/compression.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@browsercore/testing",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Protocol verification
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Protocol verification \u2014 RFC compliance tests, browser golden packet captures, integration tests, and benchmarking.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/jverneuer/browsercore-testing.git"
|
|
@@ -20,7 +20,11 @@
|
|
|
20
20
|
"import": "./dist/index.js"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
|
-
"files": [
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
24
28
|
"publishConfig": {
|
|
25
29
|
"access": "public",
|
|
26
30
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -41,13 +45,14 @@
|
|
|
41
45
|
"node": ">=24.0.0"
|
|
42
46
|
},
|
|
43
47
|
"dependencies": {
|
|
44
|
-
"@browsercore/
|
|
45
|
-
"@browsercore/
|
|
46
|
-
"@browsercore/
|
|
47
|
-
"@browsercore/
|
|
48
|
-
"@browsercore/
|
|
49
|
-
"@browsercore/
|
|
50
|
-
"@browsercore/
|
|
51
|
-
"@browsercore/
|
|
48
|
+
"@browsercore/compression": "latest",
|
|
49
|
+
"@browsercore/cookies": "latest",
|
|
50
|
+
"@browsercore/crypto": "latest",
|
|
51
|
+
"@browsercore/fetch": "latest",
|
|
52
|
+
"@browsercore/http1": "latest",
|
|
53
|
+
"@browsercore/http2": "latest",
|
|
54
|
+
"@browsercore/profiles": "latest",
|
|
55
|
+
"@browsercore/tls": "latest",
|
|
56
|
+
"@browsercore/transport": "latest"
|
|
52
57
|
}
|
|
53
58
|
}
|