Reland "[soft-navigations] move startTime to processing end"

This is a reland of commit bc3a536a4fc930ff5161c7795758e72893b6afca, which was
reverted in ba0a09e0fca6c7e8e98ad168d52684e4b3f34a08.

Original change's description:
> Reland "[soft-navigations] move startTime to processing end"
>
> This is a reland of commit eab7d4b6462aee496860f0dbe342066bd342f5b9
>
> It better takes into account event bubbling, and the fact we see
> multiple tasks in a single EventScope in those cases. It also tests this case specifically.
>
> Bug: 1505059
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5076713
> Commit-Queue: Yoav Weiss <yoavweiss@chromium.org>
> Reviewed-by: Ian Clelland <iclelland@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1231299}

Original original change's description:
> [soft-navigations] move startTime to processing end
>
> This CL aligns the implementation with [1], and sets the soft navigation
> start time to be the processingEnd of the relevant earlier event.
>
> It also cleans up a few bits of code that became useless, as well as
> issues around PerInteractionData copying that were buggy yet hidden
> before the timing of setting the different attributes was changed.
>
>
> [1] https://github.com/WICG/soft-navigations/issues/14
>
> Change-Id: Id9f7ebf9f372a334a206f99258c882f10eeda2c5
> Bug: 1505059
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5059108
> Reviewed-by: Ian Clelland <iclelland@chromium.org>
> Commit-Queue: Yoav Weiss <yoavweiss@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1230490}

