Skip to content

Commit d8dc2b8

Browse files
committed
RFC 86: fetch_tests_from_prefixed_local_storage
1 parent f22d3e7 commit d8dc2b8

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# RFC 86: Add `fetch_tests_from_prefixed_local_storage` method
2+
3+
## Summary
4+
5+
Add `fetch_tests_from_prefixed_local_storage` method that fetches test results from another page via local storage and `/common/PrefixedLocalStorage.js`.
6+
This is similar to `fetch_tests_from_window`, but is designed for cases where direct communication channels including `postMessage` are not available, like a `Window` opened by `window.open(url, "noopener")`.
7+
8+
This is primarily for the use in [Back-foward cache WPTs](https://github.com/web-platform-tests/wpt/pull/28950), but can be also used for other tests involving isolated Windows or top-level navigations.
9+
10+
## Details
11+
12+
Testing things requiring isolated windows is not well supported by the WPT frameworks.
13+
For example, when `A.html` calls `window.open('B.html', 'noopener')` and tests something on `B.html`, `B.html` sends data to `A.html` and `A.html` calls `testharness.js` APIs like `assert_equals()` on the data, like:
14+
15+
A.html:
16+
```
17+
async_test(t => {
18+
window.open(prefixedLocalStorage.url('B.html'), '_blank', 'noopener');
19+
wait_for_result();
20+
assert_equals(localStorage.getItem('result'), 'expected');
21+
});
22+
```
23+
24+
B.html:
25+
```
26+
localStorage.setItem('result', doSomethingAndGetResult());
27+
```
28+
29+
The problems here are:
30+
31+
- Test logic often spreads across multiple HTMLs, which can make the logic and its failure mode unclear.
32+
- we need non-`postMessage` communication mechanisms (which tend to be one-off; see below for existing examples).
33+
34+
Instead, this RFC proposes
35+
36+
- Writing tests using `testharness.js` APIs on isolated Windows (`B.html` in the example above), and
37+
- Communicating test results within a new API `fetch_tests_from_prefixed_local_storage` in `testharness.js` from the isolated Windows to the main test Window (`A.html` in the example).
38+
39+
A.html:
40+
```
41+
const prefixedLocalStorage = new PrefixedLocalStorageTest();
42+
fetch_tests_from_prefixed_local_storage(prefixedLocalStorage);
43+
window.open(prefixedLocalStorage.url('B.html'), '_blank', 'noopener');
44+
```
45+
46+
B.html:
47+
```
48+
async_test(t => {
49+
assert_equals(doSomethingAndGetResult(), 'expected');
50+
});
51+
```
52+
53+
By doing so,
54+
55+
- More test logic can be centralized to `B.html`, especially when the most of the test logic can be done in `B.html` and `window.open() + noopener` is needed just to create a separate browsing context (this is the case for most of the BFCache tests).
56+
- Communication implementation is encapsulated within `testharness.js`, instead of within individual tests.
57+
58+
## Risks
59+
60+
We might want to change the implementations within `fetch_tests_from_prefixed_local_storage`, when
61+
62+
* More use cases are to be supported (like cross-origin Windows)
63+
* `localStorage` spec or implementation is changed
64+
65+
This kind of risks is somehow inherent regardless of communication methods we use, because we anyway want communications between isolated Windows, which might be blocked by security/privacy efforts.
66+
67+
Changes needed will be anyway small, because I expect
68+
69+
* We only have to change the implementation within `fetch_tests_from_prefixed_local_storage` and boilerplate-like code on its caller side, (hopefully) not the test contents, given that the APIs supported in the test contents are stable `testharness.js` APIs.
70+
* The number of tests using `fetch_tests_from_prefixed_local_storage` will be limited.
71+
72+
## Existing communication helpers
73+
74+
Existing tests (WPT or Chromium, mainly those with `window.open()` + `noopener`) uses several communication mechanisms/helpers for this purpose.
75+
76+
- localStorage
77+
- [/wpt/common/PrefixedLocalStorage.js](https://github.com/web-platform-tests/wpt/blob/master/common/PrefixedLocalStorage.js)
78+
- e.g. used by [/wpt/html/browsers/windows/auxiliary-browsing-contexts/opener-noopener.html](https://github.com/web-platform-tests/wpt/blob/master/html/browsers/windows/auxiliary-browsing-contexts/opener-noopener.html)
79+
- sessionStorage
80+
- [http/tests/navigation/resources/back-to-get-after-post-helper.html](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/http/tests/navigation/resources/back-to-get-after-post-helper.html)
81+
- Fetch API + server-side stash
82+
- [/wpt/scroll-to-text-fragment/stash.js](https://github.com/web-platform-tests/wpt/blob/master/scroll-to-text-fragment/stash.js)
83+
- [/wpt/html/browsers/windows/resources/window-name-stash.py](https://github.com/web-platform-tests/wpt/blob/master/html/browsers/windows/resources/window-name-stash.py)
84+
- [/wpt_internal/prerender/resources/key-value-store.py](third_party/blink/web_tests/wpt_internal/prerender/resources/key-value-store.py)
85+
86+
## Alternatives Considered
87+
88+
### Fetch API + server-side stash instead of `localStorage`
89+
90+
- pros: More robust than `localStorage`: Fetch API will be less affected by efforts to block communications between windows, and works even in cross-origin cases.
91+
- cons: Fetch API is async, and pages with open fetch requests are not BFCache-eligible in Chromium. Therefore, a little more coordination is needed to ensure the fetch requests for accessing stash are closed before navigation.
92+
93+
### BroadcastChannel instead of `localStorage`
94+
95+
- cons: Pages with open BroadcastChannels is not BFCache-eligible in Chromium.
96+
- cons: BroadcastChannel is not supported in Safari.
97+
98+
### Introduce a new class of tests that drive the browser from the outside
99+
100+
Instead of writing tests and passing data within JavaScript, introduce a new class of tests and its infrastructure controling the browser "from the outside", much more like WebDriver tests.
101+
102+
- cons: Design and implementation costs are much higher.
103+
- It would be preferable to create a design that covers a broader use cases like navigation, BFCache, prerendering, etc., but right now I don't have clear ideas (both on design/implementation and use cases).

0 commit comments

Comments
 (0)