OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
11 * copyright notice, this list of conditions and the following disclaimer | 11 * copyright notice, this list of conditions and the following disclaimer |
12 * in the documentation and/or other materials provided with the | 12 * in the documentation and/or other materials provided with the |
13 * distribution. | 13 * distribution. |
14 * * Neither the name of Google Inc. nor the names of its | 14 * * Neither the name of Google Inc. nor the names of its |
15 * contributors may be used to endorse or promote products derived from | 15 * contributors may be used to endorse or promote products derived from |
16 * this software without specific prior written permission. | 16 * this software without specific prior written permission. |
17 * | 17 * |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | |
31 /* eslint-disable indent */ | 30 /* eslint-disable indent */ |
32 | 31 |
33 /** | 32 /** |
34 * @fileoverview This file contains small testing framework along with the | 33 * @fileoverview This file contains small testing framework along with the |
35 * test suite for the frontend. These tests are a part of the continues build | 34 * test suite for the frontend. These tests are a part of the continues build |
36 * and are executed by the devtools_sanity_unittest.cc as a part of the | 35 * and are executed by the devtools_sanity_unittest.cc as a part of the |
37 * Interactive UI Test suite. | 36 * Interactive UI Test suite. |
38 * FIXME: change field naming style to use trailing underscore. | 37 * FIXME: change field naming style to use trailing underscore. |
39 */ | 38 */ |
40 | 39 |
41 (function createTestSuite(window) | 40 (function createTestSuite(window) { |
42 { | 41 |
43 | 42 /** |
44 /** | 43 * @unrestricted |
45 * Test suite for interactive UI tests. | 44 */ |
46 * @constructor | 45 var TestSuite = class { |
47 * @param {Object} domAutomationController DomAutomationController instance. | 46 /** |
48 */ | 47 * Test suite for interactive UI tests. |
49 function TestSuite(domAutomationController) | 48 * @param {Object} domAutomationController DomAutomationController instance. |
50 { | 49 */ |
51 this.domAutomationController_ = domAutomationController; | 50 constructor(domAutomationController) { |
52 this.controlTaken_ = false; | 51 this.domAutomationController_ = domAutomationController; |
53 this.timerId_ = -1; | 52 this.controlTaken_ = false; |
54 this._asyncInvocationId = 0; | 53 this.timerId_ = -1; |
55 } | 54 this._asyncInvocationId = 0; |
56 | 55 } |
57 /** | 56 |
58 * Reports test failure. | 57 /** |
59 * @param {string} message Failure description. | 58 * Key event with given key identifier. |
60 */ | 59 */ |
61 TestSuite.prototype.fail = function(message) | 60 static createKeyEvent(key) { |
62 { | 61 return new KeyboardEvent('keydown', {bubbles: true, cancelable: true, key:
key}); |
| 62 } |
| 63 }; |
| 64 |
| 65 /** |
| 66 * Reports test failure. |
| 67 * @param {string} message Failure description. |
| 68 */ |
| 69 TestSuite.prototype.fail = function(message) { |
63 if (this.controlTaken_) | 70 if (this.controlTaken_) |
64 this.reportFailure_(message); | 71 this.reportFailure_(message); |
65 else | 72 else |
66 throw message; | 73 throw message; |
67 }; | 74 }; |
68 | 75 |
69 | 76 /** |
70 /** | 77 * Equals assertion tests that expected === actual. |
71 * Equals assertion tests that expected === actual. | 78 * @param {!Object|boolean} expected Expected object. |
72 * @param {!Object|boolean} expected Expected object. | 79 * @param {!Object|boolean} actual Actual object. |
73 * @param {!Object|boolean} actual Actual object. | 80 * @param {string} opt_message User message to print if the test fails. |
74 * @param {string} opt_message User message to print if the test fails. | 81 */ |
75 */ | 82 TestSuite.prototype.assertEquals = function(expected, actual, opt_message) { |
76 TestSuite.prototype.assertEquals = function(expected, actual, opt_message) | |
77 { | |
78 if (expected !== actual) { | 83 if (expected !== actual) { |
79 var message = "Expected: '" + expected + "', but was '" + actual + "'"; | 84 var message = 'Expected: \'' + expected + '\', but was \'' + actual + '\''
; |
80 if (opt_message) | 85 if (opt_message) |
81 message = opt_message + "(" + message + ")"; | 86 message = opt_message + '(' + message + ')'; |
82 this.fail(message); | 87 this.fail(message); |
83 } | 88 } |
84 }; | 89 }; |
85 | 90 |
86 | 91 /** |
87 /** | 92 * True assertion tests that value == true. |
88 * True assertion tests that value == true. | 93 * @param {!Object} value Actual object. |
89 * @param {!Object} value Actual object. | 94 * @param {string} opt_message User message to print if the test fails. |
90 * @param {string} opt_message User message to print if the test fails. | 95 */ |
91 */ | 96 TestSuite.prototype.assertTrue = function(value, opt_message) { |
92 TestSuite.prototype.assertTrue = function(value, opt_message) | |
93 { | |
94 this.assertEquals(true, !!value, opt_message); | 97 this.assertEquals(true, !!value, opt_message); |
95 }; | 98 }; |
96 | 99 |
97 | 100 /** |
98 /** | 101 * Takes control over execution. |
99 * Takes control over execution. | 102 */ |
100 */ | 103 TestSuite.prototype.takeControl = function() { |
101 TestSuite.prototype.takeControl = function() | |
102 { | |
103 this.controlTaken_ = true; | 104 this.controlTaken_ = true; |
104 // Set up guard timer. | 105 // Set up guard timer. |
105 var self = this; | 106 var self = this; |
106 this.timerId_ = setTimeout(function() { | 107 this.timerId_ = setTimeout(function() { |
107 self.reportFailure_("Timeout exceeded: 20 sec"); | 108 self.reportFailure_('Timeout exceeded: 20 sec'); |
108 }, 20000); | 109 }, 20000); |
109 }; | 110 }; |
110 | 111 |
111 | 112 /** |
112 /** | 113 * Releases control over execution. |
113 * Releases control over execution. | 114 */ |
114 */ | 115 TestSuite.prototype.releaseControl = function() { |
115 TestSuite.prototype.releaseControl = function() | |
116 { | |
117 if (this.timerId_ !== -1) { | 116 if (this.timerId_ !== -1) { |
118 clearTimeout(this.timerId_); | 117 clearTimeout(this.timerId_); |
119 this.timerId_ = -1; | 118 this.timerId_ = -1; |
120 } | 119 } |
121 this.controlTaken_ = false; | 120 this.controlTaken_ = false; |
122 this.reportOk_(); | 121 this.reportOk_(); |
123 }; | 122 }; |
124 | 123 |
125 | 124 /** |
126 /** | 125 * Async tests use this one to report that they are completed. |
127 * Async tests use this one to report that they are completed. | 126 */ |
128 */ | 127 TestSuite.prototype.reportOk_ = function() { |
129 TestSuite.prototype.reportOk_ = function() | 128 this.domAutomationController_.send('[OK]'); |
130 { | 129 }; |
131 this.domAutomationController_.send("[OK]"); | 130 |
132 }; | 131 /** |
133 | 132 * Async tests use this one to report failures. |
134 | 133 */ |
135 /** | 134 TestSuite.prototype.reportFailure_ = function(error) { |
136 * Async tests use this one to report failures. | |
137 */ | |
138 TestSuite.prototype.reportFailure_ = function(error) | |
139 { | |
140 if (this.timerId_ !== -1) { | 135 if (this.timerId_ !== -1) { |
141 clearTimeout(this.timerId_); | 136 clearTimeout(this.timerId_); |
142 this.timerId_ = -1; | 137 this.timerId_ = -1; |
143 } | 138 } |
144 this.domAutomationController_.send("[FAILED] " + error); | 139 this.domAutomationController_.send('[FAILED] ' + error); |
145 }; | 140 }; |
146 | 141 |
147 | 142 /** |
148 /** | 143 * Run specified test on a fresh instance of the test suite. |
149 * Run specified test on a fresh instance of the test suite. | 144 * @param {Array<string>} args method name followed by its parameters. |
150 * @param {Array<string>} args method name followed by its parameters. | 145 */ |
151 */ | 146 TestSuite.prototype.dispatchOnTestSuite = function(args) { |
152 TestSuite.prototype.dispatchOnTestSuite = function(args) | |
153 { | |
154 var methodName = args.shift(); | 147 var methodName = args.shift(); |
155 try { | 148 try { |
156 this[methodName].apply(this, args); | 149 this[methodName].apply(this, args); |
157 if (!this.controlTaken_) | 150 if (!this.controlTaken_) |
158 this.reportOk_(); | 151 this.reportOk_(); |
159 } catch (e) { | 152 } catch (e) { |
160 this.reportFailure_(e); | 153 this.reportFailure_(e); |
161 } | 154 } |
162 }; | 155 }; |
163 | 156 |
164 | 157 /** |
165 /** | 158 * Wrap an async method with TestSuite.{takeControl(), releaseControl()} |
166 * Wrap an async method with TestSuite.{takeControl(), releaseControl()} | 159 * and invoke TestSuite.reportOk_ upon completion. |
167 * and invoke TestSuite.reportOk_ upon completion. | 160 * @param {Array<string>} args method name followed by its parameters. |
168 * @param {Array<string>} args method name followed by its parameters. | 161 */ |
169 */ | 162 TestSuite.prototype.waitForAsync = function(var_args) { |
170 TestSuite.prototype.waitForAsync = function(var_args) | |
171 { | |
172 var args = Array.prototype.slice.call(arguments); | 163 var args = Array.prototype.slice.call(arguments); |
173 this.takeControl(); | 164 this.takeControl(); |
174 args.push(this.releaseControl.bind(this)); | 165 args.push(this.releaseControl.bind(this)); |
175 this.dispatchOnTestSuite(args); | 166 this.dispatchOnTestSuite(args); |
176 }; | 167 }; |
177 | 168 |
178 /** | 169 /** |
179 * Overrides the method with specified name until it's called first time. | 170 * Overrides the method with specified name until it's called first time. |
180 * @param {!Object} receiver An object whose method to override. | 171 * @param {!Object} receiver An object whose method to override. |
181 * @param {string} methodName Name of the method to override. | 172 * @param {string} methodName Name of the method to override. |
182 * @param {!Function} override A function that should be called right after the | 173 * @param {!Function} override A function that should be called right after th
e |
183 * overridden method returns. | 174 * overridden method returns. |
184 * @param {?boolean} opt_sticky Whether restore original method after first run | 175 * @param {?boolean} opt_sticky Whether restore original method after first ru
n |
185 * or not. | 176 * or not. |
186 */ | 177 */ |
187 TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_st
icky) | 178 TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_
sticky) { |
188 { | |
189 var orig = receiver[methodName]; | 179 var orig = receiver[methodName]; |
190 if (typeof orig !== "function") | 180 if (typeof orig !== 'function') |
191 this.fail("Cannot find method to override: " + methodName); | 181 this.fail('Cannot find method to override: ' + methodName); |
192 var test = this; | 182 var test = this; |
193 receiver[methodName] = function(var_args) { | 183 receiver[methodName] = function(var_args) { |
194 try { | 184 try { |
195 var result = orig.apply(this, arguments); | 185 var result = orig.apply(this, arguments); |
196 } finally { | 186 } finally { |
197 if (!opt_sticky) | 187 if (!opt_sticky) |
198 receiver[methodName] = orig; | 188 receiver[methodName] = orig; |
199 } | 189 } |
200 // In case of exception the override won't be called. | 190 // In case of exception the override won't be called. |
201 try { | 191 try { |
202 override.apply(this, arguments); | 192 override.apply(this, arguments); |
203 } catch (e) { | 193 } catch (e) { |
204 test.fail("Exception in overriden method '" + methodName + "': " + e
); | 194 test.fail('Exception in overriden method \'' + methodName + '\': ' + e); |
205 } | 195 } |
206 return result; | 196 return result; |
207 }; | 197 }; |
208 }; | 198 }; |
209 | 199 |
210 /** | 200 /** |
211 * Waits for current throttler invocations, if any. | 201 * Waits for current throttler invocations, if any. |
212 * @param {!WebInspector.Throttler} throttler | 202 * @param {!WebInspector.Throttler} throttler |
213 * @param {function()} callback | 203 * @param {function()} callback |
214 */ | 204 */ |
215 TestSuite.prototype.waitForThrottler = function(throttler, callback) | 205 TestSuite.prototype.waitForThrottler = function(throttler, callback) { |
216 { | |
217 var test = this; | 206 var test = this; |
218 var scheduleShouldFail = true; | 207 var scheduleShouldFail = true; |
219 test.addSniffer(throttler, "schedule", onSchedule); | 208 test.addSniffer(throttler, 'schedule', onSchedule); |
220 | 209 |
221 function hasSomethingScheduled() | 210 function hasSomethingScheduled() { |
222 { | 211 return throttler._isRunningProcess || throttler._process; |
223 return throttler._isRunningProcess || throttler._process; | 212 } |
224 } | 213 |
225 | 214 function checkState() { |
226 function checkState() | 215 if (!hasSomethingScheduled()) { |
227 { | 216 scheduleShouldFail = false; |
228 if (!hasSomethingScheduled()) { | 217 callback(); |
229 scheduleShouldFail = false; | 218 return; |
230 callback(); | 219 } |
231 return; | 220 |
232 } | 221 test.addSniffer(throttler, '_processCompletedForTests', checkState); |
233 | 222 } |
234 test.addSniffer(throttler, "_processCompletedForTests", checkState); | 223 |
235 } | 224 function onSchedule() { |
236 | 225 if (scheduleShouldFail) |
237 function onSchedule() | 226 test.fail('Unexpected Throttler.schedule'); |
238 { | |
239 if (scheduleShouldFail) | |
240 test.fail("Unexpected Throttler.schedule"); | |
241 } | 227 } |
242 | 228 |
243 checkState(); | 229 checkState(); |
244 }; | 230 }; |
245 | 231 |
246 /** | 232 /** |
247 * @param {string} panelName Name of the panel to show. | 233 * @param {string} panelName Name of the panel to show. |
248 */ | 234 */ |
249 TestSuite.prototype.showPanel = function(panelName) | 235 TestSuite.prototype.showPanel = function(panelName) { |
250 { | |
251 return WebInspector.inspectorView.showPanel(panelName); | 236 return WebInspector.inspectorView.showPanel(panelName); |
252 }; | 237 }; |
253 | 238 |
254 // UI Tests | 239 // UI Tests |
255 | 240 |
256 | 241 /** |
257 /** | 242 * Tests that scripts tab can be open and populated with inspected scripts. |
258 * Tests that scripts tab can be open and populated with inspected scripts. | 243 */ |
259 */ | 244 TestSuite.prototype.testShowScriptsTab = function() { |
260 TestSuite.prototype.testShowScriptsTab = function() | 245 var test = this; |
261 { | 246 this.showPanel('sources').then(function() { |
262 var test = this; | 247 // There should be at least main page script. |
263 this.showPanel("sources").then(function() { | 248 this._waitUntilScriptsAreParsed(['debugger_test_page.html'], function() { |
264 // There should be at least main page script. | 249 test.releaseControl(); |
265 this._waitUntilScriptsAreParsed(["debugger_test_page.html"], | 250 }); |
266 function() { | |
267 test.releaseControl(); | |
268 }); | |
269 }.bind(this)); | 251 }.bind(this)); |
270 // Wait until all scripts are added to the debugger. | 252 // Wait until all scripts are added to the debugger. |
271 this.takeControl(); | 253 this.takeControl(); |
272 }; | 254 }; |
273 | 255 |
274 | 256 /** |
275 /** | 257 * Tests that scripts tab is populated with inspected scripts even if it |
276 * Tests that scripts tab is populated with inspected scripts even if it | 258 * hadn't been shown by the moment inspected paged refreshed. |
277 * hadn't been shown by the moment inspected paged refreshed. | 259 * @see http://crbug.com/26312 |
278 * @see http://crbug.com/26312 | 260 */ |
279 */ | 261 TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function
() { |
280 TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function() | |
281 { | |
282 var test = this; | 262 var test = this; |
283 var debuggerModel = WebInspector.DebuggerModel.fromTarget(WebInspector.targe
tManager.mainTarget()); | 263 var debuggerModel = WebInspector.DebuggerModel.fromTarget(WebInspector.targe
tManager.mainTarget()); |
284 debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjec
tCleared, waitUntilScriptIsParsed); | 264 debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjec
tCleared, waitUntilScriptIsParsed); |
285 | 265 |
286 this.showPanel("elements").then(function() { | 266 this.showPanel('elements').then(function() { |
287 // Reload inspected page. It will reset the debugger agent. | 267 // Reload inspected page. It will reset the debugger agent. |
288 test.evaluateInConsole_("window.location.reload(true);", function(result
Text) {}); | 268 test.evaluateInConsole_('window.location.reload(true);', function(resultTe
xt) {}); |
289 }); | 269 }); |
290 | 270 |
291 function waitUntilScriptIsParsed() | 271 function waitUntilScriptIsParsed() { |
292 { | 272 debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.Global
ObjectCleared, waitUntilScriptIsParsed); |
293 debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.Glob
alObjectCleared, waitUntilScriptIsParsed); | 273 test.showPanel('sources').then(function() { |
294 test.showPanel("sources").then(function() { | 274 test._waitUntilScriptsAreParsed(['debugger_test_page.html'], function()
{ |
295 test._waitUntilScriptsAreParsed(["debugger_test_page.html"], | 275 test.releaseControl(); |
296 function() { | |
297 test.releaseControl(); | |
298 }); | |
299 }); | 276 }); |
| 277 }); |
300 } | 278 } |
301 | 279 |
302 // Wait until all scripts are added to the debugger. | 280 // Wait until all scripts are added to the debugger. |
303 this.takeControl(); | 281 this.takeControl(); |
304 }; | 282 }; |
305 | 283 |
306 | 284 /** |
307 /** | 285 * Tests that scripts list contains content scripts. |
308 * Tests that scripts list contains content scripts. | 286 */ |
309 */ | 287 TestSuite.prototype.testContentScriptIsPresent = function() { |
310 TestSuite.prototype.testContentScriptIsPresent = function() | 288 var test = this; |
311 { | 289 this.showPanel('sources').then(function() { |
312 var test = this; | 290 test._waitUntilScriptsAreParsed(['page_with_content_script.html', 'simple_
content_script.js'], function() { |
313 this.showPanel("sources").then(function() { | 291 test.releaseControl(); |
314 test._waitUntilScriptsAreParsed( | 292 }); |
315 ["page_with_content_script.html", "simple_content_script.js"], | |
316 function() { | |
317 test.releaseControl(); | |
318 }); | |
319 }); | 293 }); |
320 | 294 |
321 // Wait until all scripts are added to the debugger. | 295 // Wait until all scripts are added to the debugger. |
322 this.takeControl(); | 296 this.takeControl(); |
323 }; | 297 }; |
324 | 298 |
325 | 299 /** |
326 /** | 300 * Tests that scripts are not duplicaed on Scripts tab switch. |
327 * Tests that scripts are not duplicaed on Scripts tab switch. | 301 */ |
328 */ | 302 TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function() { |
329 TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function() | |
330 { | |
331 var test = this; | 303 var test = this; |
332 | 304 |
333 // There should be two scripts: one for the main page and another | 305 // There should be two scripts: one for the main page and another |
334 // one which is source of console API(see | 306 // one which is source of console API(see |
335 // InjectedScript._ensureCommandLineAPIInstalled). | 307 // InjectedScript._ensureCommandLineAPIInstalled). |
336 var expectedScriptsCount = 2; | 308 var expectedScriptsCount = 2; |
337 var parsedScripts = []; | 309 var parsedScripts = []; |
338 | 310 |
339 function switchToElementsTab() { | 311 function switchToElementsTab() { |
340 test.showPanel("elements").then(function() { | 312 test.showPanel('elements').then(function() { |
341 setTimeout(switchToScriptsTab, 0); | 313 setTimeout(switchToScriptsTab, 0); |
342 }); | 314 }); |
343 } | 315 } |
344 | 316 |
345 function switchToScriptsTab() { | 317 function switchToScriptsTab() { |
346 test.showPanel("sources").then(function() { | 318 test.showPanel('sources').then(function() { |
347 setTimeout(checkScriptsPanel, 0); | 319 setTimeout(checkScriptsPanel, 0); |
348 }); | 320 }); |
349 } | 321 } |
350 | 322 |
351 function checkScriptsPanel() { | 323 function checkScriptsPanel() { |
352 test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html"]), "So
me scripts are missing."); | 324 test.assertTrue(test._scriptsAreParsed(['debugger_test_page.html']), 'Some
scripts are missing.'); |
| 325 checkNoDuplicates(); |
| 326 test.releaseControl(); |
| 327 } |
| 328 |
| 329 function checkNoDuplicates() { |
| 330 var uiSourceCodes = test.nonAnonymousUISourceCodes_(); |
| 331 for (var i = 0; i < uiSourceCodes.length; i++) { |
| 332 for (var j = i + 1; j < uiSourceCodes.length; j++) |
| 333 test.assertTrue( |
| 334 uiSourceCodes[i].url() !== uiSourceCodes[j].url(), |
| 335 'Found script duplicates: ' + test.uiSourceCodesToString_(uiSource
Codes)); |
| 336 } |
| 337 } |
| 338 |
| 339 this.showPanel('sources').then(function() { |
| 340 test._waitUntilScriptsAreParsed(['debugger_test_page.html'], function() { |
353 checkNoDuplicates(); | 341 checkNoDuplicates(); |
354 test.releaseControl(); | 342 setTimeout(switchToElementsTab, 0); |
355 } | 343 }); |
356 | |
357 function checkNoDuplicates() { | |
358 var uiSourceCodes = test.nonAnonymousUISourceCodes_(); | |
359 for (var i = 0; i < uiSourceCodes.length; i++) { | |
360 for (var j = i + 1; j < uiSourceCodes.length; j++) | |
361 test.assertTrue(uiSourceCodes[i].url() !== uiSourceCodes[j].url(
), "Found script duplicates: " + test.uiSourceCodesToString_(uiSourceCodes)); | |
362 } | |
363 } | |
364 | |
365 this.showPanel("sources").then(function() { | |
366 test._waitUntilScriptsAreParsed( | |
367 ["debugger_test_page.html"], | |
368 function() { | |
369 checkNoDuplicates(); | |
370 setTimeout(switchToElementsTab, 0); | |
371 }); | |
372 }); | 344 }); |
373 | 345 |
374 // Wait until all scripts are added to the debugger. | 346 // Wait until all scripts are added to the debugger. |
375 this.takeControl(); | 347 this.takeControl(); |
376 }; | 348 }; |
377 | 349 |
378 | 350 // Tests that debugger works correctly if pause event occurs when DevTools |
379 // Tests that debugger works correctly if pause event occurs when DevTools | 351 // frontend is being loaded. |
380 // frontend is being loaded. | 352 TestSuite.prototype.testPauseWhenLoadingDevTools = function() { |
381 TestSuite.prototype.testPauseWhenLoadingDevTools = function() | |
382 { | |
383 var debuggerModel = WebInspector.DebuggerModel.fromTarget(WebInspector.targe
tManager.mainTarget()); | 353 var debuggerModel = WebInspector.DebuggerModel.fromTarget(WebInspector.targe
tManager.mainTarget()); |
384 if (debuggerModel.debuggerPausedDetails) | 354 if (debuggerModel.debuggerPausedDetails) |
| 355 return; |
| 356 |
| 357 this.showPanel('sources').then(function() { |
| 358 // Script execution can already be paused. |
| 359 |
| 360 this._waitForScriptPause(this.releaseControl.bind(this)); |
| 361 }.bind(this)); |
| 362 |
| 363 this.takeControl(); |
| 364 }; |
| 365 |
| 366 // Tests that pressing "Pause" will pause script execution if the script |
| 367 // is already running. |
| 368 TestSuite.prototype.testPauseWhenScriptIsRunning = function() { |
| 369 this.showPanel('sources').then(function() { |
| 370 this.evaluateInConsole_('setTimeout("handleClick()", 0)', didEvaluateInCon
sole.bind(this)); |
| 371 }.bind(this)); |
| 372 |
| 373 function didEvaluateInConsole(resultText) { |
| 374 this.assertTrue(!isNaN(resultText), 'Failed to get timer id: ' + resultTex
t); |
| 375 // Wait for some time to make sure that inspected page is running the |
| 376 // infinite loop. |
| 377 setTimeout(testScriptPause.bind(this), 300); |
| 378 } |
| 379 |
| 380 function testScriptPause() { |
| 381 // The script should be in infinite loop. Click "Pause" button to |
| 382 // pause it and wait for the result. |
| 383 WebInspector.panels.sources._togglePause(); |
| 384 |
| 385 this._waitForScriptPause(this.releaseControl.bind(this)); |
| 386 } |
| 387 |
| 388 this.takeControl(); |
| 389 }; |
| 390 |
| 391 /** |
| 392 * Tests network size. |
| 393 */ |
| 394 TestSuite.prototype.testNetworkSize = function() { |
| 395 var test = this; |
| 396 |
| 397 function finishResource(resource, finishTime) { |
| 398 test.assertEquals(25, resource.resourceSize, 'Incorrect total data length'
); |
| 399 test.releaseControl(); |
| 400 } |
| 401 |
| 402 this.addSniffer(WebInspector.NetworkDispatcher.prototype, '_finishNetworkReq
uest', finishResource); |
| 403 |
| 404 // Reload inspected page to sniff network events |
| 405 test.evaluateInConsole_('window.location.reload(true);', function(resultText
) {}); |
| 406 |
| 407 this.takeControl(); |
| 408 }; |
| 409 |
| 410 /** |
| 411 * Tests network sync size. |
| 412 */ |
| 413 TestSuite.prototype.testNetworkSyncSize = function() { |
| 414 var test = this; |
| 415 |
| 416 function finishResource(resource, finishTime) { |
| 417 test.assertEquals(25, resource.resourceSize, 'Incorrect total data length'
); |
| 418 test.releaseControl(); |
| 419 } |
| 420 |
| 421 this.addSniffer(WebInspector.NetworkDispatcher.prototype, '_finishNetworkReq
uest', finishResource); |
| 422 |
| 423 // Send synchronous XHR to sniff network events |
| 424 test.evaluateInConsole_( |
| 425 'var xhr = new XMLHttpRequest(); xhr.open("GET", "chunked", false); xhr.
send(null);', function() {}); |
| 426 |
| 427 this.takeControl(); |
| 428 }; |
| 429 |
| 430 /** |
| 431 * Tests network raw headers text. |
| 432 */ |
| 433 TestSuite.prototype.testNetworkRawHeadersText = function() { |
| 434 var test = this; |
| 435 |
| 436 function finishResource(resource, finishTime) { |
| 437 if (!resource.responseHeadersText) |
| 438 test.fail('Failure: resource does not have response headers text'); |
| 439 var index = resource.responseHeadersText.indexOf('Date:'); |
| 440 test.assertEquals( |
| 441 112, resource.responseHeadersText.substring(index).length, 'Incorrect
response headers text length'); |
| 442 test.releaseControl(); |
| 443 } |
| 444 |
| 445 this.addSniffer(WebInspector.NetworkDispatcher.prototype, '_finishNetworkReq
uest', finishResource); |
| 446 |
| 447 // Reload inspected page to sniff network events |
| 448 test.evaluateInConsole_('window.location.reload(true);', function(resultText
) {}); |
| 449 |
| 450 this.takeControl(); |
| 451 }; |
| 452 |
| 453 /** |
| 454 * Tests network timing. |
| 455 */ |
| 456 TestSuite.prototype.testNetworkTiming = function() { |
| 457 var test = this; |
| 458 |
| 459 function finishResource(resource, finishTime) { |
| 460 // Setting relaxed expectations to reduce flakiness. |
| 461 // Server sends headers after 100ms, then sends data during another 100ms. |
| 462 // We expect these times to be measured at least as 70ms. |
| 463 test.assertTrue( |
| 464 resource.timing.receiveHeadersEnd - resource.timing.connectStart >= 70
, |
| 465 'Time between receiveHeadersEnd and connectStart should be >=70ms, but
was ' + |
| 466 'receiveHeadersEnd=' + resource.timing.receiveHeadersEnd + ', conn
ectStart=' + |
| 467 resource.timing.connectStart + '.'); |
| 468 test.assertTrue( |
| 469 resource.responseReceivedTime - resource.startTime >= 0.07, |
| 470 'Time between responseReceivedTime and startTime should be >=0.07s, bu
t was ' + |
| 471 'responseReceivedTime=' + resource.responseReceivedTime + ', start
Time=' + resource.startTime + '.'); |
| 472 test.assertTrue( |
| 473 resource.endTime - resource.startTime >= 0.14, |
| 474 'Time between endTime and startTime should be >=0.14s, but was ' + |
| 475 'endtime=' + resource.endTime + ', startTime=' + resource.startTim
e + '.'); |
| 476 |
| 477 test.releaseControl(); |
| 478 } |
| 479 |
| 480 this.addSniffer(WebInspector.NetworkDispatcher.prototype, '_finishNetworkReq
uest', finishResource); |
| 481 |
| 482 // Reload inspected page to sniff network events |
| 483 test.evaluateInConsole_('window.location.reload(true);', function(resultText
) {}); |
| 484 |
| 485 this.takeControl(); |
| 486 }; |
| 487 |
| 488 TestSuite.prototype.testPushTimes = function(url) { |
| 489 var test = this; |
| 490 var pendingResourceCount = 2; |
| 491 |
| 492 function finishResource(resource, finishTime) { |
| 493 test.assertTrue( |
| 494 typeof resource.timing.pushStart === 'number' && resource.timing.pushS
tart > 0, |
| 495 `pushStart is invalid: ${resource.timing.pushStart}`); |
| 496 test.assertTrue(typeof resource.timing.pushEnd === 'number', `pushEnd is i
nvalid: ${resource.timing.pushEnd}`); |
| 497 test.assertTrue(resource.timing.pushStart < resource.startTime, 'pushStart
should be before startTime'); |
| 498 if (resource.url.endsWith('?pushUseNullEndTime')) { |
| 499 test.assertTrue(resource.timing.pushEnd === 0, `pushEnd should be 0 but
is ${resource.timing.pushEnd}`); |
| 500 } else { |
| 501 test.assertTrue( |
| 502 resource.timing.pushStart < resource.timing.pushEnd, |
| 503 `pushStart should be before pushEnd (${resource.timing.pushStart} >=
${resource.timing.pushEnd})`); |
| 504 // The below assertion is just due to the way we generate times in the m
och URLRequestJob and is not generally an invariant. |
| 505 test.assertTrue(resource.timing.pushEnd < resource.endTime, 'pushEnd sho
uld be before endTime'); |
| 506 test.assertTrue(resource.startTime < resource.timing.pushEnd, 'pushEnd s
hould be after startTime'); |
| 507 } |
| 508 if (!--pendingResourceCount) |
| 509 test.releaseControl(); |
| 510 } |
| 511 |
| 512 this.addSniffer(WebInspector.NetworkDispatcher.prototype, '_finishNetworkReq
uest', finishResource, true); |
| 513 |
| 514 test.evaluateInConsole_('addImage(\'' + url + '\')', function(resultText) {}
); |
| 515 test.evaluateInConsole_('addImage(\'' + url + '?pushUseNullEndTime\')', func
tion(resultText) {}); |
| 516 this.takeControl(); |
| 517 }; |
| 518 |
| 519 TestSuite.prototype.testConsoleOnNavigateBack = function() { |
| 520 if (WebInspector.multitargetConsoleModel.messages().length === 1) |
| 521 firstConsoleMessageReceived.call(this); |
| 522 else |
| 523 WebInspector.multitargetConsoleModel.addEventListener( |
| 524 WebInspector.ConsoleModel.Events.MessageAdded, firstConsoleMessageRece
ived, this); |
| 525 |
| 526 function firstConsoleMessageReceived() { |
| 527 WebInspector.multitargetConsoleModel.removeEventListener( |
| 528 WebInspector.ConsoleModel.Events.MessageAdded, firstConsoleMessageRece
ived, this); |
| 529 this.evaluateInConsole_('clickLink();', didClickLink.bind(this)); |
| 530 } |
| 531 |
| 532 function didClickLink() { |
| 533 // Check that there are no new messages(command is not a message). |
| 534 this.assertEquals(3, WebInspector.multitargetConsoleModel.messages().lengt
h); |
| 535 this.evaluateInConsole_('history.back();', didNavigateBack.bind(this)); |
| 536 } |
| 537 |
| 538 function didNavigateBack() { |
| 539 // Make sure navigation completed and possible console messages were pushe
d. |
| 540 this.evaluateInConsole_('void 0;', didCompleteNavigation.bind(this)); |
| 541 } |
| 542 |
| 543 function didCompleteNavigation() { |
| 544 this.assertEquals(7, WebInspector.multitargetConsoleModel.messages().lengt
h); |
| 545 this.releaseControl(); |
| 546 } |
| 547 |
| 548 this.takeControl(); |
| 549 }; |
| 550 |
| 551 TestSuite.prototype.testSharedWorker = function() { |
| 552 function didEvaluateInConsole(resultText) { |
| 553 this.assertEquals('2011', resultText); |
| 554 this.releaseControl(); |
| 555 } |
| 556 this.evaluateInConsole_('globalVar', didEvaluateInConsole.bind(this)); |
| 557 this.takeControl(); |
| 558 }; |
| 559 |
| 560 TestSuite.prototype.testPauseInSharedWorkerInitialization1 = function() { |
| 561 // Make sure the worker is loaded. |
| 562 this.takeControl(); |
| 563 this._waitForTargets(2, callback.bind(this)); |
| 564 |
| 565 function callback() { |
| 566 var target = WebInspector.targetManager.targets(WebInspector.Target.Capabi
lity.JS)[0]; |
| 567 InspectorBackendClass.deprecatedRunAfterPendingDispatches(this.releaseCont
rol.bind(this)); |
| 568 } |
| 569 }; |
| 570 |
| 571 TestSuite.prototype.testPauseInSharedWorkerInitialization2 = function() { |
| 572 this.takeControl(); |
| 573 this._waitForTargets(2, callback.bind(this)); |
| 574 |
| 575 function callback() { |
| 576 var target = WebInspector.targetManager.targets(WebInspector.Target.Capabi
lity.JS)[0]; |
| 577 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); |
| 578 if (debuggerModel.isPaused()) { |
| 579 this.releaseControl(); |
385 return; | 580 return; |
386 | 581 } |
387 this.showPanel("sources").then(function() { | 582 this._waitForScriptPause(this.releaseControl.bind(this)); |
388 // Script execution can already be paused. | 583 } |
389 | 584 }; |
390 this._waitForScriptPause(this.releaseControl.bind(this)); | 585 |
391 }.bind(this)); | 586 TestSuite.prototype.enableTouchEmulation = function() { |
392 | |
393 this.takeControl(); | |
394 }; | |
395 | |
396 | |
397 // Tests that pressing "Pause" will pause script execution if the script | |
398 // is already running. | |
399 TestSuite.prototype.testPauseWhenScriptIsRunning = function() | |
400 { | |
401 this.showPanel("sources").then(function() { | |
402 this.evaluateInConsole_( | |
403 'setTimeout("handleClick()", 0)', | |
404 didEvaluateInConsole.bind(this)); | |
405 }.bind(this)); | |
406 | |
407 function didEvaluateInConsole(resultText) { | |
408 this.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultT
ext); | |
409 // Wait for some time to make sure that inspected page is running the | |
410 // infinite loop. | |
411 setTimeout(testScriptPause.bind(this), 300); | |
412 } | |
413 | |
414 function testScriptPause() { | |
415 // The script should be in infinite loop. Click "Pause" button to | |
416 // pause it and wait for the result. | |
417 WebInspector.panels.sources._togglePause(); | |
418 | |
419 this._waitForScriptPause(this.releaseControl.bind(this)); | |
420 } | |
421 | |
422 this.takeControl(); | |
423 }; | |
424 | |
425 | |
426 /** | |
427 * Tests network size. | |
428 */ | |
429 TestSuite.prototype.testNetworkSize = function() | |
430 { | |
431 var test = this; | |
432 | |
433 function finishResource(resource, finishTime) | |
434 { | |
435 test.assertEquals(25, resource.resourceSize, "Incorrect total data lengt
h"); | |
436 test.releaseControl(); | |
437 } | |
438 | |
439 this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkReq
uest", finishResource); | |
440 | |
441 // Reload inspected page to sniff network events | |
442 test.evaluateInConsole_("window.location.reload(true);", function(resultText
) {}); | |
443 | |
444 this.takeControl(); | |
445 }; | |
446 | |
447 | |
448 /** | |
449 * Tests network sync size. | |
450 */ | |
451 TestSuite.prototype.testNetworkSyncSize = function() | |
452 { | |
453 var test = this; | |
454 | |
455 function finishResource(resource, finishTime) | |
456 { | |
457 test.assertEquals(25, resource.resourceSize, "Incorrect total data lengt
h"); | |
458 test.releaseControl(); | |
459 } | |
460 | |
461 this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkReq
uest", finishResource); | |
462 | |
463 // Send synchronous XHR to sniff network events | |
464 test.evaluateInConsole_("var xhr = new XMLHttpRequest(); xhr.open(\"GET\", \
"chunked\", false); xhr.send(null);", function() {}); | |
465 | |
466 this.takeControl(); | |
467 }; | |
468 | |
469 | |
470 /** | |
471 * Tests network raw headers text. | |
472 */ | |
473 TestSuite.prototype.testNetworkRawHeadersText = function() | |
474 { | |
475 var test = this; | |
476 | |
477 function finishResource(resource, finishTime) | |
478 { | |
479 if (!resource.responseHeadersText) | |
480 test.fail("Failure: resource does not have response headers text"); | |
481 var index = resource.responseHeadersText.indexOf("Date:"); | |
482 test.assertEquals(112, resource.responseHeadersText.substring(index).len
gth, "Incorrect response headers text length"); | |
483 test.releaseControl(); | |
484 } | |
485 | |
486 this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkReq
uest", finishResource); | |
487 | |
488 // Reload inspected page to sniff network events | |
489 test.evaluateInConsole_("window.location.reload(true);", function(resultText
) {}); | |
490 | |
491 this.takeControl(); | |
492 }; | |
493 | |
494 | |
495 /** | |
496 * Tests network timing. | |
497 */ | |
498 TestSuite.prototype.testNetworkTiming = function() | |
499 { | |
500 var test = this; | |
501 | |
502 function finishResource(resource, finishTime) | |
503 { | |
504 // Setting relaxed expectations to reduce flakiness. | |
505 // Server sends headers after 100ms, then sends data during another 100m
s. | |
506 // We expect these times to be measured at least as 70ms. | |
507 test.assertTrue(resource.timing.receiveHeadersEnd - resource.timing.conn
ectStart >= 70, | |
508 "Time between receiveHeadersEnd and connectStart should
be >=70ms, but was " + | |
509 "receiveHeadersEnd=" + resource.timing.receiveHeadersEnd
+ ", connectStart=" + resource.timing.connectStart + "."); | |
510 test.assertTrue(resource.responseReceivedTime - resource.startTime >= 0.
07, | |
511 "Time between responseReceivedTime and startTime should be >=0.0
7s, but was " + | |
512 "responseReceivedTime=" + resource.responseReceivedTime + ", sta
rtTime=" + resource.startTime + "."); | |
513 test.assertTrue(resource.endTime - resource.startTime >= 0.14, | |
514 "Time between endTime and startTime should be >=0.14s, but was "
+ | |
515 "endtime=" + resource.endTime + ", startTime=" + resource.startT
ime + "."); | |
516 | |
517 test.releaseControl(); | |
518 } | |
519 | |
520 this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkReq
uest", finishResource); | |
521 | |
522 // Reload inspected page to sniff network events | |
523 test.evaluateInConsole_("window.location.reload(true);", function(resultText
) {}); | |
524 | |
525 this.takeControl(); | |
526 }; | |
527 | |
528 | |
529 TestSuite.prototype.testPushTimes = function(url) | |
530 { | |
531 var test = this; | |
532 var pendingResourceCount = 2; | |
533 | |
534 function finishResource(resource, finishTime) | |
535 { | |
536 test.assertTrue(typeof resource.timing.pushStart === "number" && resourc
e.timing.pushStart > 0, `pushStart is invalid: ${resource.timing.pushStart}`); | |
537 test.assertTrue(typeof resource.timing.pushEnd === "number", `pushEnd is
invalid: ${resource.timing.pushEnd}`); | |
538 test.assertTrue(resource.timing.pushStart < resource.startTime, "pushSta
rt should be before startTime"); | |
539 if (resource.url.endsWith("?pushUseNullEndTime")) { | |
540 test.assertTrue(resource.timing.pushEnd === 0, `pushEnd should be 0
but is ${resource.timing.pushEnd}`); | |
541 } else { | |
542 test.assertTrue(resource.timing.pushStart < resource.timing.pushEnd,
`pushStart should be before pushEnd (${resource.timing.pushStart} >= ${resource
.timing.pushEnd})`); | |
543 // The below assertion is just due to the way we generate times in t
he moch URLRequestJob and is not generally an invariant. | |
544 test.assertTrue(resource.timing.pushEnd < resource.endTime, "pushEnd
should be before endTime"); | |
545 test.assertTrue(resource.startTime < resource.timing.pushEnd, "pushE
nd should be after startTime"); | |
546 } | |
547 if (!--pendingResourceCount) | |
548 test.releaseControl(); | |
549 } | |
550 | |
551 this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkReq
uest", finishResource, true); | |
552 | |
553 test.evaluateInConsole_("addImage('" + url + "')", function(resultText) {}); | |
554 test.evaluateInConsole_("addImage('" + url + "?pushUseNullEndTime')", functi
on(resultText) {}); | |
555 this.takeControl(); | |
556 }; | |
557 | |
558 | |
559 TestSuite.prototype.testConsoleOnNavigateBack = function() | |
560 { | |
561 if (WebInspector.multitargetConsoleModel.messages().length === 1) | |
562 firstConsoleMessageReceived.call(this); | |
563 else | |
564 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.Conso
leModel.Events.MessageAdded, firstConsoleMessageReceived, this); | |
565 | |
566 function firstConsoleMessageReceived() { | |
567 WebInspector.multitargetConsoleModel.removeEventListener(WebInspector.Co
nsoleModel.Events.MessageAdded, firstConsoleMessageReceived, this); | |
568 this.evaluateInConsole_("clickLink();", didClickLink.bind(this)); | |
569 } | |
570 | |
571 function didClickLink() { | |
572 // Check that there are no new messages(command is not a message). | |
573 this.assertEquals(3, WebInspector.multitargetConsoleModel.messages().len
gth); | |
574 this.evaluateInConsole_("history.back();", didNavigateBack.bind(this)); | |
575 } | |
576 | |
577 function didNavigateBack() | |
578 { | |
579 // Make sure navigation completed and possible console messages were pus
hed. | |
580 this.evaluateInConsole_("void 0;", didCompleteNavigation.bind(this)); | |
581 } | |
582 | |
583 function didCompleteNavigation() { | |
584 this.assertEquals(7, WebInspector.multitargetConsoleModel.messages().len
gth); | |
585 this.releaseControl(); | |
586 } | |
587 | |
588 this.takeControl(); | |
589 }; | |
590 | |
591 TestSuite.prototype.testSharedWorker = function() | |
592 { | |
593 function didEvaluateInConsole(resultText) { | |
594 this.assertEquals("2011", resultText); | |
595 this.releaseControl(); | |
596 } | |
597 this.evaluateInConsole_("globalVar", didEvaluateInConsole.bind(this)); | |
598 this.takeControl(); | |
599 }; | |
600 | |
601 | |
602 TestSuite.prototype.testPauseInSharedWorkerInitialization1 = function() | |
603 { | |
604 // Make sure the worker is loaded. | |
605 this.takeControl(); | |
606 this._waitForTargets(2, callback.bind(this)); | |
607 | |
608 function callback() | |
609 { | |
610 var target = WebInspector.targetManager.targets(WebInspector.Target.Capa
bility.JS)[0]; | |
611 InspectorBackendClass.deprecatedRunAfterPendingDispatches(this.releaseCo
ntrol.bind(this)); | |
612 } | |
613 }; | |
614 | |
615 TestSuite.prototype.testPauseInSharedWorkerInitialization2 = function() | |
616 { | |
617 this.takeControl(); | |
618 this._waitForTargets(2, callback.bind(this)); | |
619 | |
620 function callback() | |
621 { | |
622 var target = WebInspector.targetManager.targets(WebInspector.Target.Capa
bility.JS)[0]; | |
623 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); | |
624 if (debuggerModel.isPaused()) { | |
625 this.releaseControl(); | |
626 return; | |
627 } | |
628 this._waitForScriptPause(this.releaseControl.bind(this)); | |
629 } | |
630 }; | |
631 | |
632 TestSuite.prototype.enableTouchEmulation = function() | |
633 { | |
634 var deviceModeModel = new WebInspector.DeviceModeModel(function() {}); | 587 var deviceModeModel = new WebInspector.DeviceModeModel(function() {}); |
635 deviceModeModel._target = WebInspector.targetManager.mainTarget(); | 588 deviceModeModel._target = WebInspector.targetManager.mainTarget(); |
636 deviceModeModel._applyTouch(true, true); | 589 deviceModeModel._applyTouch(true, true); |
637 }; | 590 }; |
638 | 591 |
639 TestSuite.prototype.enableAutoAttachToCreatedPages = function() | 592 TestSuite.prototype.enableAutoAttachToCreatedPages = function() { |
640 { | 593 WebInspector.settingForTest('autoAttachToCreatedPages').set(true); |
641 WebInspector.settingForTest("autoAttachToCreatedPages").set(true); | 594 }; |
642 }; | 595 |
643 | 596 TestSuite.prototype.waitForDebuggerPaused = function() { |
644 TestSuite.prototype.waitForDebuggerPaused = function() | |
645 { | |
646 var debuggerModel = WebInspector.DebuggerModel.fromTarget(WebInspector.targe
tManager.mainTarget()); | 597 var debuggerModel = WebInspector.DebuggerModel.fromTarget(WebInspector.targe
tManager.mainTarget()); |
647 if (debuggerModel.debuggerPausedDetails) | 598 if (debuggerModel.debuggerPausedDetails) |
648 return; | 599 return; |
649 | 600 |
650 this.takeControl(); | 601 this.takeControl(); |
651 this._waitForScriptPause(this.releaseControl.bind(this)); | 602 this._waitForScriptPause(this.releaseControl.bind(this)); |
652 }; | 603 }; |
653 | 604 |
654 TestSuite.prototype.switchToPanel = function(panelName) | 605 TestSuite.prototype.switchToPanel = function(panelName) { |
655 { | |
656 this.showPanel(panelName).then(this.releaseControl.bind(this)); | 606 this.showPanel(panelName).then(this.releaseControl.bind(this)); |
657 this.takeControl(); | 607 this.takeControl(); |
658 }; | 608 }; |
659 | 609 |
660 // Regression test for crbug.com/370035. | 610 // Regression test for crbug.com/370035. |
661 TestSuite.prototype.testDeviceMetricsOverrides = function() | 611 TestSuite.prototype.testDeviceMetricsOverrides = function() { |
662 { | 612 const dumpPageMetrics = function() { |
663 const dumpPageMetrics = function() | 613 return JSON.stringify( |
664 { | 614 {width: window.innerWidth, height: window.innerHeight, deviceScaleFact
or: window.devicePixelRatio}); |
665 return JSON.stringify({ | |
666 width: window.innerWidth, | |
667 height: window.innerHeight, | |
668 deviceScaleFactor: window.devicePixelRatio | |
669 }); | |
670 }; | 615 }; |
671 | 616 |
672 var test = this; | 617 var test = this; |
673 | 618 |
674 function testOverrides(params, metrics, callback) | 619 function testOverrides(params, metrics, callback) { |
675 { | 620 WebInspector.targetManager.mainTarget().emulationAgent().invoke_setDeviceM
etricsOverride(params, getMetrics); |
676 WebInspector.targetManager.mainTarget().emulationAgent().invoke_setDevic
eMetricsOverride(params, getMetrics); | 621 |
677 | 622 function getMetrics() { |
678 function getMetrics() | 623 test.evaluateInConsole_('(' + dumpPageMetrics.toString() + ')()', checkM
etrics); |
679 { | 624 } |
680 test.evaluateInConsole_("(" + dumpPageMetrics.toString() + ")()", ch
eckMetrics); | 625 |
681 } | 626 function checkMetrics(consoleResult) { |
682 | 627 test.assertEquals( |
683 function checkMetrics(consoleResult) | 628 '"' + JSON.stringify(metrics) + '"', consoleResult, 'Wrong metrics f
or params: ' + JSON.stringify(params)); |
684 { | 629 callback(); |
685 test.assertEquals('"' + JSON.stringify(metrics) + '"', consoleResult
, "Wrong metrics for params: " + JSON.stringify(params)); | 630 } |
686 callback(); | 631 } |
687 } | 632 |
688 } | 633 function step1() { |
689 | 634 testOverrides( |
690 function step1() | 635 {width: 1200, height: 1000, deviceScaleFactor: 1, mobile: false, fitWi
ndow: true}, |
691 { | 636 {width: 1200, height: 1000, deviceScaleFactor: 1}, step2); |
692 testOverrides({width: 1200, height: 1000, deviceScaleFactor: 1, mobile:
false, fitWindow: true}, {width: 1200, height: 1000, deviceScaleFactor: 1}, step
2); | 637 } |
693 } | 638 |
694 | 639 function step2() { |
695 function step2() | 640 testOverrides( |
696 { | 641 {width: 1200, height: 1000, deviceScaleFactor: 1, mobile: false, fitWi
ndow: false}, |
697 testOverrides({width: 1200, height: 1000, deviceScaleFactor: 1, mobile:
false, fitWindow: false}, {width: 1200, height: 1000, deviceScaleFactor: 1}, ste
p3); | 642 {width: 1200, height: 1000, deviceScaleFactor: 1}, step3); |
698 } | 643 } |
699 | 644 |
700 function step3() | 645 function step3() { |
701 { | 646 testOverrides( |
702 testOverrides({width: 1200, height: 1000, deviceScaleFactor: 3, mobile:
false, fitWindow: true}, {width: 1200, height: 1000, deviceScaleFactor: 3}, step
4); | 647 {width: 1200, height: 1000, deviceScaleFactor: 3, mobile: false, fitWi
ndow: true}, |
703 } | 648 {width: 1200, height: 1000, deviceScaleFactor: 3}, step4); |
704 | 649 } |
705 function step4() | 650 |
706 { | 651 function step4() { |
707 testOverrides({width: 1200, height: 1000, deviceScaleFactor: 3, mobile:
false, fitWindow: false}, {width: 1200, height: 1000, deviceScaleFactor: 3}, fin
ish); | 652 testOverrides( |
708 } | 653 {width: 1200, height: 1000, deviceScaleFactor: 3, mobile: false, fitWi
ndow: false}, |
709 | 654 {width: 1200, height: 1000, deviceScaleFactor: 3}, finish); |
710 function finish() | 655 } |
711 { | 656 |
712 test.releaseControl(); | 657 function finish() { |
| 658 test.releaseControl(); |
713 } | 659 } |
714 | 660 |
715 test.takeControl(); | 661 test.takeControl(); |
716 step1(); | 662 step1(); |
717 }; | 663 }; |
718 | 664 |
719 TestSuite.prototype.testDispatchKeyEventDoesNotCrash = function() | 665 TestSuite.prototype.testDispatchKeyEventDoesNotCrash = function() { |
720 { | 666 WebInspector.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent
( |
721 WebInspector.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent
({ | 667 {type: 'rawKeyDown', windowsVirtualKeyCode: 0x23, key: 'End'}); |
722 type: "rawKeyDown", | 668 WebInspector.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent
( |
723 windowsVirtualKeyCode: 0x23, | 669 {type: 'keyUp', windowsVirtualKeyCode: 0x23, key: 'End'}); |
724 key: "End" | 670 }; |
725 }); | 671 |
726 WebInspector.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent
({ | 672 TestSuite.prototype.testEmulateNetworkConditions = function() { |
727 type: "keyUp", | 673 var test = this; |
728 windowsVirtualKeyCode: 0x23, | 674 |
729 key: "End" | 675 function testPreset(preset, messages, next) { |
730 }); | 676 function onConsoleMessage(event) { |
731 }; | 677 var index = messages.indexOf(event.data.messageText); |
732 | 678 if (index === -1) { |
733 TestSuite.prototype.testEmulateNetworkConditions = function() | 679 test.fail('Unexpected message: ' + event.data.messageText); |
734 { | 680 return; |
735 var test = this; | |
736 | |
737 function testPreset(preset, messages, next) | |
738 { | |
739 function onConsoleMessage(event) | |
740 { | |
741 var index = messages.indexOf(event.data.messageText); | |
742 if (index === -1) { | |
743 test.fail("Unexpected message: " + event.data.messageText); | |
744 return; | |
745 } | |
746 | |
747 messages.splice(index, 1); | |
748 if (!messages.length) { | |
749 WebInspector.multitargetConsoleModel.removeEventListener(WebInsp
ector.ConsoleModel.Events.MessageAdded, onConsoleMessage, this); | |
750 next(); | |
751 } | |
752 } | 681 } |
753 | 682 |
754 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.Conso
leModel.Events.MessageAdded, onConsoleMessage, this); | 683 messages.splice(index, 1); |
755 WebInspector.multitargetNetworkManager.setNetworkConditions(preset); | 684 if (!messages.length) { |
| 685 WebInspector.multitargetConsoleModel.removeEventListener( |
| 686 WebInspector.ConsoleModel.Events.MessageAdded, onConsoleMessage, t
his); |
| 687 next(); |
| 688 } |
| 689 } |
| 690 |
| 691 WebInspector.multitargetConsoleModel.addEventListener( |
| 692 WebInspector.ConsoleModel.Events.MessageAdded, onConsoleMessage, this)
; |
| 693 WebInspector.multitargetNetworkManager.setNetworkConditions(preset); |
756 } | 694 } |
757 | 695 |
758 test.takeControl(); | 696 test.takeControl(); |
759 step1(); | 697 step1(); |
760 | 698 |
761 function step1() | 699 function step1() { |
762 { | 700 testPreset( |
763 testPreset( | 701 WebInspector.NetworkConditionsSelector._presets[0], |
764 WebInspector.NetworkConditionsSelector._presets[0], | 702 ['offline event: online = false', 'connection change event: type = non
e; downlinkMax = 0'], step2); |
765 ["offline event: online = false", "connection change event: type = n
one; downlinkMax = 0"], | 703 } |
766 step2); | 704 |
767 } | 705 function step2() { |
768 | 706 testPreset( |
769 function step2() | 707 WebInspector.NetworkConditionsSelector._presets[2], |
770 { | 708 ['online event: online = true', 'connection change event: type = cellu
lar; downlinkMax = 0.244140625'], |
771 testPreset( | 709 step3); |
772 WebInspector.NetworkConditionsSelector._presets[2], | 710 } |
773 ["online event: online = true", "connection change event: type = cel
lular; downlinkMax = 0.244140625"], | 711 |
774 step3); | 712 function step3() { |
775 } | 713 testPreset( |
776 | 714 WebInspector.NetworkConditionsSelector._presets[8], |
777 function step3() | 715 ['connection change event: type = wifi; downlinkMax = 30'], test.relea
seControl.bind(test)); |
778 { | 716 } |
779 testPreset( | 717 }; |
780 WebInspector.NetworkConditionsSelector._presets[8], | 718 |
781 ["connection change event: type = wifi; downlinkMax = 30"], | 719 TestSuite.prototype.testScreenshotRecording = function() { |
782 test.releaseControl.bind(test)); | 720 var test = this; |
783 } | 721 |
784 }; | 722 function performActionsInPage(callback) { |
785 | 723 var count = 0; |
786 TestSuite.prototype.testScreenshotRecording = function() | 724 var div = document.createElement('div'); |
787 { | 725 div.setAttribute('style', 'left: 0px; top: 0px; width: 100px; height: 100p
x; position: absolute;'); |
788 var test = this; | 726 document.body.appendChild(div); |
789 | 727 requestAnimationFrame(frame); |
790 function performActionsInPage(callback) | 728 function frame() { |
791 { | 729 var color = [0, 0, 0]; |
792 var count = 0; | 730 color[count % 3] = 255; |
793 var div = document.createElement("div"); | 731 div.style.backgroundColor = 'rgb(' + color.join(',') + ')'; |
794 div.setAttribute("style", "left: 0px; top: 0px; width: 100px; height: 10
0px; position: absolute;"); | 732 if (++count > 10) |
795 document.body.appendChild(div); | 733 requestAnimationFrame(callback); |
796 requestAnimationFrame(frame); | 734 else |
797 function frame() | 735 requestAnimationFrame(frame); |
798 { | 736 } |
799 var color = [0, 0, 0]; | 737 } |
800 color[count % 3] = 255; | 738 |
801 div.style.backgroundColor = "rgb(" + color.join(",") + ")"; | 739 var captureFilmStripSetting = WebInspector.settings.createSetting('timelineC
aptureFilmStrip', false); |
802 if (++count > 10) | |
803 requestAnimationFrame(callback); | |
804 else | |
805 requestAnimationFrame(frame); | |
806 } | |
807 } | |
808 | |
809 var captureFilmStripSetting = WebInspector.settings.createSetting("timelineC
aptureFilmStrip", false); | |
810 captureFilmStripSetting.set(true); | 740 captureFilmStripSetting.set(true); |
811 test.evaluateInConsole_(performActionsInPage.toString(), function() {}); | 741 test.evaluateInConsole_(performActionsInPage.toString(), function() {}); |
812 test.invokeAsyncWithTimeline_("performActionsInPage", onTimelineDone); | 742 test.invokeAsyncWithTimeline_('performActionsInPage', onTimelineDone); |
813 | 743 |
814 function onTimelineDone() | 744 function onTimelineDone() { |
815 { | 745 captureFilmStripSetting.set(false); |
816 captureFilmStripSetting.set(false); | 746 var filmStripModel = new WebInspector.FilmStripModel(WebInspector.panels.t
imeline._tracingModel); |
817 var filmStripModel = new WebInspector.FilmStripModel(WebInspector.panels
.timeline._tracingModel); | 747 var frames = filmStripModel.frames(); |
818 var frames = filmStripModel.frames(); | 748 test.assertTrue(frames.length > 4 && typeof frames.length === 'number'); |
819 test.assertTrue(frames.length > 4 && typeof frames.length === "number"); | 749 loadFrameImages(frames); |
820 loadFrameImages(frames); | 750 } |
821 } | 751 |
822 | 752 function loadFrameImages(frames) { |
823 function loadFrameImages(frames) | 753 var readyImages = []; |
824 { | 754 for (var frame of frames) |
825 var readyImages = []; | 755 frame.imageDataPromise().then(onGotImageData); |
826 for (var frame of frames) | 756 |
827 frame.imageDataPromise().then(onGotImageData); | 757 function onGotImageData(data) { |
828 | 758 var image = new Image(); |
829 function onGotImageData(data) | 759 test.assertTrue(!!data, 'No image data for frame'); |
830 { | 760 image.addEventListener('load', onLoad); |
831 var image = new Image(); | 761 image.src = 'data:image/jpg;base64,' + data; |
832 test.assertTrue(!!data, "No image data for frame"); | 762 } |
833 image.addEventListener("load", onLoad); | 763 |
834 image.src = "data:image/jpg;base64," + data; | 764 function onLoad(event) { |
835 } | 765 readyImages.push(event.target); |
836 | 766 if (readyImages.length === frames.length) |
837 function onLoad(event) | 767 validateImagesAndCompleteTest(readyImages); |
838 { | 768 } |
839 readyImages.push(event.target); | 769 } |
840 if (readyImages.length === frames.length) | 770 |
841 validateImagesAndCompleteTest(readyImages); | 771 function validateImagesAndCompleteTest(images) { |
842 } | 772 var redCount = 0; |
843 } | 773 var greenCount = 0; |
844 | 774 var blueCount = 0; |
845 function validateImagesAndCompleteTest(images) | 775 |
846 { | 776 var canvas = document.createElement('canvas'); |
847 var redCount = 0; | 777 var ctx = canvas.getContext('2d'); |
848 var greenCount = 0; | 778 for (var image of images) { |
849 var blueCount = 0; | 779 test.assertTrue(image.naturalWidth > 10); |
850 | 780 test.assertTrue(image.naturalHeight > 10); |
851 var canvas = document.createElement("canvas"); | 781 canvas.width = image.naturalWidth; |
852 var ctx = canvas.getContext("2d"); | 782 canvas.height = image.naturalHeight; |
853 for (var image of images) { | 783 ctx.drawImage(image, 0, 0); |
854 test.assertTrue(image.naturalWidth > 10); | 784 var data = ctx.getImageData(0, 0, 1, 1); |
855 test.assertTrue(image.naturalHeight > 10); | 785 var color = Array.prototype.join.call(data.data, ','); |
856 canvas.width = image.naturalWidth; | 786 if (data.data[0] > 200) |
857 canvas.height = image.naturalHeight; | 787 redCount++; |
858 ctx.drawImage(image, 0, 0); | 788 else if (data.data[1] > 200) |
859 var data = ctx.getImageData(0, 0, 1, 1); | 789 greenCount++; |
860 var color = Array.prototype.join.call(data.data, ","); | 790 else if (data.data[2] > 200) |
861 if (data.data[0] > 200) | 791 blueCount++; |
862 redCount++; | 792 else |
863 else if (data.data[1] > 200) | 793 test.fail('Unexpected color: ' + color); |
864 greenCount++; | 794 } |
865 else if (data.data[2] > 200) | 795 test.assertTrue(redCount && greenCount && blueCount, 'Color sanity check f
ailed'); |
866 blueCount++; | 796 test.releaseControl(); |
867 else | |
868 test.fail("Unexpected color: " + color); | |
869 } | |
870 test.assertTrue(redCount && greenCount && blueCount, "Color sanity check
failed"); | |
871 test.releaseControl(); | |
872 } | 797 } |
873 | 798 |
874 test.takeControl(); | 799 test.takeControl(); |
875 }; | 800 }; |
876 | 801 |
877 TestSuite.prototype.testSettings = function() | 802 TestSuite.prototype.testSettings = function() { |
878 { | |
879 var test = this; | 803 var test = this; |
880 | 804 |
881 createSettings(); | 805 createSettings(); |
882 test.takeControl(); | 806 test.takeControl(); |
883 setTimeout(reset, 0); | 807 setTimeout(reset, 0); |
884 | 808 |
885 function createSettings() | 809 function createSettings() { |
886 { | 810 var localSetting = WebInspector.settings.createSetting('local', undefined,
true); |
887 var localSetting = WebInspector.settings.createSetting("local", undefine
d, true); | 811 localSetting.set({s: 'local', n: 1}); |
888 localSetting.set({s: "local", n: 1 }); | 812 var globalSetting = WebInspector.settings.createSetting('global', undefine
d, false); |
889 var globalSetting = WebInspector.settings.createSetting("global", undefi
ned, false); | 813 globalSetting.set({s: 'global', n: 2}); |
890 globalSetting.set({s: "global", n: 2 }); | 814 } |
891 } | 815 |
892 | 816 function reset() { |
893 function reset() | 817 Runtime.experiments.clearForTest(); |
894 { | 818 InspectorFrontendHost.getPreferences(gotPreferences); |
895 Runtime.experiments.clearForTest(); | 819 } |
896 InspectorFrontendHost.getPreferences(gotPreferences); | 820 |
897 } | 821 function gotPreferences(prefs) { |
898 | 822 WebInspector.Main._instanceForTest._createSettings(prefs); |
899 function gotPreferences(prefs) | 823 |
900 { | 824 var localSetting = WebInspector.settings.createSetting('local', undefined,
true); |
901 WebInspector.Main._instanceForTest._createSettings(prefs); | 825 test.assertEquals('object', typeof localSetting.get()); |
902 | 826 test.assertEquals('local', localSetting.get().s); |
903 var localSetting = WebInspector.settings.createSetting("local", undefine
d, true); | 827 test.assertEquals(1, localSetting.get().n); |
904 test.assertEquals("object", typeof localSetting.get()); | 828 var globalSetting = WebInspector.settings.createSetting('global', undefine
d, false); |
905 test.assertEquals("local", localSetting.get().s); | 829 test.assertEquals('object', typeof globalSetting.get()); |
906 test.assertEquals(1, localSetting.get().n); | 830 test.assertEquals('global', globalSetting.get().s); |
907 var globalSetting = WebInspector.settings.createSetting("global", undefi
ned, false); | 831 test.assertEquals(2, globalSetting.get().n); |
908 test.assertEquals("object", typeof globalSetting.get()); | 832 test.releaseControl(); |
909 test.assertEquals("global", globalSetting.get().s); | 833 } |
910 test.assertEquals(2, globalSetting.get().n); | 834 }; |
911 test.releaseControl(); | 835 |
912 } | 836 TestSuite.prototype.testWindowInitializedOnNavigateBack = function() { |
913 }; | |
914 | |
915 TestSuite.prototype.testWindowInitializedOnNavigateBack = function() | |
916 { | |
917 var messages = WebInspector.multitargetConsoleModel.messages(); | 837 var messages = WebInspector.multitargetConsoleModel.messages(); |
918 this.assertEquals(1, messages.length); | 838 this.assertEquals(1, messages.length); |
919 var text = messages[0].messageText; | 839 var text = messages[0].messageText; |
920 if (text.indexOf("Uncaught") !== -1) | 840 if (text.indexOf('Uncaught') !== -1) |
921 this.fail(text); | 841 this.fail(text); |
922 }; | 842 }; |
923 | 843 |
924 TestSuite.prototype.testConsoleContextNames = function() | 844 TestSuite.prototype.testConsoleContextNames = function() { |
925 { | |
926 var test = this; | 845 var test = this; |
927 test.takeControl(); | 846 test.takeControl(); |
928 this.showPanel("console").then(() => this._waitForExecutionContexts(2, onExe
cutionContexts.bind(this))); | 847 this.showPanel('console').then(() => this._waitForExecutionContexts(2, onExe
cutionContexts.bind(this))); |
929 | 848 |
930 function onExecutionContexts() | 849 function onExecutionContexts() { |
931 { | 850 var consoleView = WebInspector.ConsoleView.instance(); |
932 var consoleView = WebInspector.ConsoleView.instance(); | 851 var options = consoleView._consoleContextSelector._selectElement.options; |
933 var options = consoleView._consoleContextSelector._selectElement.options
; | 852 var values = []; |
934 var values = []; | 853 for (var i = 0; i < options.length; ++i) |
935 for (var i = 0; i < options.length; ++i) | 854 values.push(options[i].value.trim()); |
936 values.push(options[i].value.trim()); | 855 test.assertEquals('top', values[0]); |
937 test.assertEquals("top", values[0]); | 856 test.assertEquals('Simple content script', values[1]); |
938 test.assertEquals("Simple content script", values[1]); | 857 test.releaseControl(); |
939 test.releaseControl(); | 858 } |
940 } | 859 }; |
941 }; | 860 |
942 | 861 TestSuite.prototype.testDevToolsSharedWorker = function() { |
943 TestSuite.prototype.testDevToolsSharedWorker = function() | |
944 { | |
945 this.takeControl(); | 862 this.takeControl(); |
946 WebInspector.TempFile.ensureTempStorageCleared().then(() => this.releaseCont
rol()); | 863 WebInspector.TempFile.ensureTempStorageCleared().then(() => this.releaseCont
rol()); |
947 }; | 864 }; |
948 | 865 |
949 TestSuite.prototype.waitForTestResultsInConsole = function() | 866 TestSuite.prototype.waitForTestResultsInConsole = function() { |
950 { | |
951 var messages = WebInspector.multitargetConsoleModel.messages(); | 867 var messages = WebInspector.multitargetConsoleModel.messages(); |
952 for (var i = 0; i < messages.length; ++i) { | 868 for (var i = 0; i < messages.length; ++i) { |
953 var text = messages[i].messageText; | 869 var text = messages[i].messageText; |
954 if (text === "PASS") | 870 if (text === 'PASS') |
955 return; | 871 return; |
956 else if (/^FAIL/.test(text)) | 872 else if (/^FAIL/.test(text)) |
957 this.fail(text); // This will throw. | 873 this.fail(text); // This will throw. |
958 } | 874 } |
959 // Neither PASS nor FAIL, so wait for more messages. | 875 // Neither PASS nor FAIL, so wait for more messages. |
960 function onConsoleMessage(event) | 876 function onConsoleMessage(event) { |
961 { | 877 var text = event.data.messageText; |
962 var text = event.data.messageText; | 878 if (text === 'PASS') |
963 if (text === "PASS") | 879 this.releaseControl(); |
964 this.releaseControl(); | 880 else if (/^FAIL/.test(text)) |
965 else if (/^FAIL/.test(text)) | 881 this.fail(text); |
966 this.fail(text); | 882 } |
967 } | 883 |
968 | 884 WebInspector.multitargetConsoleModel.addEventListener( |
969 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleMo
del.Events.MessageAdded, onConsoleMessage, this); | 885 WebInspector.ConsoleModel.Events.MessageAdded, onConsoleMessage, this); |
970 this.takeControl(); | 886 this.takeControl(); |
971 }; | 887 }; |
972 | 888 |
973 TestSuite.prototype._overrideMethod = function(receiver, methodName, override) | 889 TestSuite.prototype._overrideMethod = function(receiver, methodName, override)
{ |
974 { | |
975 var original = receiver[methodName]; | 890 var original = receiver[methodName]; |
976 if (typeof original !== "function") { | 891 if (typeof original !== 'function') { |
977 this.fail(`TestSuite._overrideMethod: $[methodName] is not a function`); | 892 this.fail(`TestSuite._overrideMethod: $[methodName] is not a function`); |
978 return; | 893 return; |
979 } | 894 } |
980 receiver[methodName] = function() | 895 receiver[methodName] = function() { |
981 { | 896 try { |
982 try { | 897 var value = original.apply(receiver, arguments); |
983 var value = original.apply(receiver, arguments); | 898 } finally { |
984 } finally { | 899 receiver[methodName] = original; |
985 receiver[methodName] = original; | 900 } |
986 } | 901 override.apply(original, arguments); |
987 override.apply(original, arguments); | 902 return value; |
988 return value; | |
989 }; | 903 }; |
990 }; | 904 }; |
991 | 905 |
992 TestSuite.prototype.startTimeline = function(callback) | 906 TestSuite.prototype.startTimeline = function(callback) { |
993 { | 907 var test = this; |
994 var test = this; | 908 this.showPanel('timeline').then(function() { |
995 this.showPanel("timeline").then(function() { | 909 var timeline = WebInspector.panels.timeline; |
996 var timeline = WebInspector.panels.timeline; | 910 test._overrideMethod(timeline, 'recordingStarted', callback); |
997 test._overrideMethod(timeline, "recordingStarted", callback); | 911 timeline._toggleRecording(); |
998 timeline._toggleRecording(); | |
999 }); | 912 }); |
1000 }; | 913 }; |
1001 | 914 |
1002 TestSuite.prototype.stopTimeline = function(callback) | 915 TestSuite.prototype.stopTimeline = function(callback) { |
1003 { | |
1004 var timeline = WebInspector.panels.timeline; | 916 var timeline = WebInspector.panels.timeline; |
1005 this._overrideMethod(timeline, "loadingComplete", callback); | 917 this._overrideMethod(timeline, 'loadingComplete', callback); |
1006 timeline._toggleRecording(); | 918 timeline._toggleRecording(); |
1007 }; | 919 }; |
1008 | 920 |
1009 TestSuite.prototype.invokePageFunctionAsync = function(functionName, opt_args, c
allback_is_always_last) | 921 TestSuite.prototype.invokePageFunctionAsync = function(functionName, opt_args,
callback_is_always_last) { |
1010 { | |
1011 var callback = arguments[arguments.length - 1]; | 922 var callback = arguments[arguments.length - 1]; |
1012 var doneMessage = `DONE: ${functionName}.${++this._asyncInvocationId}`; | 923 var doneMessage = `DONE: ${functionName}.${++this._asyncInvocationId}`; |
1013 var argsString = arguments.length < 3 ? "" : Array.prototype.slice.call(argu
ments, 1, -1).map(arg => JSON.stringify(arg)).join(",") + ","; | 924 var argsString = arguments.length < 3 ? |
1014 this.evaluateInConsole_(`${functionName}(${argsString} function() { console.
log('${doneMessage}'); });`, function() {}); | 925 '' : |
1015 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleMo
del.Events.MessageAdded, onConsoleMessage); | 926 Array.prototype.slice.call(arguments, 1, -1).map(arg => JSON.stringify(a
rg)).join(',') + ','; |
1016 | 927 this.evaluateInConsole_( |
1017 function onConsoleMessage(event) | 928 `${functionName}(${argsString} function() { console.log('${doneMessage}'
); });`, function() {}); |
1018 { | 929 WebInspector.multitargetConsoleModel.addEventListener( |
1019 var text = event.data.messageText; | 930 WebInspector.ConsoleModel.Events.MessageAdded, onConsoleMessage); |
1020 if (text === doneMessage) { | 931 |
1021 WebInspector.multitargetConsoleModel.removeEventListener(WebInspecto
r.ConsoleModel.Events.MessageAdded, onConsoleMessage); | 932 function onConsoleMessage(event) { |
1022 callback(); | 933 var text = event.data.messageText; |
1023 } | 934 if (text === doneMessage) { |
1024 } | 935 WebInspector.multitargetConsoleModel.removeEventListener( |
1025 }; | 936 WebInspector.ConsoleModel.Events.MessageAdded, onConsoleMessage); |
1026 | 937 callback(); |
1027 TestSuite.prototype.invokeAsyncWithTimeline_ = function(functionName, callback) | 938 } |
1028 { | 939 } |
| 940 }; |
| 941 |
| 942 TestSuite.prototype.invokeAsyncWithTimeline_ = function(functionName, callback
) { |
1029 var test = this; | 943 var test = this; |
1030 | 944 |
1031 this.startTimeline(onRecordingStarted); | 945 this.startTimeline(onRecordingStarted); |
1032 | 946 |
1033 function onRecordingStarted() | 947 function onRecordingStarted() { |
1034 { | 948 test.invokePageFunctionAsync(functionName, pageActionsDone); |
1035 test.invokePageFunctionAsync(functionName, pageActionsDone); | 949 } |
1036 } | 950 |
1037 | 951 function pageActionsDone() { |
1038 function pageActionsDone() | 952 test.stopTimeline(callback); |
1039 { | 953 } |
1040 test.stopTimeline(callback); | 954 }; |
1041 } | 955 |
1042 }; | 956 TestSuite.prototype.enableExperiment = function(name) { |
1043 | |
1044 TestSuite.prototype.enableExperiment = function(name) | |
1045 { | |
1046 Runtime.experiments.enableForTest(name); | 957 Runtime.experiments.enableForTest(name); |
1047 }; | 958 }; |
1048 | 959 |
1049 TestSuite.prototype.checkInputEventsPresent = function() | 960 TestSuite.prototype.checkInputEventsPresent = function() { |
1050 { | |
1051 var expectedEvents = new Set(arguments); | 961 var expectedEvents = new Set(arguments); |
1052 var model = WebInspector.panels.timeline._model; | 962 var model = WebInspector.panels.timeline._model; |
1053 var asyncEvents = model.mainThreadAsyncEvents(); | 963 var asyncEvents = model.mainThreadAsyncEvents(); |
1054 var input = asyncEvents.get(WebInspector.TimelineModel.AsyncEventGroup.input
) || []; | 964 var input = asyncEvents.get(WebInspector.TimelineModel.AsyncEventGroup.input
) || []; |
1055 var prefix = "InputLatency::"; | 965 var prefix = 'InputLatency::'; |
1056 for (var e of input) { | 966 for (var e of input) { |
1057 if (!e.name.startsWith(prefix)) | 967 if (!e.name.startsWith(prefix)) |
1058 continue; | 968 continue; |
1059 if (e.steps.length < 2) | 969 if (e.steps.length < 2) |
1060 continue; | 970 continue; |
1061 if (e.name.startsWith(prefix + "Mouse") && typeof e.steps[0].timeWaiting
ForMainThread !== "number") | 971 if (e.name.startsWith(prefix + 'Mouse') && typeof e.steps[0].timeWaitingFo
rMainThread !== 'number') |
1062 throw `Missing timeWaitingForMainThread on ${e.name}`; | 972 throw `Missing timeWaitingForMainThread on ${e.name}`; |
1063 expectedEvents.delete(e.name.substr(prefix.length)); | 973 expectedEvents.delete(e.name.substr(prefix.length)); |
1064 } | 974 } |
1065 if (expectedEvents.size) | 975 if (expectedEvents.size) |
1066 throw "Some expected events are not found: " + Array.from(expectedEvents
.keys()).join(","); | 976 throw 'Some expected events are not found: ' + Array.from(expectedEvents.k
eys()).join(','); |
1067 }; | 977 }; |
1068 | 978 |
1069 /** | 979 /** |
1070 * Serializes array of uiSourceCodes to string. | 980 * Serializes array of uiSourceCodes to string. |
1071 * @param {!Array.<!WebInspectorUISourceCode>} uiSourceCodes | 981 * @param {!Array.<!WebInspectorUISourceCode>} uiSourceCodes |
1072 * @return {string} | 982 * @return {string} |
1073 */ | 983 */ |
1074 TestSuite.prototype.uiSourceCodesToString_ = function(uiSourceCodes) | 984 TestSuite.prototype.uiSourceCodesToString_ = function(uiSourceCodes) { |
1075 { | |
1076 var names = []; | 985 var names = []; |
1077 for (var i = 0; i < uiSourceCodes.length; i++) | 986 for (var i = 0; i < uiSourceCodes.length; i++) |
1078 names.push('"' + uiSourceCodes[i].url() + '"'); | 987 names.push('"' + uiSourceCodes[i].url() + '"'); |
1079 return names.join(","); | 988 return names.join(','); |
1080 }; | 989 }; |
1081 | 990 |
1082 | 991 /** |
1083 /** | 992 * Returns all loaded non anonymous uiSourceCodes. |
1084 * Returns all loaded non anonymous uiSourceCodes. | 993 * @return {!Array.<!WebInspectorUISourceCode>} |
1085 * @return {!Array.<!WebInspectorUISourceCode>} | 994 */ |
1086 */ | 995 TestSuite.prototype.nonAnonymousUISourceCodes_ = function() { |
1087 TestSuite.prototype.nonAnonymousUISourceCodes_ = function() | |
1088 { | |
1089 /** | 996 /** |
1090 * @param {!WebInspector.UISourceCode} uiSourceCode | 997 * @param {!WebInspector.UISourceCode} uiSourceCode |
1091 */ | 998 */ |
1092 function filterOutService(uiSourceCode) | 999 function filterOutService(uiSourceCode) { |
1093 { | 1000 return !uiSourceCode.isFromServiceProject(); |
1094 return !uiSourceCode.isFromServiceProject(); | |
1095 } | 1001 } |
1096 | 1002 |
1097 var uiSourceCodes = WebInspector.workspace.uiSourceCodes(); | 1003 var uiSourceCodes = WebInspector.workspace.uiSourceCodes(); |
1098 return uiSourceCodes.filter(filterOutService); | 1004 return uiSourceCodes.filter(filterOutService); |
1099 }; | 1005 }; |
1100 | 1006 |
1101 | 1007 /* |
1102 /* | |
1103 * Evaluates the code in the console as if user typed it manually and invokes | 1008 * Evaluates the code in the console as if user typed it manually and invokes |
1104 * the callback when the result message is received and added to the console. | 1009 * the callback when the result message is received and added to the console. |
1105 * @param {string} code | 1010 * @param {string} code |
1106 * @param {function(string)} callback | 1011 * @param {function(string)} callback |
1107 */ | 1012 */ |
1108 TestSuite.prototype.evaluateInConsole_ = function(code, callback) | 1013 TestSuite.prototype.evaluateInConsole_ = function(code, callback) { |
1109 { | 1014 function innerEvaluate() { |
1110 function innerEvaluate() | 1015 WebInspector.context.removeFlavorChangeListener(WebInspector.ExecutionCont
ext, showConsoleAndEvaluate, this); |
1111 { | 1016 var consoleView = WebInspector.ConsoleView.instance(); |
1112 WebInspector.context.removeFlavorChangeListener(WebInspector.ExecutionCo
ntext, showConsoleAndEvaluate, this); | 1017 consoleView._prompt._appendCommand(code); |
1113 var consoleView = WebInspector.ConsoleView.instance(); | 1018 |
1114 consoleView._prompt._appendCommand(code); | 1019 this.addSniffer(WebInspector.ConsoleView.prototype, '_consoleMessageAddedF
orTest', function(viewMessage) { |
1115 | 1020 callback(viewMessage.toMessageElement().deepTextContent()); |
1116 this.addSniffer(WebInspector.ConsoleView.prototype, "_consoleMessageAdde
dForTest", | 1021 }.bind(this)); |
1117 function(viewMessage) { | 1022 } |
1118 callback(viewMessage.toMessageElement().deepTextContent()); | 1023 |
1119 }.bind(this)); | 1024 function showConsoleAndEvaluate() { |
1120 } | 1025 WebInspector.console.showPromise().then(innerEvaluate.bind(this)); |
1121 | |
1122 function showConsoleAndEvaluate() | |
1123 { | |
1124 WebInspector.console.showPromise().then(innerEvaluate.bind(this)); | |
1125 } | 1026 } |
1126 | 1027 |
1127 if (!WebInspector.context.flavor(WebInspector.ExecutionContext)) { | 1028 if (!WebInspector.context.flavor(WebInspector.ExecutionContext)) { |
1128 WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionConte
xt, showConsoleAndEvaluate, this); | 1029 WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext
, showConsoleAndEvaluate, this); |
1129 return; | 1030 return; |
1130 } | 1031 } |
1131 showConsoleAndEvaluate.call(this); | 1032 showConsoleAndEvaluate.call(this); |
1132 }; | 1033 }; |
1133 | 1034 |
1134 /** | 1035 /** |
1135 * Checks that all expected scripts are present in the scripts list | 1036 * Checks that all expected scripts are present in the scripts list |
1136 * in the Scripts panel. | 1037 * in the Scripts panel. |
1137 * @param {!Array.<string>} expected Regular expressions describing | 1038 * @param {!Array.<string>} expected Regular expressions describing |
1138 * expected script names. | 1039 * expected script names. |
1139 * @return {boolean} Whether all the scripts are in "scripts-files" select | 1040 * @return {boolean} Whether all the scripts are in "scripts-files" select |
1140 * box | 1041 * box |
1141 */ | 1042 */ |
1142 TestSuite.prototype._scriptsAreParsed = function(expected) | 1043 TestSuite.prototype._scriptsAreParsed = function(expected) { |
1143 { | |
1144 var uiSourceCodes = this.nonAnonymousUISourceCodes_(); | 1044 var uiSourceCodes = this.nonAnonymousUISourceCodes_(); |
1145 // Check that at least all the expected scripts are present. | 1045 // Check that at least all the expected scripts are present. |
1146 var missing = expected.slice(0); | 1046 var missing = expected.slice(0); |
1147 for (var i = 0; i < uiSourceCodes.length; ++i) { | 1047 for (var i = 0; i < uiSourceCodes.length; ++i) { |
1148 for (var j = 0; j < missing.length; ++j) { | 1048 for (var j = 0; j < missing.length; ++j) { |
1149 if (uiSourceCodes[i].name().search(missing[j]) !== -1) { | 1049 if (uiSourceCodes[i].name().search(missing[j]) !== -1) { |
1150 missing.splice(j, 1); | 1050 missing.splice(j, 1); |
1151 break; | 1051 break; |
1152 } | |
1153 } | 1052 } |
| 1053 } |
1154 } | 1054 } |
1155 return missing.length === 0; | 1055 return missing.length === 0; |
1156 }; | 1056 }; |
1157 | 1057 |
1158 | 1058 /** |
1159 /** | 1059 * Waits for script pause, checks expectations, and invokes the callback. |
1160 * Waits for script pause, checks expectations, and invokes the callback. | 1060 * @param {function():void} callback |
1161 * @param {function():void} callback | 1061 */ |
1162 */ | 1062 TestSuite.prototype._waitForScriptPause = function(callback) { |
1163 TestSuite.prototype._waitForScriptPause = function(callback) | 1063 this.addSniffer(WebInspector.DebuggerModel.prototype, '_pausedScript', callb
ack); |
1164 { | 1064 }; |
1165 this.addSniffer(WebInspector.DebuggerModel.prototype, "_pausedScript", callb
ack); | 1065 |
1166 }; | 1066 /** |
1167 | 1067 * Waits until all the scripts are parsed and invokes the callback. |
1168 | 1068 */ |
1169 /** | 1069 TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, cal
lback) { |
1170 * Waits until all the scripts are parsed and invokes the callback. | |
1171 */ | |
1172 TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, callb
ack) | |
1173 { | |
1174 var test = this; | 1070 var test = this; |
1175 | 1071 |
1176 function waitForAllScripts() { | 1072 function waitForAllScripts() { |
1177 if (test._scriptsAreParsed(expectedScripts)) | 1073 if (test._scriptsAreParsed(expectedScripts)) |
1178 callback(); | 1074 callback(); |
1179 else | 1075 else |
1180 test.addSniffer(WebInspector.panels.sources.sourcesView(), "_addUISo
urceCode", waitForAllScripts); | 1076 test.addSniffer(WebInspector.panels.sources.sourcesView(), '_addUISource
Code', waitForAllScripts); |
1181 } | 1077 } |
1182 | 1078 |
1183 waitForAllScripts(); | 1079 waitForAllScripts(); |
1184 }; | 1080 }; |
1185 | 1081 |
1186 TestSuite.prototype._waitForTargets = function(n, callback) | 1082 TestSuite.prototype._waitForTargets = function(n, callback) { |
1187 { | |
1188 checkTargets.call(this); | 1083 checkTargets.call(this); |
1189 | 1084 |
1190 function checkTargets() | 1085 function checkTargets() { |
1191 { | 1086 if (WebInspector.targetManager.targets().length >= n) |
1192 if (WebInspector.targetManager.targets().length >= n) | 1087 callback.call(null); |
1193 callback.call(null); | 1088 else |
1194 else | 1089 this.addSniffer(WebInspector.TargetManager.prototype, 'addTarget', check
Targets.bind(this)); |
1195 this.addSniffer(WebInspector.TargetManager.prototype, "addTarget", c
heckTargets.bind(this)); | 1090 } |
1196 } | 1091 }; |
1197 }; | 1092 |
1198 | 1093 TestSuite.prototype._waitForExecutionContexts = function(n, callback) { |
1199 TestSuite.prototype._waitForExecutionContexts = function(n, callback) | |
1200 { | |
1201 var runtimeModel = WebInspector.targetManager.mainTarget().runtimeModel; | 1094 var runtimeModel = WebInspector.targetManager.mainTarget().runtimeModel; |
1202 checkForExecutionContexts.call(this); | 1095 checkForExecutionContexts.call(this); |
1203 | 1096 |
1204 function checkForExecutionContexts() | 1097 function checkForExecutionContexts() { |
1205 { | 1098 if (runtimeModel.executionContexts().length >= n) |
1206 if (runtimeModel.executionContexts().length >= n) | 1099 callback.call(null); |
1207 callback.call(null); | 1100 else |
1208 else | 1101 this.addSniffer( |
1209 this.addSniffer(WebInspector.RuntimeModel.prototype, "_executionCont
extCreated", checkForExecutionContexts.bind(this)); | 1102 WebInspector.RuntimeModel.prototype, '_executionContextCreated', che
ckForExecutionContexts.bind(this)); |
1210 } | 1103 } |
1211 }; | 1104 }; |
1212 | 1105 |
1213 /** | 1106 |
1214 * Key event with given key identifier. | 1107 window.uiTests = new TestSuite(window.domAutomationController); |
1215 */ | |
1216 TestSuite.createKeyEvent = function(key) | |
1217 { | |
1218 return new KeyboardEvent("keydown", {bubbles: true, cancelable:true, key: ke
y}); | |
1219 }; | |
1220 | |
1221 window.uiTests = new TestSuite(window.domAutomationController); | |
1222 })(window); | 1108 })(window); |
OLD | NEW |