tor-browser

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

lcp.html (4132B)


      1 <!doctype html>
      2 <html>
      3  <head>
      4    <meta charset="utf-8" />
      5    <title>Soft Navigation Detection: LCP.</title>
      6    <script src="/resources/testharness.js"></script>
      7    <script src="/resources/testharnessreport.js"></script>
      8    <script src="/resources/testdriver.js"></script>
      9    <script src="/resources/testdriver-vendor.js"></script>
     10    <script src="/soft-navigation-heuristics/resources/soft-navigation-test-helper.js"></script>
     11    <script>
     12      // The click handler is triggered by user interaction; it modifies
     13      // the DOM by adding an image to the page; this triggers both
     14      // a soft navigation and a soft navigation LCP entry.
     15      function clickHandler() {
     16        const img = new Image();
     17        img.src = "/images/lcp-256x256.png";
     18        img.id = "lcp-img";
     19        document.body.appendChild(img);
     20        history.pushState({}, "", "/show-image");
     21      }
     22    </script>
     23  </head>
     24  <body>
     25    <div id="click-target" onclick="clickHandler()">Click here!</div>
     26 
     27    <script>
     28      promise_test(async (t) => {
     29        const helper = new SoftNavigationTestHelper(t);
     30 
     31        // Wait for the initial LCP entry, prior to clicking, so that
     32        // we may later observe the soft navigation LCP entry in addition.
     33        const initial_lcp =
     34            await helper.getBufferedPerformanceEntriesWithTimeout("largest-contentful-paint");
     35        assert_equals(initial_lcp.length, 1, "There's one initial LCP entry.");
     36        assert_equals(
     37          initial_lcp[0].id,
     38          "click-target",
     39          "The initial LCP entry is the div for the click target.",
     40        );
     41 
     42        if (test_driver) {
     43          test_driver.click(document.getElementById("click-target"));
     44        }
     45 
     46        // Now that we've clicked, we expect to see a soft navigation,
     47        // and a soft navigation LCP entry;
     48        const results = await Promise.allSettled([
     49          helper.getBufferedPerformanceEntriesWithTimeout("soft-navigation"),
     50          helper.getBufferedPerformanceEntriesWithTimeout("interaction-contentful-paint"),
     51        ]);
     52 
     53        // If either or both of soft nav entry or soft nav LCP are missing,
     54        // fail the test.
     55        const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason.message);
     56        if (errors.length > 0) {
     57          throw new AssertionError("PerformanceObservers failed: " + format_value(errors));
     58        }
     59 
     60        // Examine the soft navigation entries.
     61        const soft_navs = results[0].value;
     62        assert_equals(soft_navs.length, 1, "Expecting one soft navigation entry.");
     63        assert_equals(
     64          soft_navs[0].name.replace(/.*\//, ""),
     65          "show-image",
     66          "Expecting soft navigation to 'greeting'",
     67        );
     68 
     69        // Examine the soft navigation LCP entries.
     70        const icps = results[1].value;
     71        assert_equals(
     72          icps.length,
     73          1,
     74          "Expecting 1 entry.",
     75        );
     76 
     77        // Now observe the hard navs again. There should only be one entry.
     78        // See also crbug.com/40073849: We really don't want to emit hard nav
     79        // LCP entries for soft navigations unintentionally.
     80        const observer = new PerformanceObserver(assert_unreached);
     81        observer.observe({
     82          type: "largest-contentful-paint",
     83          buffered: true,
     84        });
     85        const hard_nav_lcp = observer.takeRecords();
     86        observer.disconnect();
     87 
     88        assert_equals(hard_nav_lcp.length, 1, "Expecting one entry for the hard nav LCP.");
     89 
     90        // Compare the first soft nav LCP entry with the hard nav LCP entry.
     91        assert_equals(
     92          hard_nav_lcp[0].id,
     93          "click-target",
     94          "Hard nav LCP entry is (still) for the click target.",
     95        );
     96 
     97        assert_equals(
     98          icps[0].id,
     99          "lcp-img",
    100          "Soft nav LCP entry is for the image.",
    101        );
    102 
    103        assert_equals(
    104          icps[0].navigationId,
    105          soft_navs[0].navigationId,
    106          "Soft nav LCP entry has the same navigation ID as the soft nav entry.",
    107        );
    108      }, "Detect soft navigation and LCP after a click.");
    109    </script>
    110  </body>
    111 </html>