Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 var deepEq = chrome.test.checkDeepEq; | |
| 5 var expectedEventData; | 6 var expectedEventData; |
| 7 var expectedEventOrder; | |
| 6 var capturedEventData; | 8 var capturedEventData; |
| 7 var nextFrameId; | 9 var nextFrameId; |
| 8 var frameIds; | 10 var frameIds; |
| 9 var nextTabId; | 11 var nextTabId; |
| 10 var tabIds; | 12 var tabIds; |
| 11 var initialized = false; | 13 var initialized = false; |
| 12 | 14 |
| 13 function expect(data) { | 15 // data: array of expected events, each one is a dictionary: |
| 16 // { label: "<unique identifier>", | |
| 17 // event: "<webnavigation event type>", | |
| 18 // details: { <expected details of the event> } | |
| 19 // } | |
| 20 // order: an array of sequences, e.g. [ ["a", "b", "c"], ["d", "e"] ] means that | |
| 21 // event with label "a" needs to occur before event with label "b". The | |
| 22 // relative order of "a" and "d" does not matter. | |
| 23 function expect(data, order) { | |
| 14 expectedEventData = data; | 24 expectedEventData = data; |
| 15 capturedEventData = []; | 25 capturedEventData = []; |
| 26 expectedEventOrder = order; | |
| 16 nextFrameId = 1; | 27 nextFrameId = 1; |
| 17 frameIds = {}; | 28 frameIds = {}; |
| 18 nextTabId = 0; | 29 nextTabId = 0; |
| 19 tabIds = {}; | 30 tabIds = {}; |
| 20 initListeners(); | 31 initListeners(); |
| 21 } | 32 } |
| 22 | 33 |
| 23 function checkExpectations() { | 34 function checkExpectations() { |
| 24 if (capturedEventData.length < expectedEventData.length) { | 35 if (capturedEventData.length < expectedEventData.length) { |
| 25 return; | 36 return; |
| 26 } | 37 } |
| 27 chrome.test.assertEq(JSON.stringify(expectedEventData), | 38 if (capturedEventData.length > expectedEventData.length) { |
| 28 JSON.stringify(capturedEventData)); | 39 chrome.test.fail("Recorded too many events. " + |
| 40 JSON.stringify(capturedEventData)); | |
| 41 } | |
| 42 // We have ensured that capturedEventData contains exactly the same elements | |
| 43 // as expectedEventData. Now we need to verify the ordering. | |
| 44 // Step 1: build positions such that | |
| 45 // position[<event-label>]=<position of this event in capturedEventData> | |
| 46 var curPos = 0; | |
| 47 var positions = {}; | |
| 48 capturedEventData.forEach(function (event) { | |
| 49 chrome.test.assertTrue(event.hasOwnProperty("label")); | |
| 50 positions[event.label] = curPos; | |
| 51 curPos++; | |
| 52 }); | |
| 53 // Step 2: check that elements arrived in correct order | |
| 54 expectedEventOrder.forEach(function (order) { | |
| 55 var previousLabel = undefined; | |
| 56 order.forEach(function (label) { | |
| 57 if (previousLabel === undefined) { | |
| 58 previousLabel = label; | |
| 59 return; | |
| 60 } | |
| 61 chrome.test.assertTrue(positions[previousLabel] < positions[label], | |
| 62 "Event " + previousLabel + " is supposed to arrive before " + | |
| 63 label + "."); | |
| 64 previousLabel = label; | |
| 65 }); | |
| 66 }); | |
| 29 chrome.test.succeed(); | 67 chrome.test.succeed(); |
| 30 } | 68 } |
| 31 | 69 |
| 32 function captureEvent(name, details) { | 70 function captureEvent(name, details) { |
| 33 // Skip about:blank navigations | 71 // Skip about:blank navigations |
| 34 if ('url' in details && details.url == 'about:blank') { | 72 if ('url' in details && details.url == 'about:blank') { |
| 35 return; | 73 return; |
| 36 } | 74 } |
| 37 // normalize details. | 75 // normalize details. |
| 38 if ('timeStamp' in details) { | 76 if ('timeStamp' in details) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 55 tabIds[details.tabId] = nextTabId++; | 93 tabIds[details.tabId] = nextTabId++; |
| 56 } | 94 } |
| 57 details.tabId = tabIds[details.tabId]; | 95 details.tabId = tabIds[details.tabId]; |
| 58 } | 96 } |
| 59 if ('sourceTabId' in details) { | 97 if ('sourceTabId' in details) { |
| 60 if (tabIds[details.sourceTabId] === undefined) { | 98 if (tabIds[details.sourceTabId] === undefined) { |
| 61 tabIds[details.sourceTabId] = nextTabId++; | 99 tabIds[details.sourceTabId] = nextTabId++; |
| 62 } | 100 } |
| 63 details.sourceTabId = tabIds[details.sourceTabId]; | 101 details.sourceTabId = tabIds[details.sourceTabId]; |
| 64 } | 102 } |
| 65 capturedEventData.push([name, details]); | 103 |
| 104 // find |details| in expectedEventData | |
| 105 var found = false; | |
| 106 var label = undefined; | |
| 107 expectedEventData.forEach(function (exp) { | |
| 108 if (deepEq(exp.event, name) && deepEq(exp.details, details)) { | |
| 109 if (!found) { | |
| 110 found = true; | |
| 111 label = exp.label; | |
| 112 exp.event = undefined; | |
| 113 } | |
| 114 } | |
| 115 }); | |
| 116 if (!found) { | |
| 117 chrome.test.fail("Received unexpected event '" + name + "':" + | |
| 118 JSON.stringify(details)); | |
| 119 } | |
| 120 capturedEventData.push({label: label, event: name, details: details}); | |
| 66 checkExpectations(); | 121 checkExpectations(); |
| 67 } | 122 } |
| 68 | 123 |
| 69 function initListeners() { | 124 function initListeners() { |
| 70 if (initialized) | 125 if (initialized) |
| 71 return; | 126 return; |
| 72 initialized = true; | 127 initialized = true; |
| 73 chrome.experimental.webNavigation.onBeforeNavigate.addListener( | 128 chrome.experimental.webNavigation.onBeforeNavigate.addListener( |
| 74 function(details) { | 129 function(details) { |
| 75 captureEvent("onBeforeNavigate", details); | 130 captureEvent("onBeforeNavigate", details); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 92 }); | 147 }); |
| 93 chrome.experimental.webNavigation.onReferenceFragmentUpdated.addListener( | 148 chrome.experimental.webNavigation.onReferenceFragmentUpdated.addListener( |
| 94 function(details) { | 149 function(details) { |
| 95 captureEvent("onReferenceFragmentUpdated", details); | 150 captureEvent("onReferenceFragmentUpdated", details); |
| 96 }); | 151 }); |
| 97 chrome.experimental.webNavigation.onErrorOccurred.addListener( | 152 chrome.experimental.webNavigation.onErrorOccurred.addListener( |
| 98 function(details) { | 153 function(details) { |
| 99 captureEvent("onErrorOccurred", details); | 154 captureEvent("onErrorOccurred", details); |
| 100 }); | 155 }); |
| 101 } | 156 } |
| 157 | |
| 158 // Returns the usual order of navigation events. | |
| 159 function navigationOrder(prefix) { | |
|
Matt Perry
2011/09/09 19:28:15
great idea!
| |
| 160 return [ prefix + "onBeforeNavigate", | |
| 161 prefix + "onCommitted", | |
| 162 prefix + "onDOMContentLoaded", | |
| 163 prefix + "onCompleted" ]; | |
| 164 } | |
| 165 | |
| 166 // Returns the constraints expressing that a frame is an iframe of another | |
| 167 // frame. | |
| 168 function isIFrameOf(iframe, main_frame) { | |
| 169 return [ main_frame + "onCommitted", | |
| 170 iframe + "onBeforeNavigate", | |
| 171 main_frame + "onDOMContentLoaded", | |
| 172 iframe + "onCompleted", | |
| 173 main_frame + "onCompleted" ]; | |
| 174 } | |
| 175 | |
| 176 // Returns the constraint expressing that a frame was loaded by another. | |
| 177 function isLoadedBy(target, source) { | |
| 178 return [ source + "onDOMContentLoaded", target + "onBeforeNavigate"]; | |
| 179 } | |
| OLD | NEW |