Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Side by Side Diff: chrome/test/data/extensions/api_test/downloads/test.js

Issue 8203005: Implement chrome.experimental.downloads.onChanged (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: debug the new post handler functionality Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // downloads api test 5 // downloads api test
6 // browser_tests.exe --gtest_filter=DownloadsApiTest.Downloads 6 // browser_tests.exe --gtest_filter=DownloadsApiTest.Downloads
7 7
8 var downloads = chrome.experimental.downloads; 8 var downloads = chrome.experimental.downloads;
9 9
10 chrome.test.getConfig(function(testConfig) { 10 chrome.test.getConfig(function(testConfig) {
(...skipping 24 matching lines...) Expand all
35 }); 35 });
36 func.apply(null, args); 36 func.apply(null, args);
37 } catch (exception) { 37 } catch (exception) {
38 chrome.test.assertEq(exceptionMessage, exception.message); 38 chrome.test.assertEq(exceptionMessage, exception.message);
39 chrome.test.succeed(); 39 chrome.test.succeed();
40 } 40 }
41 } 41 }
42 42
43 // The "/slow" handler waits a specified amount of time before returning a 43 // The "/slow" handler waits a specified amount of time before returning a
44 // safe file. Specify zero seconds to return quickly. 44 // safe file. Specify zero seconds to return quickly.
45 var SAFE_FAST_URL = getURL('slow?0'); 45 const SAFE_FAST_URL = getURL('slow?0');
46 var NEVER_FINISH_URL = getURL('download-known-size'); 46 const NEVER_FINISH_URL = getURL('download-known-size');
47 var ERROR_GENERIC = downloads.ERROR_GENERIC; 47 const POST_URL = 'files/post/downloads/a_zip_file.zip?require_body_eq_path'
48 var ERROR_INVALID_URL = downloads.ERROR_INVALID_URL; 48 const ERROR_GENERIC = downloads.ERROR_GENERIC;
49 var ERROR_INVALID_OPERATION = downloads.ERROR_INVALID_OPERATION; 49 const ERROR_INVALID_URL = downloads.ERROR_INVALID_URL;
50 const ERROR_INVALID_OPERATION = downloads.ERROR_INVALID_OPERATION;
51
52 console.log("I know all these console.logs stink up the place, but please " +
cbentzel 2012/02/10 21:06:31 Will these actually show up on the output of all b
benjhayden 2012/02/10 21:43:18 Done.
53 "leave them in: they will help you check that all the " +
54 "callbacks for a particular test run before the test harness " +
55 "thinks that that test is finished and that that test doesn't " +
56 "'finish' twice.");
57 console.log("All log lines that contain a download_id should appear " +
58 "before that test finishes. If a callback for test N runs " +
59 "after test N+1 begins, then that indicates a race condition " +
60 "in test N.");
50 61
51 chrome.test.runTests([ 62 chrome.test.runTests([
52 // TODO(benjhayden): Test onErased using remove(). 63 // TODO(benjhayden): Test onErased using remove().
64
65 // TODO(benjhayden): Sub-directories depend on http://crbug.com/109443
66 // function downloadSubDirectoryFilename() {
67 // var download_id = getNextId();
68 // console.log("id: " + download_id);
69 // var callbackCompleted = chrome.test.callbackAdded();
70 // function myListener(delta) {
71 // console.log("id: " + download_id);
72 // if (delta.filename) console.log("filename: " + delta.filename.new);
73 // if (delta.filename &&
74 // delta.filename.new.indexOf('/foo/slow') !== -1) {
75 // downloads.onChanged.removeListener(myListener);
76 // callbackCompleted();
77 // }
78 // }
79 // downloads.onChanged.addListener(myListener);
80 // downloads.download(
81 // {'url': SAFE_FAST_URL, 'filename': 'foo/slow'},
82 // chrome.test.callback(function(id) {
83 // console.log("id: " + download_id);
84 // chrome.test.assertEq(download_id, id);
85 // }));
86 // },
87
88 function downloadSimple() {
89 // Test that we can begin a download.
90 const download_id = getNextId();
91 console.log("id: " + download_id);
92 downloads.download(
93 {'url': SAFE_FAST_URL},
94 chrome.test.callbackPass(function(id) {
95 console.log("id: " + download_id);
96 chrome.test.assertEq(download_id, id);
97 }));
98 },
99
100 function downloadPostSuccess() {
101 // Test the |method| download option.
102 const download_id = getNextId();
103 console.log("id: " + download_id);
104
105 var changedCompleted = chrome.test.callbackAdded();
106 function changedListener(delta) {
107 console.log("id: " + delta.id);
108 if ((delta.id == download_id) &&
109 delta.state)
110 console.log("state: " + delta.state.new);
111 // Ignore onChanged events for downloads besides our own, or events that
112 // signal any change besides completion.
113 if ((delta.id == download_id) &&
114 delta.state &&
115 (delta.state.new == downloads.STATE_COMPLETE)) {
116 console.log("id: " + delta.id);
117 chrome.test.assertEq(downloads.STATE_COMPLETE, delta.state.new);
118 downloads.search({id: download_id},
119 chrome.test.callback(function(items) {
120 chrome.test.assertEq(1, items.length);
121 chrome.test.assertEq(download_id, items[0].id);
122 const kExpectedSize = 164;
123 chrome.test.assertEq(kExpectedSize, items[0].totalBytes);
124 chrome.test.assertEq(kExpectedSize, items[0].fileSize);
125 chrome.test.assertEq(kExpectedSize, items[0].bytesReceived);
126 }));
127 downloads.onChanged.removeListener(changedListener);
128 changedCompleted();
129 }
130 }
131 downloads.onChanged.addListener(changedListener);
132
133 downloads.download(
134 {'url': getURL(POST_URL),
135 'method': 'POST',
136 'filename': download_id + '.txt',
137 'body': '/' + POST_URL},
138 chrome.test.callbackPass(function(id) {
139 console.log("id: " + download_id);
140 chrome.test.assertEq(download_id, id);
141 }));
142 },
143
144 function downloadPostWouldFailWithoutMethod() {
145 // Test that downloadPostSuccess would fail if the resource requires the
146 // POST method, and chrome fails to propagate the |method| parameter back
147 // to the server.
148 const download_id = getNextId();
149 console.log("id: " + download_id);
150
151 var changedCompleted = chrome.test.callbackAdded();
152 function changedListener(delta) {
153 console.log("id: " + delta.id);
154 if (delta.state) console.log("state: " + delta.state.new);
155 // Ignore onChanged events for downloads besides our own, or events that
156 // signal any change besides interruption.
157 if ((delta.id == download_id) &&
158 delta.state &&
159 ((delta.state.new == downloads.STATE_INTERRUPTED) ||
160 (delta.state.new == downloads.STATE_COMPLETE))) {
161 console.log("id: " + delta.id);
162 // TODO(benjhayden): Figure out why this download isn't interrupted.
163 // chrome.test.assertEq(downloads.STATE_INTERRUPTED, delta.state.new);
164 downloads.search({id: download_id},
165 chrome.test.callback(function(items) {
166 chrome.test.assertEq(1, items.length);
167 chrome.test.assertEq(download_id, items[0].id);
168 chrome.test.assertEq(0, items[0].bytesReceived);
169 }));
170 downloads.onChanged.removeListener(changedListener);
171 changedCompleted();
172 }
173 }
174 downloads.onChanged.addListener(changedListener);
175
176 downloads.download(
177 {'url': getURL(POST_URL),
178 'filename': download_id + '.txt',
179 'body': '/' + POST_URL},
180 chrome.test.callbackPass(function(id) {
181 console.log("id: " + download_id);
182 chrome.test.assertEq(download_id, id);
183 }));
184 },
185
186 function downloadPostWouldFailWithoutBody() {
187 // Test that downloadPostSuccess would fail if the resource requires the
188 // POST method and a request body, and chrome fails to propagate the
189 // |body| parameter back to the server.
190 const download_id = getNextId();
191 console.log("id: " + download_id);
192
193 var changedCompleted = chrome.test.callbackAdded();
194 function changedListener(delta) {
195 console.log("id: " + delta.id);
196 if (delta.state) console.log("state: " + delta.state.new);
197 // Ignore onChanged events for downloads besides our own, or events that
198 // signal any change besides interruption.
199 if ((delta.id == download_id) &&
200 delta.state &&
201 ((delta.state.new == downloads.STATE_INTERRUPTED) ||
202 (delta.state.new == downloads.STATE_COMPLETE))) {
203 console.log("id: " + delta.id);
204 // TODO(benjhayden): Figure out why this download isn't interrupted.
205 // chrome.test.assertEq(downloads.STATE_INTERRUPTED, delta.state.new);
206 downloads.search({id: download_id},
207 chrome.test.callback(function(items) {
208 chrome.test.assertEq(1, items.length);
209 chrome.test.assertEq(download_id, items[0].id);
210 chrome.test.assertEq(0, items[0].bytesReceived);
211 }));
212 downloads.onChanged.removeListener(changedListener);
213 changedCompleted();
214 }
215 }
216 downloads.onChanged.addListener(changedListener);
217
218 downloads.download(
219 {'url': getURL(POST_URL),
220 'filename': download_id + '.txt',
221 'method': 'POST'},
222 chrome.test.callbackPass(function(id) {
223 console.log("id: " + download_id);
224 chrome.test.assertEq(download_id, id);
225 }));
226 },
227
228 function downloadHeader() {
229 // Test the |headers| download option.
230 const download_id = getNextId();
231 console.log("id: " + download_id);
232 downloads.download(
233 {'url': SAFE_FAST_URL,
234 'headers': [{'name': 'Foo', 'value': 'bar'}]
235 },
236 chrome.test.callbackPass(function(id) {
237 console.log("id: " + download_id);
238 chrome.test.assertEq(download_id, id);
239 }));
240 },
241
242 function downloadInterrupted() {
243 // Test that cancel()ing an in-progress download causes its state to
244 // transition to interrupted, and test that that state transition is
245 // detectable by an onChanged event listener.
246 const download_id = getNextId();
247 console.log("id: " + download_id);
248
249 var createdCompleted = chrome.test.callbackAdded();
250 function createdListener(created_item) {
251 console.log("created_id: " + created_item.id);
252 // Ignore onCreated events for any download besides our own.
253 if (created_item.id != download_id)
254 return;
255 // TODO(benjhayden) Move this cancel() into the download() callback
256 // after ensuring that DownloadItems are created before that callback
257 // is fired.
258 downloads.cancel(download_id, chrome.test.callback(function() {
259 console.log("id: " + download_id);
260 }));
261 downloads.onCreated.removeListener(createdListener);
262 createdCompleted();
263 }
264 downloads.onCreated.addListener(createdListener);
265
266 var changedCompleted = chrome.test.callbackAdded();
267 function changedListener(delta) {
268 console.log("id: " + delta.id);
269 // Ignore onChanged events for downloads besides our own, or events that
270 // signal any change besides interruption.
271 if ((delta.id == download_id) &&
272 delta.state &&
273 (delta.state.new == downloads.STATE_INTERRUPTED)) {
274 console.log("id: " + delta.id);
275 downloads.onChanged.removeListener(changedListener);
276 changedCompleted();
277 }
278 }
279 downloads.onChanged.addListener(changedListener);
280
281 downloads.download(
282 {'url': NEVER_FINISH_URL},
283 chrome.test.callback(function(id) {
284 console.log("id: " + download_id);
285 chrome.test.assertEq(download_id, id);
286 }));
287 },
288
289
290 function downloadOnChanged() {
291 // Test that download completion is detectable by an onChanged event
292 // listener.
293 const download_id = getNextId();
294 console.log("id: " + download_id);
295 var callbackCompleted = chrome.test.callbackAdded();
296 function myListener(delta) {
297 console.log("id: " + delta.id);
298 if (delta.state) console.log("state: " + delta.state.new);
299 if (delta.state && delta.state.new == downloads.STATE_COMPLETE) {
300 downloads.onChanged.removeListener(myListener);
301 callbackCompleted();
302 }
303 }
304 downloads.onChanged.addListener(myListener);
305 downloads.download(
306 {"url": getURL("slow?0")},
307 chrome.test.callback(function(id) {
308 console.log("id: " + download_id);
309 chrome.test.assertEq(download_id, id);
310 }));
311 },
312
53 function downloadFilename() { 313 function downloadFilename() {
54 downloads.download( 314 // Test that we can suggest a filename for a new download, and test that
55 {'url': SAFE_FAST_URL, 'filename': 'foo'}, 315 // we can detect filename changes with an onChanged event listener.
56 chrome.test.callbackPass(function(id) { 316 const kFilename = 'owiejtoiwjrfoiwjroiwjroiwjroiwjrfi';
57 chrome.test.assertEq(getNextId(), id); 317 const download_id = getNextId();
58 })); 318 console.log("id: " + download_id);
59 // TODO(benjhayden): Test the filename using onChanged. 319 var callbackCompleted = chrome.test.callbackAdded();
60 }, 320 function myListener(delta) {
321 console.log("id: " + download_id);
322 if (delta.filename) console.log("filename: " + delta.filename.new);
323 if (delta.filename && delta.filename.new.indexOf(kFilename) !== -1) {
324 downloads.onChanged.removeListener(myListener);
325 callbackCompleted();
326 }
327 }
328 downloads.onChanged.addListener(myListener);
329 downloads.download(
330 {'url': SAFE_FAST_URL, 'filename': kFilename},
331 chrome.test.callback(function(id) {
332 console.log("id: " + download_id);
333 chrome.test.assertEq(download_id, id);
334 }));
335 },
336
61 function downloadOnCreated() { 337 function downloadOnCreated() {
62 chrome.test.listenOnce(downloads.onCreated, 338 // Test that the onCreated event fires when we start a download.
63 chrome.test.callbackPass(function(item) {})); 339 var download_id = getNextId();
340 console.log("id: " + download_id);
341 var createdCompleted = chrome.test.callbackAdded();
342 function createdListener(item) {
343 if (item.id == download_id) {
344 createdCompleted();
345 downloads.onCreated.removeListener(createdListener);
346 }
347 };
348 downloads.onCreated.addListener(createdListener);
64 downloads.download( 349 downloads.download(
65 {'url': SAFE_FAST_URL}, 350 {'url': SAFE_FAST_URL},
66 function(id) { 351 chrome.test.callback(function(id) {
67 chrome.test.assertEq(getNextId(), id); 352 chrome.test.assertEq(download_id, id);
68 }); 353 }));
69 }, 354 },
70 function downloadSubDirectoryFilename() { 355
71 downloads.download(
72 {'url': SAFE_FAST_URL, 'filename': 'foo/slow'},
73 chrome.test.callbackPass(function(id) {
74 chrome.test.assertEq(getNextId(), id);
75 }));
76 // TODO(benjhayden): Test the filename using onChanged.
77 },
78 function downloadInvalidFilename() { 356 function downloadInvalidFilename() {
357 // Test that we disallow invalid filenames for new downloads.
79 downloads.download( 358 downloads.download(
80 {'url': SAFE_FAST_URL, 'filename': '../../../../../etc/passwd'}, 359 {'url': SAFE_FAST_URL, 'filename': '../../../../../etc/passwd'},
81 chrome.test.callbackFail(ERROR_GENERIC)); 360 chrome.test.callbackFail(ERROR_GENERIC));
82 // TODO(benjhayden): Give a better error message. 361 },
83 }, 362
84 function downloadEmpty() { 363 function downloadEmpty() {
85 assertThrows(('Invalid value for argument 1. Property \'url\': ' + 364 assertThrows(('Invalid value for argument 1. Property \'url\': ' +
86 'Property is required.'), 365 'Property is required.'),
87 downloads.download, {}); 366 downloads.download, {});
88 }, 367 },
368
89 function downloadInvalidSaveAs() { 369 function downloadInvalidSaveAs() {
90 assertThrows(('Invalid value for argument 1. Property \'saveAs\': ' + 370 assertThrows(('Invalid value for argument 1. Property \'saveAs\': ' +
91 'Expected \'boolean\' but got \'string\'.'), 371 'Expected \'boolean\' but got \'string\'.'),
92 downloads.download, 372 downloads.download,
93 {'url': SAFE_FAST_URL, 'saveAs': 'GOAT'}); 373 {'url': SAFE_FAST_URL, 'saveAs': 'GOAT'});
94 }, 374 },
375
95 function downloadInvalidHeadersOption() { 376 function downloadInvalidHeadersOption() {
96 assertThrows(('Invalid value for argument 1. Property \'headers\': ' + 377 assertThrows(('Invalid value for argument 1. Property \'headers\': ' +
97 'Expected \'array\' but got \'string\'.'), 378 'Expected \'array\' but got \'string\'.'),
98 downloads.download, 379 downloads.download,
99 {'url': SAFE_FAST_URL, 'headers': 'GOAT'}); 380 {'url': SAFE_FAST_URL, 'headers': 'GOAT'});
100 }, 381 },
382
101 function downloadInvalidURL() { 383 function downloadInvalidURL() {
384 // Test that download() requires a valid url.
102 downloads.download( 385 downloads.download(
103 {'url': 'foo bar'}, 386 {'url': 'foo bar'},
104 chrome.test.callbackFail(ERROR_INVALID_URL)); 387 chrome.test.callbackFail(ERROR_INVALID_URL));
105 }, 388 },
389
106 function downloadInvalidMethod() { 390 function downloadInvalidMethod() {
107 assertThrows(('Invalid value for argument 1. Property \'method\': ' + 391 assertThrows(('Invalid value for argument 1. Property \'method\': ' +
108 'Value must be one of: [GET, POST].'), 392 'Value must be one of: [GET, POST].'),
109 downloads.download, 393 downloads.download,
110 {'url': SAFE_FAST_URL, 'method': 'GOAT'}); 394 {'url': SAFE_FAST_URL, 'method': 'GOAT'});
111 }, 395 },
112 function downloadSimple() { 396
113 downloads.download(
114 {'url': SAFE_FAST_URL},
115 chrome.test.callbackPass(function(id) {
116 chrome.test.assertEq(getNextId(), id);
117 }));
118 },
119 function downloadPost() {
120 downloads.download(
121 {'url': getURL('files/post/downloads/a_zip_file.js'),
122 'method': 'POST',
123 'body': 'WOOHOO'},
124 chrome.test.callbackPass(function(id) {
125 chrome.test.assertEq(getNextId(), id);
126 }));
127 },
128 function downloadHeader() {
129 downloads.download(
130 {'url': SAFE_FAST_URL,
131 'headers': [{'name': 'Foo', 'value': 'bar'}]
132 },
133 chrome.test.callbackPass(function(id) {
134 chrome.test.assertEq(getNextId(), id);
135 }));
136 },
137 function downloadInterrupted() {
138 // TODO(benjhayden): Find a suitable URL and test that this id is
139 // eventually interrupted using onChanged.
140 downloads.download(
141 {'url': SAFE_FAST_URL},
142 chrome.test.callbackPass(function(id) {
143 chrome.test.assertEq(getNextId(), id);
144 }));
145 },
146 function downloadInvalidHeader() { 397 function downloadInvalidHeader() {
398 // Test that download() disallows setting the Cookie header.
147 downloads.download( 399 downloads.download(
148 {'url': SAFE_FAST_URL, 400 {'url': SAFE_FAST_URL,
149 'headers': [{ 'name': 'Cookie', 'value': 'fake'}] 401 'headers': [{ 'name': 'Cookie', 'value': 'fake'}]
150 }, 402 },
151 chrome.test.callbackFail(ERROR_GENERIC)); 403 chrome.test.callbackFail(ERROR_GENERIC));
152 // TODO(benjhayden): Give a better error message. 404 },
153 }, 405
154 function downloadGetFileIconInvalidOptions() { 406 function downloadGetFileIconInvalidOptions() {
155 assertThrows(('Invalid value for argument 2. Property \'cat\': ' + 407 assertThrows(('Invalid value for argument 2. Property \'cat\': ' +
156 'Unexpected property.'), 408 'Unexpected property.'),
157 downloads.getFileIcon, 409 downloads.getFileIcon,
158 -1, {cat: 'mouse'}); 410 -1, {cat: 'mouse'});
159 }, 411 },
412
160 function downloadGetFileIconInvalidSize() { 413 function downloadGetFileIconInvalidSize() {
161 assertThrows(('Invalid value for argument 2. Property \'size\': ' + 414 assertThrows(('Invalid value for argument 2. Property \'size\': ' +
162 'Value must be one of: [16, 32].'), 415 'Value must be one of: [16, 32].'),
163 downloads.getFileIcon, -1, {size: 31}); 416 downloads.getFileIcon, -1, {size: 31});
164 }, 417 },
418
165 function downloadGetFileIconInvalidId() { 419 function downloadGetFileIconInvalidId() {
166 downloads.getFileIcon(-42, {size: 32}, 420 downloads.getFileIcon(-42, {size: 32},
167 chrome.test.callbackFail(ERROR_INVALID_OPERATION)); 421 chrome.test.callbackFail(ERROR_INVALID_OPERATION));
168 }, 422 },
169 function downloadNoComplete() { 423
170 // This is used partly to test cleanUp.
171 downloads.download(
172 {'url': NEVER_FINISH_URL},
173 chrome.test.callbackPass(function(id) {
174 chrome.test.assertEq(getNextId(), id);
175 }));
176 },
177 function downloadPauseInvalidId() { 424 function downloadPauseInvalidId() {
178 downloads.pause(-42, chrome.test.callbackFail(ERROR_INVALID_OPERATION)); 425 downloads.pause(-42, chrome.test.callbackFail(ERROR_INVALID_OPERATION));
179 }, 426 },
427
180 function downloadPauseInvalidType() { 428 function downloadPauseInvalidType() {
181 assertThrows(('Invalid value for argument 1. Expected \'integer\' ' + 429 assertThrows(('Invalid value for argument 1. Expected \'integer\' ' +
182 'but got \'string\'.'), 430 'but got \'string\'.'),
183 downloads.pause, 431 downloads.pause,
184 'foo'); 432 'foo');
185 }, 433 },
434
186 function downloadResumeInvalidId() { 435 function downloadResumeInvalidId() {
187 downloads.resume(-42, chrome.test.callbackFail(ERROR_INVALID_OPERATION)); 436 downloads.resume(-42, chrome.test.callbackFail(ERROR_INVALID_OPERATION));
188 }, 437 },
438
189 function downloadResumeInvalidType() { 439 function downloadResumeInvalidType() {
190 assertThrows(('Invalid value for argument 1. Expected \'integer\' ' + 440 assertThrows(('Invalid value for argument 1. Expected \'integer\' ' +
191 'but got \'string\'.'), 441 'but got \'string\'.'),
192 downloads.resume, 442 downloads.resume,
193 'foo'); 443 'foo');
194 }, 444 },
445
195 function downloadCancelInvalidId() { 446 function downloadCancelInvalidId() {
196 // Canceling a non-existent download is not considered an error. 447 // Canceling a non-existent download is not considered an error.
197 downloads.cancel(-42, chrome.test.callbackPass(function() {})); 448 downloads.cancel(-42, chrome.test.callbackPass(function() {}));
198 }, 449 },
450
199 function downloadCancelInvalidType() { 451 function downloadCancelInvalidType() {
200 assertThrows(('Invalid value for argument 1. Expected \'integer\' ' + 452 assertThrows(('Invalid value for argument 1. Expected \'integer\' ' +
201 'but got \'string\'.'), 453 'but got \'string\'.'),
202 downloads.cancel, 'foo'); 454 downloads.cancel, 'foo');
203 }, 455 },
456
457 function downloadNoComplete() {
458 // This is used partly to test cleanUp.
459 var download_id = getNextId();
460 console.log("id: " + download_id);
461 downloads.download(
462 {'url': NEVER_FINISH_URL},
463 chrome.test.callbackPass(function(id) {
464 console.log("id: " + download_id);
465 chrome.test.assertEq(download_id, id);
466 }));
467 },
468
204 function cleanUp() { 469 function cleanUp() {
205 // cleanUp must come last. It clears out all in-progress downloads 470 // cleanUp must come last. It clears out all in-progress downloads
206 // so the browser can shutdown cleanly. 471 // so the browser can shutdown cleanly.
207 for (var id = 0; id < nextId; ++id) { 472 for (var id = 0; id < nextId; ++id) {
208 downloads.cancel(id, chrome.test.callbackPass(function() {})); 473 downloads.cancel(id, chrome.test.callbackPass(function() {}));
209 } 474 }
210 } 475 }
211 ]); 476 ]);
212 }); 477 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698