automatic-beacon-helper.js (5051B)
1 // This is a helper file used for the automatic-beacon-*.https.html tests. 2 // To use this, make sure you import these scripts: 3 // <script src="/resources/testharness.js"></script> 4 // <script src="/resources/testharnessreport.js"></script> 5 // <script src="/common/utils.js"></script> 6 // <script src="/common/dispatcher/dispatcher.js"></script> 7 // <script src="resources/utils.js"></script> 8 // <script src="/resources/testdriver.js"></script> 9 // <script src="/resources/testdriver-actions.js"></script> 10 // <script src="/resources/testdriver-vendor.js"></script> 11 // <script src="/common/get-host-info.sub.js"></script> 12 13 const NavigationTrigger = { 14 Click: 0, 15 ClickOnce: 1, 16 CrossOriginClick: 2, 17 CrossOriginClickNoOptIn: 3 18 }; 19 20 // Registers an automatic beacon in a given remote context frame, and registers 21 // the navigation handler for the frame that will trigger the beacon. 22 // remote_context: The context for the fenced frame or URN iframe. 23 // beacon_events: An array of FenceEvents to register with the frame. 24 // navigation_url: The URL the frame will navigate to. 25 // navigation_trigger: How the navigation will be performed. Either through a 26 // click, a click with a `once` event, a click in a 27 // cross-origin subframe, or a click in a cross-origin 28 // subframe with no opt-in header. 29 // target: the target of the navigation. Either '_blank' or 30 // '_unfencedTop'. 31 async function setupAutomaticBeacon( 32 remote_context, beacon_events, navigation_url = 'resources/dummy.html', 33 navigation_trigger = NavigationTrigger.Click, target = '_blank') { 34 const full_url = new URL(navigation_url, location.href); 35 await remote_context.execute( 36 async ( 37 NavigationTrigger, beacon_events, navigation_trigger, full_url, 38 target) => { 39 switch (navigation_trigger) { 40 case NavigationTrigger.Click: 41 addEventListener('click', (event) => { 42 beacon_events.forEach((beacon_event) => { 43 window.fence.setReportEventDataForAutomaticBeacons( 44 beacon_event); 45 }); 46 window.open(full_url, target); 47 }); 48 break; 49 case NavigationTrigger.ClickOnce: 50 beacon_events.forEach((beacon_event) => { 51 window.fence.setReportEventDataForAutomaticBeacons(beacon_event); 52 }); 53 addEventListener('click', (event) => { 54 window.open(full_url, target); 55 }); 56 break; 57 case NavigationTrigger.CrossOriginClick: 58 case NavigationTrigger.CrossOriginClickNoOptIn: 59 beacon_events.forEach((beacon_event) => { 60 window.fence.setReportEventDataForAutomaticBeacons(beacon_event); 61 }); 62 // Add a cross-origin iframe that will perform the top-level 63 // navigation. 64 const iframe = await attachIFrameContext({ 65 origin: get_host_info().HTTPS_REMOTE_ORIGIN, 66 headers: [[ 67 'Allow-Fenced-Frame-Automatic-Beacons', 68 navigation_trigger == NavigationTrigger.CrossOriginClick ? 69 'true' : 70 'false' 71 ]] 72 }); 73 await iframe.execute(async (full_url, target) => { 74 addEventListener('click', (event) => { 75 window.open(full_url, target); 76 }); 77 }, [full_url, target]); 78 break; 79 } 80 }, 81 [NavigationTrigger, beacon_events, navigation_trigger, full_url, target]); 82 } 83 84 // Checks if an automatic beacon of type `event_type` with contents `event_data` 85 // was sent out or not. 86 // event_type: The automatic beacon type to check. 87 // event_data: The automatic beacon data to check. 88 // expected_referrer: The expected referrer header, if different from origin. 89 // expected_success: Whether we expect the automatic beacon to be sent. 90 // t: The WPT's test object. Only required if 91 // expected_success = false. 92 async function verifyBeaconData( 93 event_type, event_data, expected_referrer = null, expected_success = true, 94 t) { 95 if (expected_success) { 96 const data = await nextBeacon(event_type, event_data); 97 const [beacon_initiator_origin, beacon_referrer] = 98 data.split(","); 99 assert_equals(beacon_initiator_origin, get_host_info().HTTPS_ORIGIN, 100 "The initiator origin should be set as expected."); 101 // The Referer header has a trailing '/' appended to the URL. 102 assert_equals(beacon_referrer, 103 (expected_referrer ? expected_referrer : 104 get_host_info().HTTPS_ORIGIN) + "/", 105 "The beacon referrer should be set as expected."); 106 } else { 107 const timeout = new Promise(r => t.step_timeout(r, 1000)); 108 const result = 109 await Promise.race([nextBeacon(event_type, event_data), timeout]); 110 assert_true(typeof result === 'undefined', 111 "The beacon should not have sent."); 112 } 113 }