Skip to content

Commit de59a45

Browse files
authored
RFC 177 - fetch_json and other ShadowRealm facilities (#177)
Request for feedback on the APIs proposed in web-platform-tests/wpt#43639 adding some facilities for executing existing tests inside ShadowRealm global contexts.
1 parent fee37d8 commit de59a45

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

rfcs/fetch_json_et_al.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# RFC 177: `fetch_json` and other `ShadowRealm` facilities
2+
3+
## Summary
4+
5+
This follows up [RFC 107][rfc-107].
6+
[`ShadowRealm`s][proposal] are a new sandboxing primitive, currently in
7+
the process of being integrated into relevant Web specifications.
8+
`ShadowRealm` environments resemble vanilla JS shell environments, but
9+
do have some Web interfaces available, such as `URL`.
10+
11+
I've submitted a [pull request][pr] with some changes to the
12+
test harness.
13+
The goal is to more easily allow existing WPT test files to run in
14+
`ShadowRealm` contexts, without writing separate duplicated tests for
15+
`ShadowRealm`.
16+
17+
The most notable change is a `fetch_json` function to allow importing
18+
test data from JSON files across the sandboxing boundary.
19+
20+
## Details
21+
22+
The [pull request][pr] comprises four commits, which I'll explain in
23+
detail in this section.
24+
25+
### Document self.GLOBAL.isShadowRealm()
26+
27+
This commit is just an improvement to the documentation.
28+
29+
### Add fetch_json() test harness API
30+
31+
A common pattern for importing additional test data from a JSON file
32+
looks like this:
33+
34+
```js
35+
promise_test(() => fetch("resources/mydata.json").then(res => res.json()).then(run_tests), "Loading data…");
36+
```
37+
38+
`ShadowRealm` scopes do not have the `fetch()` API available.
39+
Additionally, the sandboxing only allows primitive or callable values
40+
to be passed into or out of the sandbox, not other objects.
41+
Therefore, this approach isn't feasible for `ShadowRealm` scopes.
42+
43+
The proposed `fetch_json()`, in non-`ShadowRealm` scopes, is just a
44+
shorthand for the above: call `fetch()`, and then call the returned
45+
`Response` object's `json()` method.
46+
47+
Inside `ShadowRealm` scopes, it is overwritten by a function that calls
48+
the host realm's `fetch()`, passes the response in string form across
49+
the sandbox boundary, and then inside the sandbox turns it into an
50+
object using `JSON.parse()`.
51+
52+
The previous pattern described above will continue to work in
53+
non-`ShadowRealm` scopes, but if a test is to be executed inside a
54+
`ShadowRealm` scope, it will need to change to a pattern like the
55+
following:
56+
57+
```js
58+
promise_test(() => fetch_json("resources/mydata.json").then(run_tests), "Loading data…");
59+
```
60+
61+
### Expose location.search in ShadowRealm scopes
62+
63+
Browser-specifc APIs such as `location` are not available in
64+
`ShadowRealm` scopes.
65+
However, the [mechanism for variant tests][variant] relies on
66+
`location.search`.
67+
68+
This proposed change would expose a fake `location.search`, with the
69+
same value as the host realm's `location.search`, inside `ShadowRealm`
70+
scopes.
71+
This would allow test variants to be executed in `ShadowRealm` scopes.
72+
73+
### Use fake setTimeout in ShadowRealm scopes
74+
75+
`ShadowRealm` scopes also do not have timer-related APIs such as
76+
`setTimeout` and friends.
77+
However, several facilities from `testharness.js`, namely
78+
[`Test.step_timeout`][step_timeout], [`Test.step_wait`][step_wait], and
79+
[`Test.step_wait_func`][step_wait_func], rely on the global `setTimeout`
80+
being present.
81+
82+
This proposed change adds a fallback version of `setTimeout` which is
83+
used by the test harness when the global one is not present, i.e. in
84+
`ShadowRealm` scopes.
85+
The fallback is not exposed directly to test code.
86+
87+
## Risks
88+
89+
The documentation commit carries no risk.
90+
91+
The `fetch_json()` API doesn't change how any existing APIs work.
92+
Existing tests would have to opt-in to it by replacing their use of
93+
`fetch()` to import JSON test data, with `fetch_json()`.
94+
A natural time to make this change is when enabling a test to run in a
95+
`ShadowRealm` global scope; otherwise the test won't pass.
96+
Therefore, I think the potential risk is low.
97+
98+
Of the four proposed changes, the fake `location.search` has the biggest
99+
potential risk.
100+
It's possible that future `ShadowRealm`-scope tests might depend on the
101+
`location` object not being present.
102+
This seems acceptable for the time being.
103+
But if that changes, the variant mechanism in files such as
104+
`common/subset-tests.js` and `common/subset-tests-by-key.js` would need
105+
to be rewritten to indicate which variant to run using a different
106+
mechanism than the URL search parameters.
107+
108+
The fake `setTimeout` should not affect any existing tests.
109+
In non-`ShadowRealm` scopes, the behaviour should remain the same,
110+
because `setTimeout` is available.
111+
In `ShadowRealm` scopes, use of test harness APIs such as `step_timeout`
112+
would previously fail due to the missing `setTimeout`; now they can be
113+
used.
114+
Therefore, I think the potential risk is low.
115+
116+
[rfc-107]: https://github.com/web-platform-tests/rfcs/blob/master/rfcs/shadowrealm-global.md
117+
[proposal]: https://github.com/tc39/proposal-shadowrealm
118+
[pr]: https://github.com/web-platform-tests/wpt/pull/43639
119+
[variant]: https://web-platform-tests.org/writing-tests/testharness.html#variants
120+
[step_timeout]: https://web-platform-tests.org/writing-tests/testharness-api.html#Test.step_timeout
121+
[step_wait]: https://web-platform-tests.org/writing-tests/testharness-api.html#Test.step_wait
122+
[step_wait_func]: https://web-platform-tests.org/writing-tests/testharness-api.html#Test.step_wait_func

0 commit comments

Comments
 (0)