summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/speculation-rules/prerender/resources/session-history-harness.js
blob: 619ee3aa92de422c1ba882911879a7ef300491b1 (plain)
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
// We don't have the test harness in this context, so we roll our own
// which communicates with our initiator which is actually running the tests.

function assert(condition, message) {
  if (!condition) {
    throw new Error("Assertion failed: " + message);
  }
}

// Run a test after activation.
document.addEventListener("prerenderingchange", async (_) => {
  // history.length is racy on activation. Wait *100ms* as a workaround.
  // See crbug.com/1222893.
  await new Promise((resolve) => {
    window.setTimeout(resolve, 100);
  });

  const urlParams = new URLSearchParams(window.location.search);
  const testName = urlParams.get("testName");
  const uid = urlParams.get("uid");
  const testChannel = new PrerenderChannel(
    `test-channel-${testName}`, uid
  );

  try {
    const activationTestFn = testName + "Activation";
    const testFn = window[activationTestFn];
    if (!testFn) {
      testChannel.postMessage("Missing test: " + testName);
      return;
    }
    testFn();
    testChannel.postMessage("Passed");
  } catch (e) {
    testChannel.postMessage(
      "Failed: " + e.name + ": " + e.message,
    );
  } finally {
    testChannel.close();
  }
})

if (document.prerendering) {
  window.onload = async () => {
    const urlParams = new URLSearchParams(window.location.search);
    const testName = urlParams.get("testName");
    const uid = urlParams.get("uid");
    const prerenderChannel = new PrerenderChannel(
      `prerender-channel-${testName}`, uid
    );

    // The document load event is not finished at this point, so navigations
    // would be done with replacement. This interferes with our tests. We wait
    // for the next task before navigating to avoid this.
    await new Promise((resolve) => {
      window.setTimeout(resolve);
    });

    try {
      let testFn = window[testName];
      if (!testFn) {
        prerenderChannel.postMessage("Missing test: " + testName);
        return;
      }
      await testFn();
      prerenderChannel.postMessage("Passed");
    } catch (e) {
      prerenderChannel.postMessage(
        "Failed: " + e.name + ": " + e.message,
      );
    } finally {
      prerenderChannel.close();
    }
  };
}