summaryrefslogtreecommitdiffstats
path: root/netwerk/test/browser/browser_103_assets.js
blob: 4e32c8bf7cfbd1a3c63ba3354742bb5b0e0777f8 (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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// On debug osx test machine, verify chaos mode takes slightly too long
requestLongerTimeout(2);

Services.prefs.setBoolPref("network.early-hints.enabled", true);

const { request_count_checking } = ChromeUtils.importESModule(
  "resource://testing-common/early_hint_preload_test_helper.sys.mjs"
);

// - testName is just there to be printed during Asserts when failing
// - asset is the asset type, see early_hint_asset_html.sjs for possible values
//   for the asset type fetch see test_hint_fetch due to timing issues
// - variant:
//   - "normal": no early hints, expects one normal request expected
//   - "hinted": early hints sent, expects one hinted request
//   - "reload": early hints sent, resources non-cacheable, two early-hint requests expected
//   - "cached": same as reload, but resources are cacheable, so only one hinted network request expected
async function test_hint_asset(testName, asset, variant) {
  // reset the count
  let headers = new Headers();
  headers.append("X-Early-Hint-Count-Start", "");
  await fetch(
    "http://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs",
    { headers }
  );

  let requestUrl = `https://example.com/browser/netwerk/test/browser/early_hint_asset_html.sjs?as=${asset}&hinted=${
    variant !== "normal" ? "1" : "0"
  }&cached=${variant === "cached" ? "1" : "0"}`;

  let numConnectBackRemaining = 0;
  if (variant === "hinted") {
    numConnectBackRemaining = 1;
  } else if (variant === "reload" || variant === "cached") {
    numConnectBackRemaining = 2;
  }

  let observer = {
    QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
    observe(aSubject, aTopic, aData) {
      if (aTopic == "earlyhints-connectback") {
        numConnectBackRemaining -= 1;
      }
    },
  };
  Services.obs.addObserver(observer, "earlyhints-connectback");

  await BrowserTestUtils.withNewTab(
    {
      gBrowser,
      url: requestUrl,
      waitForLoad: true,
    },
    async function (browser) {
      if (asset === "fetch") {
        // wait until the fetch is complete
        await TestUtils.waitForCondition(_ => {
          return SpecialPowers.spawn(browser, [], _ => {
            return (
              content.document.getElementsByTagName("h2")[0] != undefined &&
              content.document.getElementsByTagName("h2")[0].textContent !==
                "Fetching..." // default text set by early_hint_asset_html.sjs
            );
          });
        });
      }

      // reload
      if (variant === "reload" || variant === "cached") {
        await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
      }

      if (asset === "fetch") {
        // wait until the fetch is complete
        await TestUtils.waitForCondition(_ => {
          return SpecialPowers.spawn(browser, [], _ => {
            return (
              content.document.getElementsByTagName("h2")[0] != undefined &&
              content.document.getElementsByTagName("h2")[0].textContent !==
                "Fetching..." // default text set by early_hint_asset_html.sjs
            );
          });
        });
      }
    }
  );
  Services.obs.removeObserver(observer, "earlyhints-connectback");

  let gotRequestCount = await fetch(
    "http://example.com/browser/netwerk/test/browser/early_hint_pixel_count.sjs"
  ).then(response => response.json());
  Assert.equal(
    numConnectBackRemaining,
    0,
    `${testName} (${asset}) no remaining connect back expected`
  );

  let expectedRequestCount;
  if (variant === "normal") {
    expectedRequestCount = { hinted: 0, normal: 1 };
  } else if (variant === "hinted") {
    expectedRequestCount = { hinted: 1, normal: 0 };
  } else if (variant === "reload") {
    expectedRequestCount = { hinted: 2, normal: 0 };
  } else if (variant === "cached") {
    expectedRequestCount = { hinted: 1, normal: 0 };
  }

  await request_count_checking(
    `${testName} (${asset})`,
    gotRequestCount,
    expectedRequestCount
  );
  if (variant === "cached") {
    Services.cache2.clear();
  }
}

// preload image
add_task(async function test_103_asset_image() {
  await test_hint_asset("test_103_asset_normal", "image", "normal");
  await test_hint_asset("test_103_asset_hinted", "image", "hinted");
  await test_hint_asset("test_103_asset_reload", "image", "reload");
  // TODO(Bug 1815884): await test_hint_asset("test_103_asset_cached", "image", "cached");
});

// preload css
add_task(async function test_103_asset_style() {
  await test_hint_asset("test_103_asset_normal", "style", "normal");
  await test_hint_asset("test_103_asset_hinted", "style", "hinted");
  await test_hint_asset("test_103_asset_reload", "style", "reload");
  // TODO(Bug 1815884): await test_hint_asset("test_103_asset_cached", "style", "cached");
});

// preload javascript
add_task(async function test_103_asset_javascript() {
  await test_hint_asset("test_103_asset_normal", "script", "normal");
  await test_hint_asset("test_103_asset_hinted", "script", "hinted");
  await test_hint_asset("test_103_asset_reload", "script", "reload");
  await test_hint_asset("test_103_asset_cached", "script", "cached");
});

// preload javascript module
add_task(async function test_103_asset_module() {
  await test_hint_asset("test_103_asset_normal", "module", "normal");
  await test_hint_asset("test_103_asset_hinted", "module", "hinted");
  await test_hint_asset("test_103_asset_reload", "module", "reload");
  await test_hint_asset("test_103_asset_cached", "module", "cached");
});

// preload font
add_task(async function test_103_asset_font() {
  await test_hint_asset("test_103_asset_normal", "font", "normal");
  await test_hint_asset("test_103_asset_hinted", "font", "hinted");
  await test_hint_asset("test_103_asset_reload", "font", "reload");
  await test_hint_asset("test_103_asset_cached", "font", "cached");
});

// preload fetch
add_task(async function test_103_asset_fetch() {
  await test_hint_asset("test_103_asset_normal", "fetch", "normal");
  await test_hint_asset("test_103_asset_hinted", "fetch", "hinted");
  await test_hint_asset("test_103_asset_reload", "fetch", "reload");
  await test_hint_asset("test_103_asset_cached", "fetch", "cached");
});