summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/test/mochitest/browser_dbg-inline-cache.js
blob: f579ddb1b9763d61d2dd0d5ccf030f1ea9abecc4 (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
/* 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/>. */

/*
 * Test loading inline scripts from cache:
 *   - Load document with inline script
 *   - Reload inside debugger with toolbox caching disabled
 *   - Reload inside debugger with toolbox caching enabled
 */

"use strict";

// Breakpoint position calculations can throw when interrupted by a navigation.
PromiseTestUtils.allowMatchingRejectionsGlobally(/Resource .*? does not exist/);

const server = createTestHTTPServer();

let docValue = 1;
server.registerPathHandler("/inline-cache.html", (request, response) => {
  response.setHeader("Content-Type", "text/html");
  // HTTP should assume cacheable by default.
  // Toolbox defaults to disabling cache for subsequent loads when open.
  response.setHeader("Cache-Control", "public, max-age=3600");
  response.write(`
    <html>
    <head>
    <script>
      let x = ${docValue};
    </script>
    </head>
    </html>
  `);
});

const SOURCE_URL = `http://localhost:${server.identity.primaryPort}/inline-cache.html`;

add_task(async function () {
  info("Load document with inline script");
  const tab = await addTab(SOURCE_URL);
  info("Open debugger");
  clearDebuggerPreferences();
  const toolbox = await openToolboxForTab(tab, "jsdebugger");
  const dbg = createDebuggerContext(toolbox);
  await waitForSource(dbg, "inline-cache.html");
  info("Reload tab to ensure debugger finds script");
  await reloadBrowser();
  let pageValue = await getPageValue(tab);
  is(pageValue, "let x = 1;", "Content loads from network, has doc value 1");
  await waitForSource(dbg, "inline-cache.html");
  await selectSource(dbg, "inline-cache.html");
  await waitForLoadedSource(dbg, "inline-cache.html");
  let dbgValue = findSourceContent(dbg, "inline-cache.html");
  info(`Debugger text: ${dbgValue.value}`);
  ok(
    dbgValue.value.includes(pageValue),
    "Debugger loads from cache, gets value 1 like page"
  );

  info("Disable HTTP cache for page");
  await toolbox.commands.targetConfigurationCommand.updateConfiguration({
    cacheDisabled: true,
  });
  makeChanges();

  info("Reload inside debugger with toolbox caching disabled (attempt 1)");
  await reloadBrowser();
  pageValue = await getPageValue(tab);
  is(pageValue, "let x = 2;", "Content loads from network, has doc value 2");
  await waitForLoadedSource(dbg, "inline-cache.html");
  dbgValue = findSourceContent(dbg, "inline-cache.html");

  info(`Debugger text: ${dbgValue.value}`);
  ok(
    dbgValue.value.includes(pageValue),
    "Debugger loads from network, gets value 2 like page"
  );

  makeChanges();

  info("Reload inside debugger with toolbox caching disabled (attempt 2)");
  await reloadBrowser();
  pageValue = await getPageValue(tab);
  is(pageValue, "let x = 3;", "Content loads from network, has doc value 3");
  await waitForLoadedSource(dbg, "inline-cache.html");
  dbgValue = findSourceContent(dbg, "inline-cache.html");
  info(`Debugger text: ${dbgValue.value}`);
  ok(
    dbgValue.value.includes(pageValue),
    "Debugger loads from network, gets value 3 like page"
  );

  info("Enable HTTP cache for page");
  await toolbox.commands.targetConfigurationCommand.updateConfiguration({
    cacheDisabled: false,
  });
  makeChanges();

  // Even though the HTTP cache is now enabled, Gecko sets the VALIDATE_ALWAYS flag when
  // reloading the page.  So, it will always make a request to the server for the main
  // document contents.

  info("Reload inside debugger with toolbox caching enabled (attempt 1)");
  await reloadBrowser();
  pageValue = await getPageValue(tab);
  is(pageValue, "let x = 4;", "Content loads from network, has doc value 4");
  await waitForLoadedSource(dbg, "inline-cache.html");
  dbgValue = findSourceContent(dbg, "inline-cache.html");
  info(`Debugger text: ${dbgValue.value}`);
  ok(
    dbgValue.value.includes(pageValue),
    "Debugger loads from cache, gets value 4 like page"
  );

  makeChanges();

  info("Reload inside debugger with toolbox caching enabled (attempt 2)");
  await reloadBrowser();
  pageValue = await getPageValue(tab);
  is(pageValue, "let x = 5;", "Content loads from network, has doc value 5");
  await waitForLoadedSource(dbg, "inline-cache.html");
  await waitForSelectedSource(dbg, "inline-cache.html");
  dbgValue = findSourceContent(dbg, "inline-cache.html");
  info(`Debugger text: ${dbgValue.value}`);
  ok(
    dbgValue.value.includes(pageValue),
    "Debugger loads from cache, gets value 5 like page"
  );

  await toolbox.destroy();
  await removeTab(tab);
});

/**
 * This is meant to simulate the developer editing the inline source and saving.
 * Effectively, we change the source during the test at specific controlled points.
 */
function makeChanges() {
  docValue++;
}

function getPageValue(tab) {
  return SpecialPowers.spawn(tab.linkedBrowser, [], function () {
    return content.document.querySelector("script").textContent.trim();
  });
}