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

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs

Issue 2079073002: Make ChromeVox Next a setting in options page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: m Created 4 years, 6 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 // Include test fixture. 5 // Include test fixture.
6 GEN_INCLUDE(['../../testing/chromevox_next_e2e_test_base.js', 6 GEN_INCLUDE(['../../testing/chromevox_next_e2e_test_base.js',
7 '../../testing/assert_additions.js']); 7 '../../testing/assert_additions.js']);
8 8
9 GEN_INCLUDE(['../../testing/mock_feedback.js']); 9 GEN_INCLUDE(['../../testing/mock_feedback.js']);
10 10
11 /** 11 /**
12 * Test fixture for Background. 12 * Test fixture for Background.
13 * @constructor 13 * @constructor
14 * @extends {ChromeVoxNextE2ETest} 14 * @extends {ChromeVoxNextE2ETest}
15 */ 15 */
16 function BackgroundTest() { 16 function BackgroundTest() {
17 ChromeVoxNextE2ETest.call(this); 17 ChromeVoxNextE2ETest.call(this);
18 } 18 }
19 19
20 BackgroundTest.prototype = { 20 BackgroundTest.prototype = {
21 __proto__: ChromeVoxNextE2ETest.prototype, 21 __proto__: ChromeVoxNextE2ETest.prototype,
22 22
23 /** @override */ 23 /** @override */
24 setUp: function() { 24 setUp: function() {
25 global.backgroundObj.forceChromeVoxNextActive(); 25 ChromeVoxState.instance.toggleNext(true);
26 window.RoleType = chrome.automation.RoleType; 26 window.RoleType = chrome.automation.RoleType;
27 window.doCmd = this.doCmd; 27 window.doCmd = this.doCmd;
28 }, 28 },
29 29
30 /** 30 /**
31 * @return {!MockFeedback} 31 * @return {!MockFeedback}
32 */ 32 */
33 createMockFeedback: function() { 33 createMockFeedback: function() {
34 var mockFeedback = new MockFeedback(this.newCallback(), 34 var mockFeedback = new MockFeedback(this.newCallback(),
35 this.newCallback.bind(this)); 35 this.newCallback.bind(this));
36 mockFeedback.install(); 36 mockFeedback.install();
37 return mockFeedback; 37 return mockFeedback;
38 }, 38 },
39 39
40 /** 40 /**
41 * Create a function which perform the command |cmd|. 41 * Create a function which perform the command |cmd|.
42 * @param {string} cmd 42 * @param {string} cmd
43 * @return {function() : void} 43 * @return {function() : void}
44 */ 44 */
45 doCmd: function(cmd) { 45 doCmd: function(cmd) {
46 return function() { 46 return function() {
47 global.backgroundObj.onGotCommand(cmd); 47 ChromeVoxState.instance.onGotCommand(cmd);
48 }; 48 };
49 }, 49 },
50 50
51 linksAndHeadingsDoc: function() {/*! 51 linksAndHeadingsDoc: function() {/*!
52 <p>start</p> 52 <p>start</p>
53 <a href='#a'>alpha</a> 53 <a href='#a'>alpha</a>
54 <a href='#b'>beta</a> 54 <a href='#b'>beta</a>
55 <p> 55 <p>
56 <h1>charlie</h1> 56 <h1>charlie</h1>
57 <a href='foo'>delta</a> 57 <a href='foo'>delta</a>
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 'beta', 'Link', 244 'beta', 'Link',
245 'charlie', 'Heading 1'); 245 'charlie', 'Heading 1');
246 mockFeedback.replay(); 246 mockFeedback.replay();
247 }); 247 });
248 }); 248 });
249 249
250 TEST_F('BackgroundTest', 'InitialFocus', function() { 250 TEST_F('BackgroundTest', 'InitialFocus', function() {
251 var mockFeedback = this.createMockFeedback(); 251 var mockFeedback = this.createMockFeedback();
252 this.runWithLoadedTree('<a href="a">a</a>', 252 this.runWithLoadedTree('<a href="a">a</a>',
253 function(rootNode) { 253 function(rootNode) {
254 mockFeedback.expectSpeech('data:text/html,<!doctype html>' + 254 mockFeedback.expectSpeech('a')
255 '<a href="a">a</a>')
256 .expectSpeech('a')
257 .expectSpeech('Link'); 255 .expectSpeech('Link');
258 mockFeedback.replay(); 256 mockFeedback.replay();
259 }); 257 });
260 }); 258 });
261 259
262 TEST_F('BackgroundTest', 'AriaLabel', function() { 260 TEST_F('BackgroundTest', 'AriaLabel', function() {
263 var mockFeedback = this.createMockFeedback(); 261 var mockFeedback = this.createMockFeedback();
264 this.runWithLoadedTree('<a aria-label="foo" href="a">a</a>', 262 this.runWithLoadedTree('<a aria-label="foo" href="a">a</a>',
265 function(rootNode) { 263 function(rootNode) {
266 rootNode.find({role: RoleType.link}).focus(); 264 rootNode.find({role: RoleType.link}).focus();
267 mockFeedback.expectSpeech('foo') 265 mockFeedback.expectSpeech('foo')
268 .expectSpeech('Link') 266 .expectSpeech('Link')
269 .expectBraille('foo lnk'); 267 .expectBraille('foo lnk');
270 mockFeedback.replay(); 268 mockFeedback.replay();
271 } 269 }
272 ); 270 );
273 }); 271 });
274 272
275 TEST_F('BackgroundTest', 'ShowContextMenu', function() { 273 TEST_F('BackgroundTest', 'ShowContextMenu', function() {
276 var mockFeedback = this.createMockFeedback(); 274 var mockFeedback = this.createMockFeedback();
277 this.runWithLoadedTree('<a href="a">a</a>', 275 this.runWithLoadedTree('<p>before</p><a href="a">a</a>',
278 function(rootNode) { 276 function(rootNode) {
279 mockFeedback.expectSpeech(/menu opened/) 277 mockFeedback.expectSpeech(/menu opened/)
280 .call(function() { 278 .call(function() {
281 // When shown, the context menu pushes a new message loop so test 279 // When shown, the context menu pushes a new message loop so test
282 // messages sent to the browser do not get processed. Ensure we 280 // messages sent to the browser do not get processed. Ensure we
283 // exit the context menu here. 281 // exit the context menu here.
284 go.showContextMenu(); 282 go.showContextMenu();
285 }); 283 });
286 mockFeedback.replay(); 284 mockFeedback.replay();
287 285
288 var go = rootNode.find({ role: RoleType.link }); 286 var go = rootNode.find({ role: RoleType.link });
289 this.listenOnce(go, 'focus', function(e) { 287 this.listenOnce(go, 'focus', function(e) {
290 doCmd('contextMenu')(); 288 doCmd('contextMenu')();
291 }.bind(this), true); 289 }.bind(this), true);
292 go.focus(); 290 go.focus();
293 }.bind(this)); 291 }.bind(this));
294 }); 292 });
295 293
296 TEST_F('BackgroundTest', 'BrailleRouting', function() { 294 TEST_F('BackgroundTest', 'BrailleRouting', function() {
297 var mockFeedback = this.createMockFeedback(); 295 var mockFeedback = this.createMockFeedback();
298 var route = function(position) { 296 var route = function(position) {
299 assertTrue(global.backgroundObj.onBrailleKeyEvent( 297 assertTrue(ChromeVoxState.instance.onBrailleKeyEvent(
300 {command: cvox.BrailleKeyCommand.ROUTING, 298 {command: cvox.BrailleKeyCommand.ROUTING,
301 displayPosition: position}, 299 displayPosition: position},
302 mockFeedback.lastMatchedBraille)); 300 mockFeedback.lastMatchedBraille));
303 }; 301 };
304 this.runWithLoadedTree( 302 this.runWithLoadedTree(
305 function() {/*! 303 function() {/*!
306 <p>start</p> 304 <p>start</p>
307 <button id="btn1">Click me</button> 305 <button id="btn1">Click me</button>
308 <p>Some text</p> 306 <p>Some text</p>
309 <button id="btn2">Focus me</button> 307 <button id="btn2">Focus me</button>
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 360
363 TEST_F('BackgroundTest', 'UseEditableState', function() { 361 TEST_F('BackgroundTest', 'UseEditableState', function() {
364 this.runWithLoadedTree( 362 this.runWithLoadedTree(
365 function() {/*! 363 function() {/*!
366 <input type="text"></input> 364 <input type="text"></input>
367 <p tabindex=0>hi</p> 365 <p tabindex=0>hi</p>
368 */}, 366 */},
369 function(rootNode) { 367 function(rootNode) {
370 var assertExists = this.newCallback(function (evt) { 368 var assertExists = this.newCallback(function (evt) {
371 assertNotNullNorUndefined( 369 assertNotNullNorUndefined(
372 global.desktopAutomationHandler.textEditHandler_); 370 ChromeVoxState.desktopAutomationHandler.textEditHandler_);
373 evt.stopPropagation(); 371 evt.stopPropagation();
374 }); 372 });
375 var assertDoesntExist = this.newCallback(function (evt) { 373 var assertDoesntExist = this.newCallback(function (evt) {
376 assertTrue(!global.desktopAutomationHandler.editableTextHandler_); 374 assertTrue(
375 !ChromeVoxState.desktopAutomationHandler.editableTextHandler_);
377 evt.stopPropagation(); 376 evt.stopPropagation();
378 }); 377 });
379 378
380 var editable = rootNode.find({ role: RoleType.textField }); 379 var editable = rootNode.find({ role: RoleType.textField });
381 var nonEditable = rootNode.find({ role: RoleType.paragraph }); 380 var nonEditable = rootNode.find({ role: RoleType.paragraph });
382 381
383 this.listenOnce(editable, 'focus', assertExists); 382 this.listenOnce(editable, 'focus', assertExists);
384 this.listenOnce(nonEditable, 'focus', assertDoesntExist); 383 this.listenOnce(nonEditable, 'focus', assertDoesntExist);
385 384
386 editable.focus(); 385 editable.focus();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 .expectSpeech(/slider/) 427 .expectSpeech(/slider/)
429 .expectEarcon(cvox.Earcon.SLIDER); 428 .expectEarcon(cvox.Earcon.SLIDER);
430 429
431 mockFeedback.replay(); 430 mockFeedback.replay();
432 }.bind(this)); 431 }.bind(this));
433 }); 432 });
434 433
435 TEST_F('BackgroundTest', 'ToggleChromeVoxVersion', function() { 434 TEST_F('BackgroundTest', 'ToggleChromeVoxVersion', function() {
436 var mockFeedback = this.createMockFeedback(); 435 var mockFeedback = this.createMockFeedback();
437 this.runWithLoadedTree(this.linksAndHeadingsDoc, function() { 436 this.runWithLoadedTree(this.linksAndHeadingsDoc, function() {
438 var gotCmd = global.backgroundObj.onGotCommand; 437 var gotCmd = ChromeVoxState.instance.onGotCommand;
439 438
440 // The command came from the background keyboard handler. 439 // The command came from the background keyboard handler.
441 var togglerFromBackground = gotCmd.bind(gotCmd, 'toggleChromeVoxVersion'); 440 var togglerFromBackground = gotCmd.bind(gotCmd, 'toggleChromeVoxVersion');
442 441
443 // The command came from a content script. 442 // The command came from a content script.
444 var togglerFromContent = gotCmd.bind(gotCmd, 'toggleChromeVoxVersion', 443 var togglerFromContent = gotCmd.bind(gotCmd, 'toggleChromeVoxVersion',
445 true); 444 true);
446 445
447 mockFeedback.call(togglerFromBackground) 446 mockFeedback.call(togglerFromBackground)
448 .expectSpeech('classic') 447 .expectSpeech('Switched to Classic ChromeVox')
449 .call(togglerFromContent) 448 .call(togglerFromContent)
450 .expectSpeech('next') 449 .expectSpeech('Switched to ChromeVox Next')
451 .call(togglerFromBackground) 450 .call(togglerFromBackground)
452 .expectSpeech('classic'); 451 .expectSpeech('Switched to Classic ChromeVox');
453 mockFeedback.replay(); 452 mockFeedback.replay();
454 }); 453 });
455 }); 454 });
456 455
457 SYNC_TEST_F('BackgroundTest', 'GlobsToRegExp', function() { 456 SYNC_TEST_F('BackgroundTest', 'GlobsToRegExp', function() {
458 assertEquals('/^()$/', Background.globsToRegExp_([]).toString()); 457 assertEquals('/^()$/', Background.globsToRegExp_([]).toString());
459 assertEquals( 458 assertEquals(
460 '/^(http:\\/\\/host\\/path\\+here)$/', 459 '/^(http:\\/\\/host\\/path\\+here)$/',
461 Background.globsToRegExp_(['http://host/path+here']).toString()); 460 Background.globsToRegExp_(['http://host/path+here']).toString());
462 assertEquals( 461 assertEquals(
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 503
505 TEST_F('BackgroundTest', 'ModeSwitching', function() { 504 TEST_F('BackgroundTest', 'ModeSwitching', function() {
506 this.runWithLoadedTree('<button></button>', function(root) { 505 this.runWithLoadedTree('<button></button>', function(root) {
507 var fakeDesktop = {}; 506 var fakeDesktop = {};
508 fakeDesktop.role = 'desktop'; 507 fakeDesktop.role = 'desktop';
509 fakeDesktop.root = fakeDesktop; 508 fakeDesktop.root = fakeDesktop;
510 509
511 var fakeWebRoot = {}; 510 var fakeWebRoot = {};
512 fakeWebRoot.root = fakeWebRoot; 511 fakeWebRoot.root = fakeWebRoot;
513 fakeWebRoot.parent = fakeDesktop; 512 fakeWebRoot.parent = fakeDesktop;
514 fakeWebRoot.role = 'rootWebArea'; 513 fakeWebRoot.role = RoleType.rootWebArea;
514 fakeWebRoot.makeVisible = function() {};
515 fakeWebRoot.location = {left: 1, top: 1, width: 1, height: 1};
515 var fakeSubRoot = {}; 516 var fakeSubRoot = {};
516 fakeSubRoot.root = fakeSubRoot; 517 fakeSubRoot.root = fakeSubRoot;
517 fakeSubRoot.parent = fakeWebRoot; 518 fakeSubRoot.parent = fakeWebRoot;
518 fakeSubRoot.role = 'rootWebArea'; 519 fakeSubRoot.role = RoleType.rootWebArea;
520 fakeSubRoot.makeVisible = function() {};
521 fakeSubRoot.location = {left: 1, top: 1, width: 1, height: 1};
522 var bk = ChromeVoxState.instance;
519 523
520 // Tests default to force next mode. 524 // Tests default to force next mode.
521 assertEquals('force_next', global.backgroundObj.mode); 525 assertEquals('force_next', bk.mode);
522 526
523 // Force next mode stays set regardless of where the range lands. 527 // Force next mode stays set regardless of where the range lands.
524 fakeWebRoot.docUrl = 'http://google.com'; 528 fakeWebRoot.docUrl = 'http://google.com';
525 global.backgroundObj.refreshMode(fakeWebRoot); 529 bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
526 assertEquals('force_next', global.backgroundObj.mode); 530 assertEquals('force_next', bk.mode);
527 // Empty urls occur before document load or when root is desktop. 531 // Empty urls occur before document load or when root is desktop.
528 fakeWebRoot.docUrl = ''; 532 fakeWebRoot.docUrl = '';
529 global.backgroundObj.refreshMode(fakeWebRoot); 533 bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
530 assertEquals('force_next', global.backgroundObj.mode); 534 assertEquals('force_next', bk.mode);
531 535
532 // Verify compat -> classic switching. 536 // Verify force next -> compat switching.
533 global.backgroundObj.setMode('compat'); 537 localStorage['useNext'] = false;
538 fakeWebRoot.docUrl = 'chrome://foobar';
539 bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
540 assertEquals('compat', bk.mode);
541
542 // Compat -> classic.
534 fakeWebRoot.docUrl = 'http://google.com'; 543 fakeWebRoot.docUrl = 'http://google.com';
535 global.backgroundObj.refreshMode(fakeWebRoot); 544 bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
536 assertEquals('classic', global.backgroundObj.mode); 545 assertEquals('classic', bk.mode);
537 546
538 // Ensure we switch to compat if our current range has focused 547 // Ensure we switch to compat if our current range has focused
539 // state set and is not in web content. 548 // state set and is not in web content.
540 assertTrue(root.parent.state.focused); 549 assertTrue(root.parent.state.focused);
541 global.backgroundObj.setCurrentRange(cursors.Range.fromNode(root.parent)); 550 bk.setCurrentRange(cursors.Range.fromNode(root.parent));
542 global.backgroundObj.refreshMode(root.parent); 551 assertEquals('compat', bk.mode);
543 assertEquals('compat', global.backgroundObj.mode);
544 552
545 // And back to classic. 553 // And back to classic.
546 global.backgroundObj.setCurrentRange(cursors.Range.fromNode(root)); 554 bk.setCurrentRange(cursors.Range.fromNode(root));
547 global.backgroundObj.refreshMode(fakeWebRoot); 555 assertEquals('classic', bk.mode);
548 assertEquals('classic', global.backgroundObj.mode);
549 556
550 // Now, try refreshing mode (which we call after tab switching) with a range 557 // Now, verify mode switching uses the top level root.
551 // that's not actually focused.
552 assertEquals(undefined, root.parent.parent.state.focused);
553 global.backgroundObj.setCurrentRange(cursors.Range.fromNode(root.parent.pare nt));
554 global.backgroundObj.refreshMode(root.parent.parent);
555 assertEquals('classic', global.backgroundObj.mode);
556
557 // Now, verify mode refreshes uses the top level root.
558 fakeWebRoot.docUrl = 'http://google.com/#chromevox_next_test'; 558 fakeWebRoot.docUrl = 'http://google.com/#chromevox_next_test';
559 fakeSubRoot.docUrl = 'http://chromevox.com'; 559 fakeSubRoot.docUrl = 'http://chromevox.com';
560 global.backgroundObj.refreshMode(fakeSubRoot); 560 bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
561 assertEquals('next', global.backgroundObj.mode); 561 assertEquals('next', bk.mode);
562 }.bind(this)); 562 }.bind(this));
563 }); 563 });
564 564
565 TEST_F('BackgroundTest', 'FocusIframe', function() { 565 TEST_F('BackgroundTest', 'FocusIframe', function() {
566 this.runWithLoadedTree( function() {/*! 566 this.runWithLoadedTree( function() {/*!
567 <iframe tabindex=0 src="data:text/html,<p>Inside</p>"></iframe> 567 <iframe tabindex=0 src="data:text/html,<p>Inside</p>"></iframe>
568 <button>outside</button> 568 <button>outside</button>
569 */}, function(root) { 569 */}, function(root) {
570 var iframe = root.find({role: RoleType.iframe}); 570 var iframe = root.find({role: RoleType.iframe});
571 var button = root.find({role: RoleType.button}); 571 var button = root.find({role: RoleType.button});
572 572
573 assertEquals('iframe', iframe.role); 573 assertEquals('iframe', iframe.role);
574 assertEquals('button', button.role); 574 assertEquals('button', button.role);
575 575
576 var didFocus = false; 576 var didFocus = false;
577 iframe.focus = function() { 577 iframe.focus = function() {
578 didFocus = true; 578 didFocus = true;
579 }; 579 };
580 var b = global.backgroundObj; 580 var b = ChromeVoxState.instance;
581 b.currentRange_ = cursors.Range.fromNode(button); 581 b.currentRange_ = cursors.Range.fromNode(button);
582 b.onGotCommand('previousElement'); 582 b.onGotCommand('previousElement');
583 assertFalse(didFocus); 583 assertFalse(didFocus);
584 }.bind(this)); 584 }.bind(this));
585 }); 585 });
586 586
587 TEST_F('BackgroundTest', 'NoisySlider', function() { 587 TEST_F('BackgroundTest', 'NoisySlider', function() {
588 var mockFeedback = this.createMockFeedback(); 588 var mockFeedback = this.createMockFeedback();
589 this.runWithLoadedTree( function() {/*! 589 this.runWithLoadedTree( function() {/*!
590 <button id="go">go</button> 590 <button id="go">go</button>
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 if (isChecked) 622 if (isChecked)
623 go.setAttribute('aria-checked', true); 623 go.setAttribute('aria-checked', true);
624 else 624 else
625 go.removeAttribute('aria-checked'); 625 go.removeAttribute('aria-checked');
626 isChecked = !isChecked; 626 isChecked = !isChecked;
627 }); 627 });
628 </script> 628 </script>
629 */}, function(root) { 629 */}, function(root) {
630 var cbx = root.find({role: RoleType.checkBox}); 630 var cbx = root.find({role: RoleType.checkBox});
631 var click = cbx.doDefault.bind(cbx); 631 var click = cbx.doDefault.bind(cbx);
632 mockFeedback.call(click) 632 var focus = cbx.focus.bind(cbx);
633 mockFeedback.call(focus)
634 .expectSpeech('go')
635 .expectSpeech('Check box')
636 .expectSpeech('not checked')
637 .call(click)
633 .expectSpeech('go') 638 .expectSpeech('go')
634 .expectSpeech('Check box') 639 .expectSpeech('Check box')
635 .expectSpeech('checked') 640 .expectSpeech('checked')
636 .call(click) 641 .call(click)
637 .expectSpeech('go') 642 .expectSpeech('go')
638 .expectSpeech('Check box') 643 .expectSpeech('Check box')
639 .expectSpeech('not checked') 644 .expectSpeech('not checked')
640 .replay(); 645 .replay();
641 }); 646 });
642 }); 647 });
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 }); 758 });
754 }); 759 });
755 760
756 TEST_F('BackgroundTest', 'ToggleButton', function() { 761 TEST_F('BackgroundTest', 'ToggleButton', function() {
757 var mockFeedback = this.createMockFeedback(); 762 var mockFeedback = this.createMockFeedback();
758 this.runWithLoadedTree(function() {/*! 763 this.runWithLoadedTree(function() {/*!
759 <div aria-pressed="true" role="button">ok</div> 764 <div aria-pressed="true" role="button">ok</div>
760 <div aria-pressed="false" role="button">cancel</div> 765 <div aria-pressed="false" role="button">cancel</div>
761 <div aria-pressed role="button">close</div> 766 <div aria-pressed role="button">close</div>
762 */}, function(root) { 767 */}, function(root) {
763 var b = global.backgroundObj; 768 var b = ChromeVoxState.instance;
764 var move = b.onGotCommand.bind(b, 'nextObject'); 769 var move = b.onGotCommand.bind(b, 'nextObject');
765 mockFeedback.call(move) 770 mockFeedback.call(move)
766 .expectSpeech('ok') 771 .expectSpeech('ok')
767 .expectSpeech('Button') 772 .expectSpeech('Button')
768 .expectSpeech('Pressed') 773 .expectSpeech('Pressed')
769 774
770 .call(move) 775 .call(move)
771 .expectSpeech('cancel') 776 .expectSpeech('cancel')
772 .expectSpeech('Button') 777 .expectSpeech('Button')
773 .expectSpeech('Not pressed') 778 .expectSpeech('Not pressed')
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 */}, function(root) { 928 */}, function(root) {
924 mockFeedback.call(doCmd('nextHeading')) 929 mockFeedback.call(doCmd('nextHeading'))
925 .expectNextSpeechUtteranceIsNot('NE') 930 .expectNextSpeechUtteranceIsNot('NE')
926 .expectSpeech('NW') 931 .expectSpeech('NW')
927 .call(doCmd('previousHeading')) 932 .call(doCmd('previousHeading'))
928 .expectNextSpeechUtteranceIsNot('NE') 933 .expectNextSpeechUtteranceIsNot('NE')
929 .expectSpeech('NW') 934 .expectSpeech('NW')
930 .replay(); 935 .replay();
931 }); 936 });
932 }); 937 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698