summaryrefslogtreecommitdiffstats
path: root/devtools/client/netmonitor/src/har/test/browser_net_har_multipage.js
blob: 1761e2042cc571f570c70023d3eeaae2046e4c6d (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
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

requestLongerTimeout(2);

const MULTIPAGE_IFRAME_URL = HAR_EXAMPLE_URL + "html_har_multipage_iframe.html";
const MULTIPAGE_PAGE_URL = HAR_EXAMPLE_URL + "html_har_multipage_page.html";

/**
 * Tests HAR export with navigations and multipage support
 */
add_task(async function () {
  await testHARWithNavigation({ enableMultipage: false, filter: false });
  await testHARWithNavigation({ enableMultipage: true, filter: false });
  await testHARWithNavigation({ enableMultipage: false, filter: true });
  await testHARWithNavigation({ enableMultipage: true, filter: true });
});

async function testHARWithNavigation({ enableMultipage, filter }) {
  await pushPref("devtools.netmonitor.persistlog", true);
  await pushPref("devtools.netmonitor.har.multiple-pages", enableMultipage);

  const { tab, monitor } = await initNetMonitor(MULTIPAGE_PAGE_URL + "?page1", {
    requestCount: 1,
  });

  info("Starting test... ");

  const { store, windowRequire } = monitor.panelWin;
  const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");

  store.dispatch(Actions.batchEnable(false));

  info("Perform 3 additional requests");
  let onNetworkEvents = waitForNetworkEvents(monitor, 3);
  await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
    content.wrappedJSObject.sendRequests(3);
  });
  await onNetworkEvents;

  info("Navigate to a second page where we will not perform any extra request");
  onNetworkEvents = waitForNetworkEvents(monitor, 1);
  await navigateTo(MULTIPAGE_PAGE_URL + "?page2");
  await onNetworkEvents;

  info("Navigate to a third page where we will not perform any extra request");
  onNetworkEvents = waitForNetworkEvents(monitor, 1);
  await navigateTo(MULTIPAGE_PAGE_URL + "?page3");
  await onNetworkEvents;

  info("Perform 2 additional requests");
  onNetworkEvents = waitForNetworkEvents(monitor, 2);
  await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
    content.wrappedJSObject.sendRequests(2);
  });
  await onNetworkEvents;

  info("Create an iframe which will perform 2 additional requests");
  onNetworkEvents = waitForNetworkEvents(monitor, 2);
  await SpecialPowers.spawn(
    tab.linkedBrowser,
    [MULTIPAGE_IFRAME_URL],
    async function (url) {
      const iframe = content.document.createElement("iframe");
      const onLoad = new Promise(resolve =>
        iframe.addEventListener("load", resolve, { once: true })
      );
      content.content.document.body.appendChild(iframe);
      iframe.setAttribute("src", url);
      await onLoad;
    }
  );
  await onNetworkEvents;

  if (filter) {
    info("Start filtering requests");
    store.dispatch(Actions.setRequestFilterText("?request"));
  }

  info("Trigger Copy All As HAR from the context menu");
  const har = await copyAllAsHARWithContextMenu(monitor);

  // Check out the HAR log.
  isnot(har.log, null, "The HAR log must exist");

  if (enableMultipage) {
    is(har.log.pages.length, 3, "There must be three pages");
  } else {
    is(har.log.pages.length, 1, "There must be one page");
  }

  if (!filter) {
    // Expect 9 requests:
    // - 3 requests performed with sendRequests on the first page
    // - 1 navigation request to the second page
    // - 1 navigation request to the third page
    // - 2 requests performed with sendRequests on the third page
    // - 1 request to load an iframe on the third page
    // - 1 request from the iframe on the third page
    is(har.log.entries.length, 9, "There must be 9 requests");
  } else {
    // Same but we only expect the fetch requests
    is(har.log.entries.length, 6, "There must be 6 requests");
  }

  if (enableMultipage) {
    // With multipage enabled, check that the page entries are valid and that
    // requests are referencing the expected page id.
    assertPageDetails(
      har.log.pages[0],
      "page_0",
      `${MULTIPAGE_PAGE_URL}?page1`
    );
    assertPageRequests(har.log.entries, 0, 2, har.log.pages[0].id);

    assertPageDetails(
      har.log.pages[1],
      "page_1",
      `${MULTIPAGE_PAGE_URL}?page2`
    );
    if (filter) {
      // When filtering, we don't expect any request to match page_1
    } else {
      assertPageRequests(har.log.entries, 3, 3, har.log.pages[1].id);
    }

    assertPageDetails(
      har.log.pages[2],
      "page_2",
      `${MULTIPAGE_PAGE_URL}?page3`
    );
    if (filter) {
      assertPageRequests(har.log.entries, 3, 5, har.log.pages[2].id);
    } else {
      assertPageRequests(har.log.entries, 4, 8, har.log.pages[2].id);
    }
  } else {
    is(har.log.pages[0].id, "page_1");
    // Without multipage, all requests are associated with the only page entry.
    for (const entry of har.log.entries) {
      is(entry.pageref, "page_1");
    }
  }

  // Clean up
  return teardown(monitor);
}

function assertPageDetails(page, expectedId, expectedTitle) {
  is(page.id, expectedId, "Page has the expected id");
  is(page.title, expectedTitle, "Page has the expected title");
}

function assertPageRequests(entries, startIndex, endIndex, expectedPageId) {
  for (let i = startIndex; i < endIndex + 1; i++) {
    const entry = entries[i];
    is(
      entry.pageref,
      expectedPageId,
      `Entry ${i} is attached to page id: ${expectedPageId}`
    );
  }
}