File: navigation-timing-requestStart-responseStart.https.html

package info (click to toggle)
firefox 143.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,617,328 kB
  • sloc: cpp: 7,478,492; javascript: 6,417,157; ansic: 3,720,058; python: 1,396,372; xml: 627,523; asm: 438,677; java: 186,156; sh: 63,477; makefile: 19,171; objc: 13,059; perl: 12,983; yacc: 4,583; cs: 3,846; pascal: 3,405; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 53; csh: 10
file content (102 lines) | stat: -rw-r--r-- 5,542 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/common/utils.js"></script>
<script src="../resources/utils.js"></script>
<script src="resources/utils.sub.js"></script>
<script src="/common/subset-tests-by-key.js"></script>

<meta name="variant" content="?include=noPrefetch">
<meta name="variant" content="?include=afterResponse">
<meta name="variant" content="?include=waitingForResponse">
<meta name="variant" content="?include=waitingForRedirect">

<script>
const setupProperties = {};
if (shouldRunSubTest('waitingForResponse') || shouldRunSubTest('waitingForRedirect')) {
  // These tests rely on the relationship between these timeouts, the delays
  // on the server, and any vendor specific timeouts. Force a multiplier of 1,
  // since using setTimeout directly incurs the wrath of `wpt lint`.
  setupProperties.timeout_multiplier = 1;
}
setup(() => assertSpeculationRulesIsSupported(), setupProperties);

subsetTestByKey('noPrefetch', promise_test, async t => {
  const agent = await spawnWindow(t);
  const landingUrl = agent.getExecutorURL({page: 2});

  await agent.navigate(landingUrl);
  assert_not_prefetched(await agent.getRequestHeaders(), `${landingUrl} should not be prefetched.`);

  // It's generally expected that events occur in this order:
  //   ... -> connectEnd --> requestStart --> responseStart --> ...
  const [entry] = await agent.execute_script(
      () => performance.getEntriesByType('navigation'));
  assert_less_than_equal(entry.connectEnd, entry.requestStart);
  assert_less_than_equal(entry.requestStart, entry.responseStart);
}, "PerformanceNavigationTiming data should be in the correct order (no prefetch)");

subsetTestByKey('afterResponse', promise_test, async t => {
  const agent = await spawnWindow(t);
  const landingUrl = agent.getExecutorURL({page: 2});
  await agent.forceSinglePrefetch(landingUrl);

  await agent.navigate(landingUrl);
  assert_prefetched(await agent.getRequestHeaders(), `${landingUrl} should have been prefetched.`);

  // Since the response should have started before the navigation, these should
  // all have the same value (i.e., the start of the fetch).
  const [entry] = await agent.execute_script(
      () => performance.getEntriesByType('navigation'));
  assert_equals(entry.connectEnd, entry.requestStart);
  assert_equals(entry.requestStart, entry.responseStart);
}, "PerformanceNavigationTiming data should show 'instantaneous' events completed beforehand");

subsetTestByKey('waitingForResponse', promise_test, async t => {
  const agent = await spawnWindow(t);
  const landingUrl = agent.getExecutorURL({executor: 'slow-executor.py', delay: '3', page: 2});
  await agent.forceSinglePrefetch(landingUrl, {}, /*wait_for_completion=*/false);

  // Chromium, at least, will give up the prefetch if the response head doesn't
  // come back within 1 second of navigation. So since the server will take
  // 3 seconds to respond, we wait 2.5 seconds before navigating, to ensure the
  // response comes back within about 0.5 seconds.
  await new Promise(resolve => t.step_timeout(resolve, 2_500));

  await agent.navigate(landingUrl);
  assert_prefetched(await agent.getRequestHeaders(), `${landingUrl} should have been prefetched.`);

  // Unlike the `afterResponse` test, we expect delays between `requestStart`
  // and `responseStart` here. If our timing was perfect and server round-trips
  // were instantaneous, that delay would be 0.5 seconds. To give ourselves a
  // bit of wiggle room, instead we assert that it's at least 0.1 seconds.
  const [entry] = await agent.execute_script(
      () => performance.getEntriesByType('navigation'));
  assert_less_than_equal(entry.connectEnd, entry.requestStart, "connectEnd must be before requestStart");
  assert_greater_than(entry.responseStart, entry.requestStart + 100, "responseStart must be > 100 ms after requestStart");
}, "PerformanceNavigationTiming data should show noticeable TTFB if the response is slow");

subsetTestByKey('waitingForRedirect', promise_test, async t => {
  const agent = await spawnWindow(t);
  const landingUrl = agent.getExecutorURL({page: 2});
  const slowRedirectUrl = new URL(`/common/slow-redirect.py?delay=3&location=${encodeURIComponent(landingUrl)}`, document.baseURI);
  await agent.forceSinglePrefetch(slowRedirectUrl, {}, /*wait_for_completion=*/false);

  // Considerations here are the same as for `waitingForResponse`.
  await new Promise(resolve => t.step_timeout(resolve, 2_500));

  await agent.navigate(slowRedirectUrl, {expectedDestinationUrl: landingUrl});
  assert_prefetched(await agent.getRequestHeaders(), `${landingUrl} should have been prefetched.`);

  // As in `waitingForResponse`, we expect at least 0.1 seconds TTFB. Unlike in
  // that test, the delta isn't captured by `requestStart` vs. `responseStart`,
  // because these stats only measure the final request/response pair, which is
  // not delayed.
  const [entry] = await agent.execute_script(
      () => performance.getEntriesByType('navigation'));
  assert_less_than_equal(entry.connectEnd, entry.requestStart, "connectEnd must be before requestStart");
  assert_less_than_equal(entry.requestStart, entry.responseStart, "requestStart must be before responseStart");
  assert_greater_than(entry.connectEnd, 100, "connectEnd must be > 100 ms");
}, "PerformanceNavigationTiming data should show noticeable TTFB if the response is slow");
</script>