Skip to content

Commit

Permalink
[soft navigations] Enable keyboard shortcuts as soft navigation triggers
Browse files Browse the repository at this point in the history
Following the discussion on issue #3 [1], this CL adds support to soft
navigations triggered by keyboard shortcuts, by adding unfocused keydown
events to the events that can trigger the soft navigation heuristic.

[1] WICG/soft-navigations#3
Bug: 1478772
Change-Id: Ib423a3cfc09eaf4dd9a2221b3494ab1016fa8668
  • Loading branch information
Yoav Weiss authored and chromium-wpt-export-bot committed Sep 6, 2023
1 parent c933272 commit f030ec1
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

const first_click_paint_promise = waitOnPaintEntriesPromise();

click(link);
interact(link);
await new Promise(resolve => {
(new PerformanceObserver(resolve)).observe({
type: 'soft-navigation'
Expand All @@ -54,7 +54,7 @@

const second_click_paint_promise = waitOnPaintEntriesPromise();
const preClickLcp2 = await getLcpEntries();
click(link);
interact(link);
await new Promise(resolve => {
(new PerformanceObserver(() => resolve())).observe({
type: 'soft-navigation'
Expand Down
30 changes: 30 additions & 0 deletions soft-navigation-heuristics/keydown.tentative.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Detect hashchange event.</title>
<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>
<div>
First LCP!
</div>
</main>
<script>
testSoftNavigation({
addContent: () => {
addTextToDivOnMain();
},
link: document.body,
interactionType: "keydown",
eventType: "keydown",
test: "Keydown on body triggers SoftNavigationHeuristics"});
</script>
</body>
</html>

2 changes: 1 addition & 1 deletion soft-navigation-heuristics/navigate-child.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
await new Promise(r => t.step_timeout(r, 10));
}
const link = document.getElementById("link");
click(link);
interact(link);
while (!child.location.href.includes("2")) {
await new Promise(r => t.step_timeout(r, 10));
}
Expand Down
35 changes: 21 additions & 14 deletions soft-navigation-heuristics/resources/soft-navigation-helper.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var counter = 0;
var clicked;
var interacted;
var timestamps = []
const MAX_CLICKS = 50;
// Entries for one hard navigation + 50 soft navigations.
Expand All @@ -20,6 +20,7 @@ const testSoftNavigation =
const testName = options.testName;
const pushUrl = readValue(options.pushUrl, true);
const eventType = readValue(options.eventType, "click");
const interactionType = readValue(options.interactionType, 'click');
const expectLCP = options.validate != 'no-lcp';
promise_test(async t => {
await waitInitialLCP();
Expand All @@ -29,8 +30,8 @@ const testSoftNavigation =
const firstClick = (i === 0);
let paint_entries_promise =
waitOnPaintEntriesPromise(expectLCP && firstClick);
clicked = false;
click(link);
interacted = false;
interact(link, interactionType);

await new Promise(resolve => {
(new PerformanceObserver(() => resolve())).observe({
Expand Down Expand Up @@ -61,7 +62,7 @@ const testNavigationApi = (testName, navigateEventHandler, link) => {
await waitInitialLCP();
const preClickLcp = await getLcpEntries();
let paint_entries_promise = waitOnPaintEntriesPromise();
click(link);
interact(link);
await new Promise(resolve => {
(new PerformanceObserver(() => resolve())).observe({
type: 'soft-navigation'
Expand All @@ -80,7 +81,7 @@ const testSoftNavigationNotDetected = options => {
promise_test(async t => {
const preClickLcp = await getLcpEntries();
options.eventTarget.addEventListener(options.eventName, options.eventHandler);
click(options.link);
interact(options.link);
await new Promise((resolve, reject) => {
(new PerformanceObserver(() =>
reject("Soft navigation should not be triggered"))).observe({
Expand Down Expand Up @@ -128,15 +129,21 @@ const runEntryValidations =
}
};

const click = link => {
if (test_driver) {
test_driver.click(link);
timestamps[counter] = {"syncPostClick": performance.now()};
}
}
const interact =
(link, interactionType = 'click') => {
if (test_driver) {
if (interactionType == 'click') {
test_driver.click(link);
} else {
test_driver.send_keys(link, 'j');
}
timestamps[counter] = {"syncPostInteraction": performance.now()};
}
}

const setEvent = (t, button, pushState, addContent, pushUrl, eventType) => {
const eventObject = (eventType == "click") ? button : window;
const eventObject =
(eventType == 'click' || eventType == 'keydown') ? button : window;
eventObject.addEventListener(eventType, async e => {
timestamps[counter]["eventStart"] = performance.now();
// Jump through a task, to ensure task tracking is working properly.
Expand All @@ -158,7 +165,7 @@ const setEvent = (t, button, pushState, addContent, pushUrl, eventType) => {
await addContent(url);
++counter;

clicked = true;
interacted = true;
});
};

Expand All @@ -178,7 +185,7 @@ const validateSoftNavigationEntry = async (clicks, extraValidations,
assert_true(entry.name.includes(pushUrl ? URL : document.location.href),
"The soft navigation name is properly set");
const entryTimestamp = entry.startTime;
assert_less_than_equal(timestamps[i]["syncPostClick"], entryTimestamp);
assert_less_than_equal(timestamps[i]["syncPostInteraction"], entryTimestamp);
assert_greater_than_equal(
timestamps[i]['eventStart'], entryTimestamp,
'Event start timestamp matches');
Expand Down

0 comments on commit f030ec1

Please sign in to comment.