113 lines
4.9 KiB
JavaScript
113 lines
4.9 KiB
JavaScript
// This is a helper file used for the automatic-beacon-*.https.html tests.
|
|
// To use this, make sure you import these scripts:
|
|
// <script src="/resources/testharness.js"></script>
|
|
// <script src="/resources/testharnessreport.js"></script>
|
|
// <script src="/common/utils.js"></script>
|
|
// <script src="/common/dispatcher/dispatcher.js"></script>
|
|
// <script src="resources/utils.js"></script>
|
|
// <script src="/resources/testdriver.js"></script>
|
|
// <script src="/resources/testdriver-actions.js"></script>
|
|
// <script src="/resources/testdriver-vendor.js"></script>
|
|
// <script src="/common/get-host-info.sub.js"></script>
|
|
|
|
const NavigationTrigger = {
|
|
Click: 0,
|
|
ClickOnce: 1,
|
|
CrossOriginClick: 2,
|
|
CrossOriginClickNoOptIn: 3
|
|
};
|
|
|
|
// Registers an automatic beacon in a given remote context frame, and registers
|
|
// the navigation handler for the frame that will trigger the beacon.
|
|
// remote_context: The context for the fenced frame or URN iframe.
|
|
// beacon_events: An array of FenceEvents to register with the frame.
|
|
// navigation_url: The URL the frame will navigate to.
|
|
// navigation_trigger: How the navigation will be performed. Either through a
|
|
// click, a click with a `once` event, a click in a
|
|
// cross-origin subframe, or a click in a cross-origin
|
|
// subframe with no opt-in header.
|
|
// target: the target of the navigation. Either '_blank' or
|
|
// '_unfencedTop'.
|
|
async function setupAutomaticBeacon(
|
|
remote_context, beacon_events, navigation_url = 'resources/dummy.html',
|
|
navigation_trigger = NavigationTrigger.Click, target = '_blank') {
|
|
const full_url = new URL(navigation_url, location.href);
|
|
await remote_context.execute(
|
|
async (
|
|
NavigationTrigger, beacon_events, navigation_trigger, full_url,
|
|
target) => {
|
|
switch (navigation_trigger) {
|
|
case NavigationTrigger.Click:
|
|
addEventListener('click', (event) => {
|
|
beacon_events.forEach((beacon_event) => {
|
|
window.fence.setReportEventDataForAutomaticBeacons(
|
|
beacon_event);
|
|
});
|
|
window.open(full_url, target);
|
|
});
|
|
break;
|
|
case NavigationTrigger.ClickOnce:
|
|
beacon_events.forEach((beacon_event) => {
|
|
window.fence.setReportEventDataForAutomaticBeacons(beacon_event);
|
|
});
|
|
addEventListener('click', (event) => {
|
|
window.open(full_url, target);
|
|
});
|
|
break;
|
|
case NavigationTrigger.CrossOriginClick:
|
|
case NavigationTrigger.CrossOriginClickNoOptIn:
|
|
beacon_events.forEach((beacon_event) => {
|
|
window.fence.setReportEventDataForAutomaticBeacons(beacon_event);
|
|
});
|
|
// Add a cross-origin iframe that will perform the top-level
|
|
// navigation.
|
|
const iframe = await attachIFrameContext({
|
|
origin: get_host_info().HTTPS_REMOTE_ORIGIN,
|
|
headers: [[
|
|
'Allow-Fenced-Frame-Automatic-Beacons',
|
|
navigation_trigger == NavigationTrigger.CrossOriginClick ?
|
|
'true' :
|
|
'false'
|
|
]]
|
|
});
|
|
await iframe.execute(async (full_url, target) => {
|
|
addEventListener('click', (event) => {
|
|
window.open(full_url, target);
|
|
});
|
|
}, [full_url, target]);
|
|
break;
|
|
}
|
|
},
|
|
[NavigationTrigger, beacon_events, navigation_trigger, full_url, target]);
|
|
}
|
|
|
|
// Checks if an automatic beacon of type `event_type` with contents `event_data`
|
|
// was sent out or not.
|
|
// event_type: The automatic beacon type to check.
|
|
// event_data: The automatic beacon data to check.
|
|
// expected_referrer: The expected referrer header, if different from origin.
|
|
// expected_success: Whether we expect the automatic beacon to be sent.
|
|
// t: The WPT's test object. Only required if
|
|
// expected_success = false.
|
|
async function verifyBeaconData(
|
|
event_type, event_data, expected_referrer = null, expected_success = true,
|
|
t) {
|
|
if (expected_success) {
|
|
const data = await nextBeacon(event_type, event_data);
|
|
const [beacon_initiator_origin, beacon_referrer] =
|
|
data.split(",");
|
|
assert_equals(beacon_initiator_origin, get_host_info().HTTPS_ORIGIN,
|
|
"The initiator origin should be set as expected.");
|
|
// The Referer header has a trailing '/' appended to the URL.
|
|
assert_equals(beacon_referrer,
|
|
(expected_referrer ? expected_referrer :
|
|
get_host_info().HTTPS_ORIGIN) + "/",
|
|
"The beacon referrer should be set as expected.");
|
|
} else {
|
|
const timeout = new Promise(r => t.step_timeout(r, 1000));
|
|
const result =
|
|
await Promise.race([nextBeacon(event_type, event_data), timeout]);
|
|
assert_true(typeof result === 'undefined',
|
|
"The beacon should not have sent.");
|
|
}
|
|
}
|