@uniflowed/test 0.5.0 → 0.6.0
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.
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import type { BrowserTransport, ControlOptions } from "./cdp.js";
|
|
3
|
+
import { runnerFetch } from "./runner-fetch.js";
|
|
3
4
|
|
|
4
5
|
export async function createTransport(options: ControlOptions): Promise<BrowserTransport> {
|
|
5
6
|
if (options.executable != null)
|
|
@@ -12,7 +13,8 @@ export async function createTransport(options: ControlOptions): Promise<BrowserT
|
|
|
12
13
|
method: string,
|
|
13
14
|
args: $ReadOnlyArray<mixed> = [],
|
|
14
15
|
): Promise<$FlowFixMe> {
|
|
15
|
-
|
|
16
|
+
// The platform's `fetch`, not the global a test's request mock replaced.
|
|
17
|
+
const response = await runnerFetch("/uf-test/browser", {
|
|
16
18
|
method: "POST",
|
|
17
19
|
headers: { "content-type": "application/json", "uf-test-browser": token },
|
|
18
20
|
body: JSON.stringify({ id, method, args }),
|
package/internal/browser/page.js
CHANGED
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
import * as output from "../output.js";
|
|
38
38
|
import { run } from "../run.js";
|
|
39
39
|
import { installInSourceTests } from "../../in-source.js";
|
|
40
|
+
import { runnerFetch } from "./runner-fetch.js";
|
|
40
41
|
|
|
41
42
|
/** One file, as the server hands it over. */
|
|
42
43
|
type PageRequest = {
|
|
@@ -74,7 +75,9 @@ function flush(): Promise<void> {
|
|
|
74
75
|
if (already != null) return already;
|
|
75
76
|
if (queue.length === 0) return Promise.resolve();
|
|
76
77
|
const batch = queue.splice(0, queue.length);
|
|
77
|
-
|
|
78
|
+
// Not the global: a file that installed a request mock owns that one, and
|
|
79
|
+
// would answer the runner's report as an unhandled request.
|
|
80
|
+
const sent = runnerFetch("/uf-test/events", {
|
|
78
81
|
method: "POST",
|
|
79
82
|
headers: { "content-type": "application/json" },
|
|
80
83
|
body: JSON.stringify(batch),
|
|
@@ -195,7 +198,7 @@ function page(): $FlowFixMe {
|
|
|
195
198
|
async function serve(): Promise<void> {
|
|
196
199
|
let request: PageRequest;
|
|
197
200
|
try {
|
|
198
|
-
request = await (await
|
|
201
|
+
request = await (await runnerFetch("/uf-test/next")).json();
|
|
199
202
|
} catch {
|
|
200
203
|
// The driver has gone. Nothing to report it to.
|
|
201
204
|
return;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
//
|
|
3
|
+
// Internal to `@uniflowed/test`: the `fetch` the browser runner talks to `uf`
|
|
4
|
+
// with.
|
|
5
|
+
//
|
|
6
|
+
// A page reports its results over HTTP — `POST /uf-test/events`, and
|
|
7
|
+
// `POST /uf-test/browser` for `createBrowser` — and the file under test runs
|
|
8
|
+
// in that same page. A file that installs a request mock replaces
|
|
9
|
+
// `globalThis.fetch`, and `@uniflowed/mock`'s default policy rejects every
|
|
10
|
+
// request no handler claimed. Reached through the global, the runner's own
|
|
11
|
+
// requests would be answered by the test's mock: rejected, and the rejection
|
|
12
|
+
// swallowed by the reporter, so the results would never reach `uf test`
|
|
13
|
+
// (ubugeeei-prod/uf#1394).
|
|
14
|
+
//
|
|
15
|
+
// So the harness captures the platform's `fetch` in a classic script that runs
|
|
16
|
+
// before any module — before the runner, and so before any test file could
|
|
17
|
+
// replace it — and the runner's requests go through that capture. A constant
|
|
18
|
+
// captured in this module would depend on when it was first evaluated and on
|
|
19
|
+
// `page.js` and the import map reaching it by the same URL; the harness
|
|
20
|
+
// script depends on neither.
|
|
21
|
+
|
|
22
|
+
/** Where `server.js`'s harness leaves the platform's `fetch`. */
|
|
23
|
+
export const RUNNER_FETCH: symbol = Symbol.for("uf.test.browser.fetch");
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `fetch`, as it was before any test file ran.
|
|
27
|
+
*
|
|
28
|
+
* Falls back to the global when nothing was captured, which is a page not
|
|
29
|
+
* served by `uf test --browser` — there is no test file ahead of it to have
|
|
30
|
+
* replaced anything.
|
|
31
|
+
*/
|
|
32
|
+
export function runnerFetch(input: RequestInfo, init?: RequestOptions): Promise<Response> {
|
|
33
|
+
const captured = Reflect.get(globalThis, RUNNER_FETCH);
|
|
34
|
+
if (typeof captured === "function") {
|
|
35
|
+
return captured(input, init);
|
|
36
|
+
}
|
|
37
|
+
return fetch(input, init);
|
|
38
|
+
}
|
|
@@ -639,6 +639,10 @@ function harnessHtml(map: string, browserToken: string): string {
|
|
|
639
639
|
'<meta charset="utf-8">',
|
|
640
640
|
"<title>uf test</title>",
|
|
641
641
|
`<script>globalThis[Symbol.for("uf.test.browser.token")]=${JSON.stringify(browserToken)}</script>`,
|
|
642
|
+
// Before any module, so before any test file can replace it: the runner
|
|
643
|
+
// reports through this `fetch`, never through a mocked global. See
|
|
644
|
+
// `./runner-fetch.js`.
|
|
645
|
+
'<script>globalThis[Symbol.for("uf.test.browser.fetch")]=globalThis.fetch.bind(globalThis)</script>',
|
|
642
646
|
`<script type="importmap">${map}</script>`,
|
|
643
647
|
`<script type="module" src="${page}"></script>`,
|
|
644
648
|
"",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniflowed/test",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "The test API and worker for `uf test`: describe/it, a full matcher set, and the process uf fans test files out to.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"!*.test.js"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@uniflowed/host": "0.
|
|
41
|
+
"@uniflowed/host": "0.6.0",
|
|
42
42
|
"pixelmatch": "^7.1.0",
|
|
43
43
|
"pngjs": "^7.0.0"
|
|
44
44
|
},
|