Do not announce robot account token before account ID is available
[chromium-blink-merge.git] / chrome / test / data / extensions / api_test / webnavigation / referenceFragment / framework.js
blob9d8cdca4eda9b361a4252fdfe05b4248dc657514
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 var deepEq = chrome.test.checkDeepEq;
6 var expectedEventData;
7 var expectedEventOrder;
8 var capturedEventData;
9 var nextFrameId;
10 var frameIds;
11 var nextTabId;
12 var tabIds;
13 var nextProcessId;
14 var processIds;
15 var initialized = false;
17 var debug = false;
19 function deepCopy(obj) {
20 if (obj === null)
21 return null;
22 if (typeof(obj) != 'object')
23 return obj;
24 if (Array.isArray(obj)) {
25 var tmp_array = new Array;
26 for (var i = 0; i < obj.length; i++) {
27 tmp_array.push(deepCopy(obj[i]));
29 return tmp_array;
32 var tmp_object = {}
33 for (var p in obj) {
34 tmp_object[p] = deepCopy(obj[p]);
36 return tmp_object;
39 // data: array of expected events, each one is a dictionary:
40 // { label: "<unique identifier>",
41 // event: "<webnavigation event type>",
42 // details: { <expected details of the event> }
43 // }
44 // order: an array of sequences, e.g. [ ["a", "b", "c"], ["d", "e"] ] means that
45 // event with label "a" needs to occur before event with label "b". The
46 // relative order of "a" and "d" does not matter.
47 function expect(data, order) {
48 expectedEventData = data;
49 capturedEventData = [];
50 expectedEventOrder = order;
51 nextFrameId = 1;
52 frameIds = {};
53 nextTabId = 0;
54 tabIds = {};
55 nextProcessId = 0;
56 processIds = {}
57 initListeners();
60 function checkExpectations() {
61 if (capturedEventData.length < expectedEventData.length) {
62 return;
64 if (capturedEventData.length > expectedEventData.length) {
65 chrome.test.fail("Recorded too many events. " +
66 JSON.stringify(capturedEventData));
68 // We have ensured that capturedEventData contains exactly the same elements
69 // as expectedEventData. Now we need to verify the ordering.
70 // Step 1: build positions such that
71 // position[<event-label>]=<position of this event in capturedEventData>
72 var curPos = 0;
73 var positions = {};
74 capturedEventData.forEach(function (event) {
75 chrome.test.assertTrue(event.hasOwnProperty("label"));
76 positions[event.label] = curPos;
77 curPos++;
78 });
79 // Step 2: check that elements arrived in correct order
80 expectedEventOrder.forEach(function (order) {
81 var previousLabel = undefined;
82 order.forEach(function (label) {
83 if (previousLabel === undefined) {
84 previousLabel = label;
85 return;
87 chrome.test.assertTrue(positions[previousLabel] < positions[label],
88 "Event " + previousLabel + " is supposed to arrive before " +
89 label + ".");
90 previousLabel = label;
91 });
92 });
93 chrome.test.succeed();
96 function captureEvent(name, details) {
97 if ('url' in details) {
98 // Skip about:blank navigations
99 if (details.url == 'about:blank') {
100 return;
102 // Strip query parameter as it is hard to predict.
103 details.url = details.url.replace(new RegExp('\\?[^#]*'), '');
105 // normalize details.
106 if ('timeStamp' in details) {
107 details.timeStamp = 0;
109 if (('frameId' in details) && (details.frameId != 0)) {
110 if (frameIds[details.frameId] === undefined) {
111 frameIds[details.frameId] = nextFrameId++;
113 details.frameId = frameIds[details.frameId];
115 if (('parentFrameId' in details) && (details.parentFrameId > 0)) {
116 if (frameIds[details.parentFrameId] === undefined) {
117 frameIds[details.parentFrameId] = nextFrameId++;
119 details.parentFrameId = frameIds[details.parentFrameId];
121 if (('sourceFrameId' in details) && (details.sourceFrameId != 0)) {
122 if (frameIds[details.sourceFrameId] === undefined) {
123 frameIds[details.sourceFrameId] = nextFrameId++;
125 details.sourceFrameId = frameIds[details.sourceFrameId];
127 if ('tabId' in details) {
128 if (tabIds[details.tabId] === undefined) {
129 tabIds[details.tabId] = nextTabId++;
131 details.tabId = tabIds[details.tabId];
133 if ('sourceTabId' in details) {
134 if (tabIds[details.sourceTabId] === undefined) {
135 tabIds[details.sourceTabId] = nextTabId++;
137 details.sourceTabId = tabIds[details.sourceTabId];
139 if ('replacedTabId' in details) {
140 if (tabIds[details.replacedTabId] === undefined) {
141 tabIds[details.replacedTabId] = nextTabId++;
143 details.replacedTabId = tabIds[details.replacedTabId];
145 if ('processId' in details) {
146 if (processIds[details.processId] === undefined) {
147 processIds[details.processId] = nextProcessId++;
149 details.processId = processIds[details.processId];
151 if ('sourceProcessId' in details) {
152 if (processIds[details.sourceProcessId] === undefined) {
153 processIds[details.sourceProcessId] = nextProcessId++;
155 details.sourceProcessId = processIds[details.sourceProcessId];
158 if (debug)
159 console.log("Received event '" + name + "':" + JSON.stringify(details));
161 // find |details| in expectedEventData
162 var found = false;
163 var label = undefined;
164 expectedEventData.forEach(function (exp) {
165 if (exp.event == name) {
166 var exp_details;
167 var alt_details;
168 if ('transitionQualifiers' in exp.details) {
169 var idx = exp.details['transitionQualifiers'].indexOf(
170 'maybe_client_redirect');
171 if (idx >= 0) {
172 exp_details = deepCopy(exp.details);
173 exp_details['transitionQualifiers'].splice(idx, 1);
174 alt_details = deepCopy(exp_details);
175 alt_details['transitionQualifiers'].push('client_redirect');
176 } else {
177 exp_details = exp.details;
178 alt_details = exp.details;
180 } else {
181 exp_details = exp.details;
182 alt_details = exp.details;
184 if (deepEq(exp_details, details) || deepEq(alt_details, details)) {
185 if (!found) {
186 found = true;
187 label = exp.label;
188 exp.event = undefined;
193 if (!found) {
194 chrome.test.fail("Received unexpected event '" + name + "':" +
195 JSON.stringify(details));
197 capturedEventData.push({label: label, event: name, details: details});
198 checkExpectations();
201 function initListeners() {
202 if (initialized)
203 return;
204 initialized = true;
205 chrome.webNavigation.onBeforeNavigate.addListener(
206 function(details) {
207 captureEvent("onBeforeNavigate", details);
209 chrome.webNavigation.onCommitted.addListener(
210 function(details) {
211 captureEvent("onCommitted", details);
213 chrome.webNavigation.onDOMContentLoaded.addListener(
214 function(details) {
215 captureEvent("onDOMContentLoaded", details);
217 chrome.webNavigation.onCompleted.addListener(
218 function(details) {
219 captureEvent("onCompleted", details);
221 chrome.webNavigation.onCreatedNavigationTarget.addListener(
222 function(details) {
223 captureEvent("onCreatedNavigationTarget", details);
225 chrome.webNavigation.onReferenceFragmentUpdated.addListener(
226 function(details) {
227 captureEvent("onReferenceFragmentUpdated", details);
229 chrome.webNavigation.onErrorOccurred.addListener(
230 function(details) {
231 captureEvent("onErrorOccurred", details);
233 chrome.webNavigation.onTabReplaced.addListener(
234 function(details) {
235 captureEvent("onTabReplaced", details);
237 chrome.webNavigation.onHistoryStateUpdated.addListener(
238 function(details) {
239 captureEvent("onHistoryStateUpdated", details);
243 // Returns the usual order of navigation events.
244 function navigationOrder(prefix) {
245 return [ prefix + "onBeforeNavigate",
246 prefix + "onCommitted",
247 prefix + "onDOMContentLoaded",
248 prefix + "onCompleted" ];
251 // Returns the constraints expressing that a frame is an iframe of another
252 // frame.
253 function isIFrameOf(iframe, main_frame) {
254 return [ main_frame + "onCommitted",
255 iframe + "onBeforeNavigate",
256 iframe + "onCompleted",
257 main_frame + "onCompleted" ];
260 // Returns the constraint expressing that a frame was loaded by another.
261 function isLoadedBy(target, source) {
262 return [ source + "onDOMContentLoaded", target + "onBeforeNavigate"];