tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

prefetch_status_updated.https.html (6455B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8"/>
      3 <script src="/resources/testharness.js"></script>
      4 <script src="/resources/testharnessreport.js"></script>
      5 <script src="/common/dispatcher/dispatcher.js"></script>
      6 <script src="/common/utils.js"></script>
      7 <script src="/resources/testdriver.js?feature=bidi"></script>
      8 <script src="/resources/testdriver-vendor.js"></script>
      9 <script src="resources/bidi-speculation-helper.js"></script>
     10 <script>
     11    promise_setup(async () => {
     12        await waitForDocumentReady();
     13    });
     14    promise_test(async t => {
     15        // Subscribe for this test only
     16        const unsubscribe = await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
     17        const receivedStatuses = [];
     18        const expectedStatuses = ['pending', 'ready'];
     19        const targetUrl = window.location.origin + "/infrastructure/testdriver/bidi/speculation/resources/target.html";
     20        // Create a promise that resolves when we receive the 'ready' event
     21        const readyEventPromise = new Promise((resolve, reject) => {
     22            const removeHandler = test_driver.bidi.speculation.prefetch_status_updated.on((event) => {
     23                // Multiple events for the same status can be sent in cases of network retries, etc.
     24                if (!receivedStatuses.includes(event.status)) {
     25                    receivedStatuses.push(event.status);
     26                }
     27                // When we receive the ready event, clean up and resolve
     28                if (event.status === 'ready') {
     29                    removeHandler();
     30                    resolve();
     31                }
     32            });
     33        });
     34        // Create prefetch rules for our target page in resources
     35        const speculationRules = {
     36            prefetch: [{
     37                source: "list",
     38                urls: [targetUrl]
     39            }]
     40        };
     41        // Use helper function to add both speculation rules and link
     42        const { script, link } = addSpeculationRulesAndLink(speculationRules, targetUrl);
     43        // Await the ready event
     44        await readyEventPromise;
     45        // Assert that we received the expected events
     46        assert_array_equals(receivedStatuses, expectedStatuses, 'Should have received pending and ready events');
     47        t.add_cleanup(async () => {
     48            await unsubscribe();
     49        });
     50    }, "prefetch_status_updated event subscription and structure validation");
     51    promise_test(async t => {
     52        // Subscribe for this test only
     53        const unsubscribe = await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
     54        const receivedStatuses = [];
     55        const expectedStatuses = ['pending', 'ready', 'success'];
     56        let newWindow = null;
     57        // Create prefetch rules for our target page in resources (different URL to avoid caching)
     58        const targetUrl = window.location.origin + "/infrastructure/testdriver/bidi/speculation/resources/target.html?test=2";
     59        // Create a promise that resolves when we receive the 'success' event
     60        const successEventPromise = new Promise((resolve, reject) => {
     61            const removeHandler = test_driver.bidi.speculation.prefetch_status_updated.on((event) => {
     62                // Multiple events for the same status can be sent for network retries, etc.
     63                if (!receivedStatuses.includes(event.status)) {
     64                    receivedStatuses.push(event.status);
     65                }
     66                // When we receive the ready event, navigate to trigger success
     67                if (event.status === 'ready') {
     68                    // Open the prefetched page in a new window to trigger success
     69                    newWindow = window.open(event.url, '_blank');
     70                } else if (event.status === 'success') {
     71                    removeHandler();
     72                    resolve();
     73                }
     74            });
     75        });
     76        const speculationRules = {
     77            prefetch: [{
     78                source: "list",
     79                urls: [targetUrl]
     80            }]
     81        };
     82        // Use helper function to add both speculation rules and link
     83        const { script, link } = addSpeculationRulesAndLink(speculationRules, targetUrl);
     84        // Await the success event
     85        await successEventPromise;
     86        // Assert that we received the expected events
     87        assert_array_equals(receivedStatuses, expectedStatuses, 'Should have received pending, ready, and success events');
     88        t.add_cleanup(async () => {
     89            await unsubscribe();
     90            if (newWindow && !newWindow.closed) {
     91                newWindow.close();
     92            }
     93        });
     94    }, "prefetch_status_updated event with navigation to success");
     95    promise_test(async t => {
     96        // Subscribe for this test only
     97        const unsubscribe = await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
     98        const receivedStatuses = [];
     99        const expectedStatuses = ['failure'];
    100        // Set error url to fail at network layer and only expect failure event
    101        const errorUrl = "http://0.0.0.0:1/test.html";
    102        // Create a promise that resolves when we receive the 'failure' event
    103        const failureEventPromise = new Promise((resolve, reject) => {
    104            const removeHandler = test_driver.bidi.speculation.prefetch_status_updated.on((event) => {
    105                // Multiple events for the same status can be sent for network retries, etc.
    106                if (!receivedStatuses.includes(event.status)) {
    107                    receivedStatuses.push(event.status);
    108                }
    109                // When we receive the failure event, we're done
    110                if (event.status === 'failure') {
    111                    removeHandler();
    112                    resolve();
    113                }
    114            });
    115        });
    116        const speculationRules = {
    117            prefetch: [{
    118                source: "list",
    119                urls: [errorUrl]
    120            }]
    121        };
    122        // Use helper function to add both speculation rules and link
    123        const { script, link } = addSpeculationRulesAndLink(speculationRules, errorUrl);
    124        // Await the failure event
    125        await failureEventPromise;
    126        // Assert that we received the expected events
    127        assert_array_equals(receivedStatuses, expectedStatuses, 'Should have received only failure event');
    128        t.add_cleanup(async () => {
    129            await unsubscribe();
    130        });
    131    }, "prefetch_status_updated event with prefetch failure");
    132 </script>