Change-Id: I333de5e1f2bfb04106abf639ecbad7698cc5ea7e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5181596
Commit-Queue: Ian Clelland <iclelland@chromium.org>
Reviewed-by: Michal Mocny <mmocny@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1248327}
diff --git a/soft-navigation-heuristics/click-event-bubbles.tentative.html b/soft-navigation-heuristics/click-event-bubbles.tentative.html
new file mode 100644
index 0000000..ee9d1e1
--- /dev/null
+++ b/soft-navigation-heuristics/click-event-bubbles.tentative.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/soft-navigation-helper.js"></script>
+</head>
+<body>
+  <main id=main>
+  <a id=link>Click me!</a>
+  </main>
+  <script>
+    const link = document.getElementById("link");
+    // Adding a noop event that the "click" would bubble to.
+    document.getElementById("main").addEventListener("click", () => {});
+
+    testSoftNavigation({
+      addContent: () => {
+        addTextParagraphToMain("Lorem Ipsum");
+      },
+      link: link,
+      test: "Ensure event bubbling works well with soft navigations."});
+  </script>
+</body>
+</html>
diff --git a/soft-navigation-heuristics/multiple_nested_events.tentative.html b/soft-navigation-heuristics/multiple-nested-events.tentative.html
similarity index 94%
rename from soft-navigation-heuristics/multiple_nested_events.tentative.html
rename to soft-navigation-heuristics/multiple-nested-events.tentative.html
index 196cfa0..e518418 100644
--- a/soft-navigation-heuristics/multiple_nested_events.tentative.html
+++ b/soft-navigation-heuristics/multiple-nested-events.tentative.html
@@ -24,7 +24,6 @@
     });
     testSoftNavigation({
       eventPrepWork: url => {
-        timestamps[counter]["eventStart"] = performance.now();
         addTextToDivOnMain();
         history.pushState({}, '', 'foobar1.html');
         // Here we're bypassing the regular test's event logic, as this test is
diff --git a/soft-navigation-heuristics/navigation-api-after-transition-commit.tentative.html b/soft-navigation-heuristics/navigation-api-after-transition-commit.tentative.html
index 5c7d8f4..ae17db7 100644
--- a/soft-navigation-heuristics/navigation-api-after-transition-commit.tentative.html
+++ b/soft-navigation-heuristics/navigation-api-after-transition-commit.tentative.html
@@ -16,11 +16,11 @@
   <script>
     const link = document.getElementById("link");
     testNavigationApi("Test soft navigation when navigate event intecepts with { commit: 'after-transition' }", e => {
-        timestamps[counter]["eventStart"] = performance.now();
         e.intercept({commit: "after-transition", handler: async () => {
           await addImageToMain();
           e.commit();
         }});
+        timestamps[counter]["eventEnd"] = performance.now();
       }, link);
   </script>
 </body>
diff --git a/soft-navigation-heuristics/navigation-api-hash.tentative.html b/soft-navigation-heuristics/navigation-api-hash.tentative.html
index a63b177..e20578e 100644
--- a/soft-navigation-heuristics/navigation-api-hash.tentative.html
+++ b/soft-navigation-heuristics/navigation-api-hash.tentative.html
@@ -16,11 +16,11 @@
   <script>
     const link = document.getElementById("link");
     testNavigationApi("Test soft navigation with the Navigation API", e => {
-        timestamps[counter]["eventStart"] = performance.now();
         e.intercept({handler: async () => {
           await addImageToMain();
           main.appendChild(img);
         }});
+        timestamps[counter]["eventEnd"] = performance.now();
       }, link);
   </script>
 </body>
diff --git a/soft-navigation-heuristics/navigation-api-preventDefault.tentative.html b/soft-navigation-heuristics/navigation-api-preventDefault.tentative.html
index d6c61ef..b7b2a24 100644
--- a/soft-navigation-heuristics/navigation-api-preventDefault.tentative.html
+++ b/soft-navigation-heuristics/navigation-api-preventDefault.tentative.html
@@ -19,12 +19,12 @@
     testSoftNavigationNotDetected({
       testName: "Aborted navigate event is not a soft navigation",
       eventHandler: e => {
-        timestamps[counter]["eventStart"] = performance.now();
         e.intercept({handler: async () => {
           await addImageToMain();
           main.appendChild(img);
         }});
         e.preventDefault();
+        timestamps[counter]["eventEnd"] = performance.now();
       },
       eventTarget: navigation,
       eventName: "navigate",
diff --git a/soft-navigation-heuristics/navigation-api-rejected.tentative.html b/soft-navigation-heuristics/navigation-api-rejected.tentative.html
index bcc0451..693f876 100644
--- a/soft-navigation-heuristics/navigation-api-rejected.tentative.html
+++ b/soft-navigation-heuristics/navigation-api-rejected.tentative.html
@@ -16,11 +16,11 @@
   <script>
     const link = document.getElementById("link");
     testNavigationApi("Test intercepted and rejected navigate event", e => {
-        timestamps[counter]["eventStart"] = performance.now();
         e.intercept({handler: async () => {
           await addImageToMain();
           throw new Error("This navigation handler rejected");
         }});
+        timestamps[counter]["eventEnd"] = performance.now();
       }, link);
   </script>
 </body>
diff --git a/soft-navigation-heuristics/navigation-api-view-transition.tentative.html b/soft-navigation-heuristics/navigation-api-view-transition.tentative.html
index 2755f9f..4d88f3d 100644
--- a/soft-navigation-heuristics/navigation-api-view-transition.tentative.html
+++ b/soft-navigation-heuristics/navigation-api-view-transition.tentative.html
@@ -23,7 +23,6 @@
       await new Promise(r => step_timeout(r, 0));
 
       const navigate_callback = e => {
-        timestamps[counter]["eventStart"] = performance.now();
         e.intercept({
           async handler() {
             const lcp_promise = new Promise(resolve => {
@@ -41,6 +40,7 @@
             await lcp_promise;
           }
         });
+        timestamps[counter]["eventEnd"] = performance.now();
       };
 
       const link = document.getElementById("link");
diff --git a/soft-navigation-heuristics/navigation-api.tentative.html b/soft-navigation-heuristics/navigation-api.tentative.html
index ca11f68..2d61736 100644
--- a/soft-navigation-heuristics/navigation-api.tentative.html
+++ b/soft-navigation-heuristics/navigation-api.tentative.html
@@ -16,10 +16,10 @@
   <script>
     const link = document.getElementById("link");
     testNavigationApi("Test soft navigation with the Navigation API", e => {
-        timestamps[counter]["eventStart"] = performance.now();
         e.intercept({handler: async () => {
           await addImageToMain();
         }});
+        timestamps[counter]["eventEnd"] = performance.now();
       }, link);
   </script>
 </body>
diff --git a/soft-navigation-heuristics/popstate-multiple-backs.tentative.html b/soft-navigation-heuristics/popstate-multiple-backs.tentative.html
index 2a12a35..fd87f5f 100644
--- a/soft-navigation-heuristics/popstate-multiple-backs.tentative.html
+++ b/soft-navigation-heuristics/popstate-multiple-backs.tentative.html
@@ -39,7 +39,10 @@
       return t.popped == 2;
     }
     const link = document.getElementById("link");
-    link.addEventListener("click", () => history.back());
+    link.addEventListener("click", () => {
+      history.back();
+      timestamps[counter]["eventEnd"] = performance.now();
+    });
     testSoftNavigation({
       addContent: () => {
         // Add the content to the main element
diff --git a/soft-navigation-heuristics/popstate.tentative.html b/soft-navigation-heuristics/popstate.tentative.html
index 60a5ff7..f89991d 100644
--- a/soft-navigation-heuristics/popstate.tentative.html
+++ b/soft-navigation-heuristics/popstate.tentative.html
@@ -22,7 +22,10 @@
     history.pushState({}, "", "another_one.html");
 
     const link = document.getElementById("link");
-    link.addEventListener("click", () => history.back());
+    link.addEventListener("click", () => {
+      history.back();
+      timestamps[counter]["eventEnd"] = performance.now();
+    });
     testSoftNavigation({
       addContent: () => {
         // Add the content to the main element
diff --git a/soft-navigation-heuristics/resources/soft-navigation-helper.js b/soft-navigation-heuristics/resources/soft-navigation-helper.js
index 58ca9c2..685bc21 100644
--- a/soft-navigation-heuristics/resources/soft-navigation-helper.js
+++ b/soft-navigation-heuristics/resources/soft-navigation-helper.js
@@ -144,10 +144,17 @@
   const eventObject =
       (eventType == 'click' || eventType.startsWith("key")) ? button : window;
   eventObject.addEventListener(eventType, async e => {
+    let prepWorkFailed = false;
     if (prepWork &&!prepWork(t)) {
+      prepWorkFailed = true;
+    }
+    // This is the end of the event's sync processing.
+    if (!timestamps[counter]["eventEnd"]) {
+      timestamps[counter]["eventEnd"] = performance.now();
+    }
+    if (prepWorkFailed) {
       return;
     }
-    timestamps[counter]["eventStart"] = performance.now();
     // Jump through a task, to ensure task tracking is working properly.
     await new Promise(r => t.step_timeout(r, 0));
 
@@ -165,9 +172,9 @@
     await new Promise(r => t.step_timeout(r, 10));
 
     await addContent(url);
-    ++counter;
 
     interacted = true;
+    ++counter;
   });
 };
 
@@ -190,7 +197,7 @@
     assert_less_than_equal(timestamps[i]["syncPostInteraction"], entryTimestamp,
                 "Entry timestamp is lower than the post interaction one");
     assert_greater_than_equal(
-        timestamps[i]['eventStart'], entryTimestamp,
+        entryTimestamp, timestamps[i]['eventEnd'],
         'Event start timestamp matches');
     assert_not_equals(entry.navigationId,
                       performance.getEntriesByType("navigation")[0].navigationId,