| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** @fileoverview Suite of tests for media-router-container. */ | |
| 6 cr.define('media_router_container', function() { | |
| 7 function registerTests() { | |
| 8 suite('MediaRouterContainer', function() { | |
| 9 /** | |
| 10 * Media Router Container created before each test. | |
| 11 * @type {MediaRouterContainer} | |
| 12 */ | |
| 13 var container; | |
| 14 | |
| 15 /** | |
| 16 * The blocking issue to show. | |
| 17 * @type {?media_router.Issue} | |
| 18 */ | |
| 19 var fakeBlockingIssue; | |
| 20 | |
| 21 /** | |
| 22 * The list of CastModes to show. | |
| 23 * @type {!Array<!media_router.CastMode>} | |
| 24 */ | |
| 25 var fakeCastModeList = []; | |
| 26 | |
| 27 /** | |
| 28 * The list of CastModes to show with non-default modes only. | |
| 29 * @type {!Array<!media_router.CastMode>} | |
| 30 */ | |
| 31 var fakeCastModeListWithNonDefaultModesOnly = []; | |
| 32 | |
| 33 /** | |
| 34 * The blocking issue to show. | |
| 35 * @type {?media_router.Issue} | |
| 36 */ | |
| 37 var fakeNonBlockingIssue; | |
| 38 | |
| 39 /** | |
| 40 * The list of current routes. | |
| 41 * @type {!Array<!media_router.Route>} | |
| 42 */ | |
| 43 var fakeRouteList = []; | |
| 44 | |
| 45 /** | |
| 46 * The list of available sinks. | |
| 47 * @type {!Array<!media_router.Sink>} | |
| 48 */ | |
| 49 var fakeSinkList = []; | |
| 50 | |
| 51 /** | |
| 52 * The list of elements to check for visibility. | |
| 53 * @const {!Array<string>} | |
| 54 */ | |
| 55 var hiddenCheckElementIdList = [ | |
| 56 'cast-mode-list', | |
| 57 'container-header', | |
| 58 'device-missing', | |
| 59 'first-run-flow', | |
| 60 'first-run-flow-cloud-pref', | |
| 61 'issue-banner', | |
| 62 'no-search-matches', | |
| 63 'route-details', | |
| 64 'search-results', | |
| 65 'sink-list', | |
| 66 'sink-list-view', | |
| 67 ]; | |
| 68 | |
| 69 // Checks whether |view| matches the current view of |container|. | |
| 70 var checkCurrentView = function(view) { | |
| 71 assertEquals(view, container.currentView_); | |
| 72 }; | |
| 73 | |
| 74 // Checks whether the elements specified in |elementIdList| are visible. | |
| 75 // Checks whether all other elements are not visible. | |
| 76 var checkElementsVisibleWithId = function(elementIdList) { | |
| 77 for (var i = 0; i < elementIdList.length; i++) | |
| 78 checkElementVisibleWithId(true, elementIdList[i]); | |
| 79 | |
| 80 for (var j = 0; j < hiddenCheckElementIdList.length; j++) { | |
| 81 if (elementIdList.indexOf(hiddenCheckElementIdList[j]) == -1) | |
| 82 checkElementVisibleWithId(false, hiddenCheckElementIdList[j]); | |
| 83 } | |
| 84 }; | |
| 85 | |
| 86 // Checks the visibility of an element with |elementId| in |container|. | |
| 87 // An element is considered visible if it exists and its |hidden| property | |
| 88 // is |false|. | |
| 89 var checkElementVisibleWithId = function(visible, elementId) { | |
| 90 var element = container.$$('#' + elementId); | |
| 91 var elementVisible = !!element && !element.hidden && | |
| 92 element.style.display != 'none'; | |
| 93 assertEquals(visible, elementVisible, elementId); | |
| 94 }; | |
| 95 | |
| 96 // Checks whether |expected| and the text in the |element| are equal. | |
| 97 var checkElementText = function(expected, element) { | |
| 98 assertEquals(expected.trim(), element.textContent.trim()); | |
| 99 }; | |
| 100 | |
| 101 // Checks whether |expected| and the |property| in |container| are equal. | |
| 102 var checkPropertyValue = function(expected, property) { | |
| 103 assertEquals(expected.trim(), container.property); | |
| 104 } | |
| 105 | |
| 106 // Import media_router_container.html before running suite. | |
| 107 suiteSetup(function() { | |
| 108 return PolymerTest.importHtml( | |
| 109 'chrome://media-router/elements/media_router_container/' + | |
| 110 'media_router_container.html'); | |
| 111 }); | |
| 112 | |
| 113 // Initialize a media-router-container before each test. | |
| 114 setup(function(done) { | |
| 115 PolymerTest.clearBody(); | |
| 116 container = document.createElement('media-router-container'); | |
| 117 document.body.appendChild(container); | |
| 118 | |
| 119 // Initialize local variables. | |
| 120 fakeCastModeList = [ | |
| 121 new media_router.CastMode(0x1, 'Description 0', 'google.com'), | |
| 122 new media_router.CastMode(0x2, 'Description 1', null), | |
| 123 new media_router.CastMode(0x4, 'Description 2', null), | |
| 124 ]; | |
| 125 | |
| 126 fakeCastModeListWithNonDefaultModesOnly = [ | |
| 127 new media_router.CastMode(0x2, 'Description 1', null), | |
| 128 new media_router.CastMode(0x4, 'Description 2', null), | |
| 129 new media_router.CastMode(0x8, 'Description 3', null), | |
| 130 ]; | |
| 131 | |
| 132 fakeRouteList = [ | |
| 133 new media_router.Route('id 1', 'sink id 1', | |
| 134 'Title 1', 0, true, false), | |
| 135 new media_router.Route('id 2', 'sink id 2', | |
| 136 'Title 2', 1, false, true), | |
| 137 ]; | |
| 138 | |
| 139 fakeRouteListWithLocalRoutesOnly = [ | |
| 140 new media_router.Route('id 1', 'sink id 1', | |
| 141 'Title 1', 0, true, false), | |
| 142 new media_router.Route('id 2', 'sink id 2', | |
| 143 'Title 2', 1, true, false), | |
| 144 ]; | |
| 145 | |
| 146 var castModeBitset = 0x2 | 0x4 | 0x8; | |
| 147 fakeSinkList = [ | |
| 148 new media_router.Sink('sink id 1', 'Sink 1', null, null, | |
| 149 media_router.SinkIconType.CAST, | |
| 150 media_router.SinkStatus.ACTIVE, castModeBitset), | |
| 151 new media_router.Sink('sink id 2', 'Sink 2', null, null, | |
| 152 media_router.SinkIconType.CAST, | |
| 153 media_router.SinkStatus.ACTIVE, castModeBitset), | |
| 154 new media_router.Sink('sink id 3', 'Sink 3', null, null, | |
| 155 media_router.SinkIconType.CAST, | |
| 156 media_router.SinkStatus.PENDING, castModeBitset), | |
| 157 ]; | |
| 158 | |
| 159 searchTextAll = 'sink'; | |
| 160 searchTextNone = 'abc'; | |
| 161 searchTextOne = 'sink 1'; | |
| 162 | |
| 163 fakeBlockingIssue = new media_router.Issue( | |
| 164 'issue id 1', 'Issue Title 1', 'Issue Message 1', 0, 1, | |
| 165 'route id 1', true, 1234); | |
| 166 | |
| 167 fakeNonBlockingIssue = new media_router.Issue( | |
| 168 'issue id 2', 'Issue Title 2', 'Issue Message 2', 0, 1, | |
| 169 'route id 2', false, 1234); | |
| 170 | |
| 171 container.castModeList = fakeCastModeList; | |
| 172 | |
| 173 // Allow for the media router container to be created and attached. | |
| 174 setTimeout(done); | |
| 175 }); | |
| 176 | |
| 177 // Tests for 'acknowledge-first-run-flow' event firing when the | |
| 178 // 'first-run-button' button is clicked and the cloud preference checkbox | |
| 179 // is not shown. | |
| 180 test('first run button click', function(done) { | |
| 181 container.showFirstRunFlow = true; | |
| 182 | |
| 183 setTimeout(function() { | |
| 184 container.addEventListener('acknowledge-first-run-flow', | |
| 185 function(data) { | |
| 186 assertEquals(undefined, data.detail.optedIntoCloudServices); | |
| 187 done(); | |
| 188 }); | |
| 189 MockInteractions.tap(container.shadowRoot.getElementById( | |
| 190 'first-run-button')); | |
| 191 }); | |
| 192 }); | |
| 193 | |
| 194 // Tests for 'acknowledge-first-run-flow' event firing when the | |
| 195 // 'first-run-button' button is clicked and the cloud preference checkbox | |
| 196 // is also shown. | |
| 197 test('first run button with cloud pref click', function(done) { | |
| 198 container.showFirstRunFlow = true; | |
| 199 container.showFirstRunFlowCloudPref = true; | |
| 200 | |
| 201 setTimeout(function() { | |
| 202 container.addEventListener('acknowledge-first-run-flow', | |
| 203 function(data) { | |
| 204 assertTrue(data.detail.optedIntoCloudServices); | |
| 205 done(); | |
| 206 }); | |
| 207 MockInteractions.tap(container.shadowRoot.getElementById( | |
| 208 'first-run-button')); | |
| 209 }); | |
| 210 }); | |
| 211 | |
| 212 // Tests for 'acknowledge-first-run-flow' event firing when the | |
| 213 // 'first-run-button' button is clicked after the cloud preference | |
| 214 // checkbox is deselected. | |
| 215 test('first run button with cloud pref deselected click', | |
| 216 function(done) { | |
| 217 container.showFirstRunFlow = true; | |
| 218 container.showFirstRunFlowCloudPref = true; | |
| 219 | |
| 220 setTimeout(function() { | |
| 221 container.addEventListener('acknowledge-first-run-flow', | |
| 222 function(data) { | |
| 223 assertFalse(data.detail.optedIntoCloudServices); | |
| 224 done(); | |
| 225 }); | |
| 226 MockInteractions.tap(container.shadowRoot.getElementById( | |
| 227 'first-run-cloud-checkbox')); | |
| 228 MockInteractions.tap(container.shadowRoot.getElementById( | |
| 229 'first-run-button')); | |
| 230 }); | |
| 231 }); | |
| 232 | |
| 233 // Tests for 'create-route' event firing when a sink with no associated | |
| 234 // route is clicked. | |
| 235 test('select sink without a route', function(done) { | |
| 236 container.allSinks = fakeSinkList; | |
| 237 | |
| 238 setTimeout(function() { | |
| 239 var sinkList = | |
| 240 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 241 container.addEventListener('create-route', function(data) { | |
| 242 // Container is initially in auto mode since a cast mode has not | |
| 243 // been selected. | |
| 244 assertEquals(media_router.CastModeType.AUTO, | |
| 245 container.shownCastModeValue_); | |
| 246 assertEquals(fakeSinkList[2].id, data.detail.sinkId); | |
| 247 | |
| 248 // The preferred compatible cast mode on the sink is used, since | |
| 249 // the we did not choose a cast mode on the container. | |
| 250 assertEquals(0x2, data.detail.selectedCastModeValue); | |
| 251 done(); | |
| 252 }); | |
| 253 // Tap on a sink without a route, which should fire a 'create-route' | |
| 254 // event. | |
| 255 assertEquals(fakeSinkList.length, sinkList.length); | |
| 256 MockInteractions.tap(sinkList[2]); | |
| 257 }); | |
| 258 }); | |
| 259 | |
| 260 // Tests that selecting a sink with an associated route will make the | |
| 261 // |container| switch to ROUTE_DETAILS view. | |
| 262 test('select sink with a route', function(done) { | |
| 263 container.allSinks = fakeSinkList; | |
| 264 container.routeList = fakeRouteList; | |
| 265 | |
| 266 setTimeout(function() { | |
| 267 var sinkList = | |
| 268 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 269 | |
| 270 // Start from the SINK_LIST view. | |
| 271 container.showSinkList_(); | |
| 272 checkCurrentView(media_router.MediaRouterView.SINK_LIST); | |
| 273 MockInteractions.tap(sinkList[0]); | |
| 274 checkCurrentView(media_router.MediaRouterView.ROUTE_DETAILS); | |
| 275 done(); | |
| 276 }); | |
| 277 }); | |
| 278 | |
| 279 // Tests that |container| returns to SINK_LIST view and arrow drop icon | |
| 280 // toggles after a cast mode is selected. | |
| 281 test('select cast mode', function(done) { | |
| 282 container.castModeList = fakeCastModeListWithNonDefaultModesOnly; | |
| 283 | |
| 284 MockInteractions.tap(container.$['container-header']. | |
| 285 $['arrow-drop-icon']); | |
| 286 checkCurrentView(media_router.MediaRouterView.CAST_MODE_LIST); | |
| 287 | |
| 288 setTimeout(function() { | |
| 289 var castModeList = | |
| 290 container.$$('#cast-mode-list').querySelectorAll('paper-item'); | |
| 291 | |
| 292 MockInteractions.tap(castModeList[2]); | |
| 293 checkCurrentView(media_router.MediaRouterView.SINK_LIST); | |
| 294 done(); | |
| 295 }); | |
| 296 }); | |
| 297 | |
| 298 // Tests that clicking on the drop down icon will toggle |container| | |
| 299 // between SINK_LIST and CAST_MODE_LIST views. | |
| 300 test('click drop down icon', function() { | |
| 301 checkCurrentView(media_router.MediaRouterView.SINK_LIST); | |
| 302 | |
| 303 MockInteractions.tap(container.$['container-header']. | |
| 304 $['arrow-drop-icon']); | |
| 305 checkCurrentView(media_router.MediaRouterView.CAST_MODE_LIST); | |
| 306 | |
| 307 MockInteractions.tap(container.$['container-header']. | |
| 308 $['arrow-drop-icon']); | |
| 309 checkCurrentView(media_router.MediaRouterView.SINK_LIST); | |
| 310 }); | |
| 311 | |
| 312 // Tests the header text. Choosing a cast mode updates the header text. | |
| 313 test('header text with no default cast modes', function(done) { | |
| 314 assertEquals(loadTimeData.getString('selectCastModeHeader'), | |
| 315 container.selectCastModeHeaderText_); | |
| 316 | |
| 317 // The container is currently in auto cast mode, since we have not | |
| 318 // picked a cast mode explicitly, and the sinks is not compatible | |
| 319 // with exactly one cast mode. | |
| 320 assertEquals(media_router.AUTO_CAST_MODE.description, | |
| 321 container.headerText); | |
| 322 assertFalse(container.userHasSelectedCastMode_); | |
| 323 | |
| 324 container.castModeList = fakeCastModeListWithNonDefaultModesOnly; | |
| 325 | |
| 326 // Switch to cast mode list view. | |
| 327 MockInteractions.tap(container.$['container-header']. | |
| 328 $['arrow-drop-icon']); | |
| 329 setTimeout(function() { | |
| 330 var castModeList = | |
| 331 container.$$('#cast-mode-list').querySelectorAll('paper-item'); | |
| 332 assertEquals(fakeCastModeListWithNonDefaultModesOnly.length, | |
| 333 castModeList.length); | |
| 334 for (var i = 0; i < castModeList.length; i++) { | |
| 335 MockInteractions.tap(castModeList[i]); | |
| 336 assertEquals( | |
| 337 fakeCastModeListWithNonDefaultModesOnly[i].description, | |
| 338 container.headerText); | |
| 339 checkElementText( | |
| 340 fakeCastModeListWithNonDefaultModesOnly[i].description, | |
| 341 castModeList[i]); | |
| 342 } | |
| 343 | |
| 344 done(); | |
| 345 }); | |
| 346 }); | |
| 347 | |
| 348 // Tests the header text when updated with a cast mode list with a mix of | |
| 349 // default and non-default cast modes. | |
| 350 test('cast modes with one default mode', function(done) { | |
| 351 container.castModeList = fakeCastModeList; | |
| 352 | |
| 353 // Switch to cast mode list view. | |
| 354 MockInteractions.tap(container.$['container-header']. | |
| 355 $['arrow-drop-icon']); | |
| 356 setTimeout(function() { | |
| 357 var castModeList = | |
| 358 container.$$('#cast-mode-list').querySelectorAll('paper-item'); | |
| 359 | |
| 360 for (var i = 0; i < fakeCastModeList.length; i++) { | |
| 361 MockInteractions.tap(castModeList[i]); | |
| 362 if (fakeCastModeList[i].type == | |
| 363 media_router.CastModeType.DEFAULT) { | |
| 364 assertEquals(fakeCastModeList[i].description, | |
| 365 container.headerText); | |
| 366 | |
| 367 checkElementText(fakeCastModeList[i].host, castModeList[i]); | |
| 368 } else { | |
| 369 assertEquals(fakeCastModeList[i].description, | |
| 370 container.headerText); | |
| 371 checkElementText(fakeCastModeList[i].description, | |
| 372 castModeList[i]); | |
| 373 } | |
| 374 } | |
| 375 | |
| 376 done(); | |
| 377 }); | |
| 378 }); | |
| 379 | |
| 380 // Tests that text shown for each sink matches their names. | |
| 381 test('sink list text', function(done) { | |
| 382 container.allSinks = fakeSinkList; | |
| 383 | |
| 384 setTimeout(function() { | |
| 385 var sinkList = | |
| 386 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 387 assertEquals(fakeSinkList.length, sinkList.length); | |
| 388 for (var i = 0; i < fakeSinkList.length; i++) { | |
| 389 checkElementText(fakeSinkList[i].name, sinkList[i]); | |
| 390 } | |
| 391 done(); | |
| 392 }); | |
| 393 }); | |
| 394 | |
| 395 // Tests that text shown for sink with domain matches the name and domain. | |
| 396 test('sink with domain text', function(done) { | |
| 397 // Sink 1 - sink, no domain -> text = name | |
| 398 // Sink 2 - sink, domain -> text = sink + domain | |
| 399 container.allSinks = [ | |
| 400 new media_router.Sink('sink id 1', 'Sink 1', null, null, | |
| 401 media_router.SinkIconType.HANGOUT, | |
| 402 media_router.SinkStatus.ACTIVE, [1, 2, 3]), | |
| 403 new media_router.Sink('sink id 2', 'Sink 2', | |
| 404 null, 'example.com', | |
| 405 media_router.SinkIconType.HANGOUT, | |
| 406 media_router.SinkStatus.ACTIVE, [1, 2, 3]), | |
| 407 ]; | |
| 408 | |
| 409 container.showDomain = true; | |
| 410 | |
| 411 setTimeout(function() { | |
| 412 var sinkList = | |
| 413 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 414 assertEquals(2, sinkList.length); | |
| 415 | |
| 416 // |sinkList[0]| has sink name only. | |
| 417 checkElementText(container.allSinks[0].name, sinkList[0]); | |
| 418 // |sinkList[1]| contains sink name and domain. | |
| 419 assertTrue(sinkList[1].textContent.trim().startsWith( | |
| 420 container.allSinks[1].name.trim())); | |
| 421 assertTrue(sinkList[1].textContent.trim().indexOf( | |
| 422 container.allSinks[1].domain.trim()) != -1); | |
| 423 done(); | |
| 424 }); | |
| 425 }); | |
| 426 | |
| 427 // Tests that domain text is not shown when |showDomain| is false. | |
| 428 test('sink with domain text', function(done) { | |
| 429 // Sink 1 - sink, no domain -> text = name | |
| 430 // Sink 2 - sink, domain -> text = sink + domain | |
| 431 container.allSinks = [ | |
| 432 new media_router.Sink('sink id 1', 'Sink 1', null, null, | |
| 433 media_router.SinkIconType.HANGOUT, | |
| 434 media_router.SinkStatus.ACTIVE, [1, 2, 3]), | |
| 435 new media_router.Sink('sink id 2', 'Sink 2', | |
| 436 null, 'example.com', | |
| 437 media_router.SinkIconType.HANGOUT, | |
| 438 media_router.SinkStatus.ACTIVE, [1, 2, 3]), | |
| 439 ]; | |
| 440 | |
| 441 container.showDomain = false; | |
| 442 | |
| 443 setTimeout(function() { | |
| 444 var sinkList = | |
| 445 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 446 assertEquals(2, sinkList.length); | |
| 447 | |
| 448 // |sinkList[0]| has sink name only. | |
| 449 checkElementText(container.allSinks[0].name, sinkList[0]); | |
| 450 // |sinkList[1]| has sink name but domain should be hidden. | |
| 451 checkElementText(container.allSinks[1].name, sinkList[1]); | |
| 452 assertTrue(sinkList[1].textContent.trim().indexOf( | |
| 453 container.allSinks[1].domain.trim()) == -1); | |
| 454 done(); | |
| 455 }); | |
| 456 }); | |
| 457 | |
| 458 // Tests the text shown for the sink list. | |
| 459 test('initial sink list route text', function(done) { | |
| 460 // Sink 1 - no sink description, no route -> no subtext | |
| 461 // Sink 2 - sink description, no route -> subtext = sink description | |
| 462 // Sink 3 - no sink description, route -> subtext = route description | |
| 463 // Sink 4 - sink description, route -> subtext = route description | |
| 464 container.allSinks = [ | |
| 465 new media_router.Sink('sink id 1', 'Sink 1', null, null, | |
| 466 media_router.SinkIconType.CAST, | |
| 467 media_router.SinkStatus.ACTIVE, [1, 2, 3]), | |
| 468 new media_router.Sink('sink id 2', 'Sink 2', | |
| 469 'Sink 2 description', null, | |
| 470 media_router.SinkIconType.CAST, | |
| 471 media_router.SinkStatus.ACTIVE, [1, 2, 3]), | |
| 472 new media_router.Sink('sink id 3', 'Sink 3', null, null, | |
| 473 media_router.SinkIconType.CAST, | |
| 474 media_router.SinkStatus.PENDING, [1, 2, 3]), | |
| 475 new media_router.Sink('sink id 4', 'Sink 4', | |
| 476 'Sink 4 description', null, | |
| 477 media_router.SinkIconType.CAST, | |
| 478 media_router.SinkStatus.PENDING, [1, 2, 3]) | |
| 479 ]; | |
| 480 | |
| 481 container.routeList = [ | |
| 482 new media_router.Route('id 3', 'sink id 3', 'Title 3', 0, true), | |
| 483 new media_router.Route('id 4', 'sink id 4', 'Title 4', 1, false), | |
| 484 ]; | |
| 485 | |
| 486 setTimeout(function() { | |
| 487 var sinkSubtextList = | |
| 488 container.$['sink-list'].querySelectorAll('.sink-subtext'); | |
| 489 | |
| 490 // There will only be 3 sink subtext entries, because Sink 1 does not | |
| 491 // have any subtext. | |
| 492 assertEquals(3, sinkSubtextList.length); | |
| 493 | |
| 494 checkElementText(container.allSinks[1].description, | |
| 495 sinkSubtextList[0]); | |
| 496 | |
| 497 // Route description overrides sink description for subtext. | |
| 498 checkElementText(container.routeList[0].description, | |
| 499 sinkSubtextList[1]); | |
| 500 | |
| 501 checkElementText(container.routeList[1].description, | |
| 502 sinkSubtextList[2]); | |
| 503 done(); | |
| 504 }); | |
| 505 }); | |
| 506 | |
| 507 // Tests the expected view when there is only one local active route and | |
| 508 // media_router_container is created for the first time. | |
| 509 test('initial view with one local route', function() { | |
| 510 container.allSinks = fakeSinkList; | |
| 511 container.routeList = fakeRouteList; | |
| 512 container.maybeShowRouteDetailsOnOpen(); | |
| 513 | |
| 514 checkCurrentView(media_router.MediaRouterView.ROUTE_DETAILS); | |
| 515 }); | |
| 516 | |
| 517 // Tests the expected view when there are multiple local active routes | |
| 518 // and media_router_container is created for the first time. | |
| 519 test('initial view with multiple local routes', function() { | |
| 520 container.allSinks = fakeSinkList; | |
| 521 container.routeList = fakeRouteListWithLocalRoutesOnly; | |
| 522 | |
| 523 checkCurrentView(media_router.MediaRouterView.SINK_LIST); | |
| 524 }); | |
| 525 | |
| 526 // Tests the expected view when there are no local active routes and | |
| 527 // media_router_container is created for the first time. | |
| 528 test('initial view with no local route', function() { | |
| 529 container.allSinks = fakeSinkList; | |
| 530 container.routeList = []; | |
| 531 | |
| 532 checkCurrentView(media_router.MediaRouterView.SINK_LIST); | |
| 533 }); | |
| 534 | |
| 535 // Tests the expected view when there are no local active routes and | |
| 536 // media_router_container is created for the first time. | |
| 537 test('view after route is closed remotely', function() { | |
| 538 container.allSinks = fakeSinkList; | |
| 539 container.routeList = fakeRouteList; | |
| 540 container.maybeShowRouteDetailsOnOpen(); | |
| 541 checkCurrentView(media_router.MediaRouterView.ROUTE_DETAILS); | |
| 542 | |
| 543 container.routeList = []; | |
| 544 checkCurrentView(media_router.MediaRouterView.SINK_LIST); | |
| 545 }); | |
| 546 | |
| 547 // Tests for expected visible UI when the view is CAST_MODE_LIST. | |
| 548 test('cast mode list state visibility', function(done) { | |
| 549 container.showCastModeList_(); | |
| 550 setTimeout(function() { | |
| 551 checkElementsVisibleWithId(['cast-mode-list', | |
| 552 'container-header', | |
| 553 'device-missing']); | |
| 554 | |
| 555 // Set a non-blocking issue. The issue should stay hidden. | |
| 556 container.issue = fakeNonBlockingIssue; | |
| 557 setTimeout(function() { | |
| 558 checkElementsVisibleWithId(['cast-mode-list', | |
| 559 'container-header', | |
| 560 'device-missing']); | |
| 561 | |
| 562 // Set a blocking issue. The issue should stay hidden. | |
| 563 container.issue = fakeBlockingIssue; | |
| 564 setTimeout(function() { | |
| 565 checkElementsVisibleWithId(['container-header', | |
| 566 'device-missing', | |
| 567 'issue-banner']); | |
| 568 done(); | |
| 569 }); | |
| 570 }); | |
| 571 }); | |
| 572 }); | |
| 573 | |
| 574 // Tests for the expected visible UI when interacting with the first run | |
| 575 // flow. | |
| 576 test('first run button visibility', function(done) { | |
| 577 container.showFirstRunFlow = true; | |
| 578 | |
| 579 setTimeout(function() { | |
| 580 checkElementVisibleWithId(true, 'first-run-flow'); | |
| 581 MockInteractions.tap(container.shadowRoot.getElementById( | |
| 582 'first-run-button')); | |
| 583 | |
| 584 setTimeout(function() { | |
| 585 checkElementVisibleWithId(false, 'first-run-flow'); | |
| 586 done(); | |
| 587 }); | |
| 588 }); | |
| 589 }); | |
| 590 | |
| 591 // Tests for the expected visible UI when interacting with the first run | |
| 592 // flow with cloud services preference. | |
| 593 test('first run button visibility', function(done) { | |
| 594 container.showFirstRunFlow = true; | |
| 595 container.showFirstRunFlowCloudPref = true; | |
| 596 | |
| 597 setTimeout(function() { | |
| 598 checkElementsVisibleWithId(['container-header', | |
| 599 'device-missing', | |
| 600 'first-run-flow', | |
| 601 'first-run-flow-cloud-pref', | |
| 602 'sink-list-view']); | |
| 603 MockInteractions.tap(container.shadowRoot.getElementById( | |
| 604 'first-run-button')); | |
| 605 | |
| 606 setTimeout(function() { | |
| 607 checkElementsVisibleWithId(['container-header', | |
| 608 'device-missing', | |
| 609 'sink-list-view']); | |
| 610 done(); | |
| 611 }); | |
| 612 }); | |
| 613 }); | |
| 614 | |
| 615 // Tests for expected visible UI when the view is ROUTE_DETAILS. | |
| 616 test('route details visibility', function(done) { | |
| 617 container.showRouteDetails_(); | |
| 618 setTimeout(function() { | |
| 619 checkElementsVisibleWithId(['container-header', | |
| 620 'device-missing', | |
| 621 'route-details']); | |
| 622 done(); | |
| 623 }); | |
| 624 }); | |
| 625 | |
| 626 test('updated route in route details', function(done) { | |
| 627 container.allSinks = fakeSinkList; | |
| 628 var description = 'Title'; | |
| 629 var route = new media_router.Route( | |
| 630 'id 1', 'sink id 1', description, 0, true, false); | |
| 631 container.routeList = [route]; | |
| 632 container.showRouteDetails_(route); | |
| 633 setTimeout(function() { | |
| 634 // Note that sink-list-view is hidden. | |
| 635 checkElementsVisibleWithId( | |
| 636 ['container-header', 'route-details', 'sink-list']); | |
| 637 assertTrue(!!container.currentRoute_); | |
| 638 assertEquals(description, container.currentRoute_.description); | |
| 639 | |
| 640 var newDescription = 'Foo'; | |
| 641 route.description = newDescription; | |
| 642 container.routeList = [route]; | |
| 643 setTimeout(function() { | |
| 644 // Note that sink-list-view is hidden. | |
| 645 checkElementsVisibleWithId( | |
| 646 ['container-header', 'route-details', 'sink-list']); | |
| 647 assertTrue(!!container.currentRoute_); | |
| 648 assertEquals(newDescription, container.currentRoute_.description); | |
| 649 done(); | |
| 650 }); | |
| 651 }); | |
| 652 }); | |
| 653 | |
| 654 // Tests for expected visible UI when the view is ROUTE_DETAILS, and there | |
| 655 // is a non-blocking issue. | |
| 656 test('route details visibility non blocking issue', function(done) { | |
| 657 container.showRouteDetails_(); | |
| 658 | |
| 659 // Set a non-blocking issue. The issue should be shown. | |
| 660 container.issue = fakeNonBlockingIssue; | |
| 661 setTimeout(function() { | |
| 662 checkElementsVisibleWithId(['container-header', | |
| 663 'device-missing', | |
| 664 'route-details']); | |
| 665 done(); | |
| 666 }); | |
| 667 }); | |
| 668 | |
| 669 // Tests for expected visible UI when the view is ROUTE_DETAILS, and there | |
| 670 // is a blocking issue. | |
| 671 test('route details visibility with blocking issue', function(done) { | |
| 672 container.showRouteDetails_(); | |
| 673 | |
| 674 // Set a blocking issue. The issue should be shown, and everything | |
| 675 // else, hidden. | |
| 676 container.issue = fakeBlockingIssue; | |
| 677 setTimeout(function() { | |
| 678 checkElementsVisibleWithId(['container-header', | |
| 679 'device-missing', | |
| 680 'issue-banner']); | |
| 681 done(); | |
| 682 }); | |
| 683 }); | |
| 684 | |
| 685 // Tests for expected visible UI when the view is SINK_LIST. | |
| 686 test('sink list state visibility', function() { | |
| 687 container.showSinkList_(); | |
| 688 checkElementsVisibleWithId(['container-header', | |
| 689 'device-missing', | |
| 690 'sink-list-view']); | |
| 691 | |
| 692 // Set an non-empty sink list. | |
| 693 container.allSinks = fakeSinkList; | |
| 694 checkElementsVisibleWithId(['container-header', | |
| 695 'sink-list', | |
| 696 'sink-list-view']); | |
| 697 }); | |
| 698 | |
| 699 // Tests for expected visible UI when the view is SINK_LIST, and there is | |
| 700 // a non blocking issue. | |
| 701 test('sink list visibility non blocking issue', function(done) { | |
| 702 container.showSinkList_(); | |
| 703 | |
| 704 // Set an non-empty sink list. | |
| 705 container.allSinks = fakeSinkList; | |
| 706 | |
| 707 // Set a non-blocking issue. The issue should be shown. | |
| 708 container.issue = fakeNonBlockingIssue; | |
| 709 setTimeout(function() { | |
| 710 checkElementsVisibleWithId(['container-header', | |
| 711 'issue-banner', | |
| 712 'sink-list', | |
| 713 'sink-list-view']); | |
| 714 done(); | |
| 715 }); | |
| 716 }); | |
| 717 | |
| 718 // Tests for expected visible UI when the view is SINK_LIST, and there is | |
| 719 // a blocking issue. | |
| 720 test('sink list visibility blocking issue', function(done) { | |
| 721 container.showSinkList_(); | |
| 722 | |
| 723 // Set an non-empty sink list. | |
| 724 container.allSinks = fakeSinkList; | |
| 725 | |
| 726 // Set a blocking issue. The issue should be shown, and everything | |
| 727 // else, hidden. | |
| 728 container.issue = fakeBlockingIssue; | |
| 729 setTimeout(function() { | |
| 730 checkElementsVisibleWithId(['container-header', | |
| 731 'issue-banner', | |
| 732 'sink-list']); | |
| 733 done(); | |
| 734 }); | |
| 735 }); | |
| 736 | |
| 737 // Tests all sinks are always shown in auto mode, and that the mode will | |
| 738 // switch if the sinks support only 1 case mode. | |
| 739 test('sink list in auto mode', function(done) { | |
| 740 container.allSinks = fakeSinkList; | |
| 741 setTimeout(function() { | |
| 742 // Container is initially in auto mode since a cast mode has not been | |
| 743 // selected. | |
| 744 assertEquals(media_router.AUTO_CAST_MODE.description, | |
| 745 container.headerText); | |
| 746 assertEquals(media_router.CastModeType.AUTO, | |
| 747 container.shownCastModeValue_); | |
| 748 assertFalse(container.userHasSelectedCastMode_); | |
| 749 var sinkList = | |
| 750 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 751 | |
| 752 // All sinks are shown in auto mode. | |
| 753 assertEquals(3, sinkList.length); | |
| 754 | |
| 755 // When sink list changes to only 1 compatible cast mode, the mode is | |
| 756 // switched, and all sinks are shown. | |
| 757 container.allSinks = [ | |
| 758 new media_router.Sink('sink id 10', 'Sink 10', null, null, | |
| 759 media_router.SinkIconType.CAST, | |
| 760 media_router.SinkStatus.ACTIVE, 0x4), | |
| 761 new media_router.Sink('sink id 20', 'Sink 20', null, null, | |
| 762 media_router.SinkIconType.CAST, | |
| 763 media_router.SinkStatus.ACTIVE, 0x4), | |
| 764 new media_router.Sink('sink id 30', 'Sink 30', null, null, | |
| 765 media_router.SinkIconType.CAST, | |
| 766 media_router.SinkStatus.PENDING, 0x4), | |
| 767 ]; | |
| 768 | |
| 769 setTimeout(function() { | |
| 770 assertEquals(fakeCastModeList[2].description, container.headerText); | |
| 771 assertEquals(fakeCastModeList[2].type, | |
| 772 container.shownCastModeValue_); | |
| 773 assertFalse(container.userHasSelectedCastMode_); | |
| 774 | |
| 775 var sinkList = | |
| 776 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 777 assertEquals(3, sinkList.length); | |
| 778 | |
| 779 // When compatible cast modes size is no longer exactly 1, switch | |
| 780 // back to auto mode, and all sinks are shown. | |
| 781 container.allSinks = fakeSinkList; | |
| 782 setTimeout(function() { | |
| 783 assertEquals(media_router.AUTO_CAST_MODE.description, | |
| 784 container.headerText); | |
| 785 assertEquals(media_router.CastModeType.AUTO, | |
| 786 container.shownCastModeValue_); | |
| 787 assertFalse(container.userHasSelectedCastMode_); | |
| 788 var sinkList = | |
| 789 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 790 | |
| 791 // All sinks are shown in auto mode. | |
| 792 assertEquals(3, sinkList.length); | |
| 793 | |
| 794 done(); | |
| 795 }); | |
| 796 }); | |
| 797 }); | |
| 798 }); | |
| 799 | |
| 800 // Tests that the sink list does not contain any sinks that are not | |
| 801 // compatible with the selected cast mode and are not associated with a | |
| 802 // route. | |
| 803 test('sink list in user selected cast mode', function(done) { | |
| 804 var newSinks = [ | |
| 805 new media_router.Sink('sink id 10', 'Sink 10', null, null, | |
| 806 media_router.SinkIconType.CAST, | |
| 807 media_router.SinkStatus.ACTIVE, 0x4 | 0x8), | |
| 808 new media_router.Sink('sink id 20', 'Sink 20', null, null, | |
| 809 media_router.SinkIconType.CAST, | |
| 810 media_router.SinkStatus.ACTIVE, 0x2 | 0x4 | 0x8), | |
| 811 new media_router.Sink('sink id 30', 'Sink 30', null, null, | |
| 812 media_router.SinkIconType.CAST, | |
| 813 media_router.SinkStatus.PENDING, 0x4 | 0x8), | |
| 814 ]; | |
| 815 | |
| 816 container.allSinks = newSinks; | |
| 817 container.routeList = [ | |
| 818 new media_router.Route('id 1', 'sink id 30', | |
| 819 'Title 1', 1, false, false), | |
| 820 ]; | |
| 821 | |
| 822 setTimeout(function() { | |
| 823 var sinkList = | |
| 824 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 825 | |
| 826 // Since we haven't selected a cast mode, we don't filter sinks. | |
| 827 assertEquals(3, sinkList.length); | |
| 828 | |
| 829 MockInteractions.tap(container.$['container-header']. | |
| 830 $['arrow-drop-icon']); | |
| 831 setTimeout(function() { | |
| 832 // Cast mode 1 is selected, and the sink list is filtered. | |
| 833 var castModeList = | |
| 834 container.$$('#cast-mode-list').querySelectorAll('paper-item'); | |
| 835 MockInteractions.tap(castModeList[1]); | |
| 836 assertEquals(fakeCastModeList[1].description, container.headerText); | |
| 837 assertEquals(fakeCastModeList[1].type, | |
| 838 container.shownCastModeValue_); | |
| 839 | |
| 840 setTimeout(function() { | |
| 841 var sinkList = | |
| 842 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 843 | |
| 844 // newSinks[0] got filtered out since it is not compatible with | |
| 845 // cast mode 1. | |
| 846 // 'Sink 20' should be on the list because it contains the | |
| 847 // selected cast mode. (sinkList[0] = newSinks[1]) | |
| 848 // 'Sink 30' should be on the list because it has a route. | |
| 849 // (sinkList[1] = newSinks[2]) | |
| 850 assertEquals(2, sinkList.length); | |
| 851 checkElementText(newSinks[1].name, sinkList[0]); | |
| 852 | |
| 853 // |sinkList[1]| contains route title in addition to sink name. | |
| 854 assertTrue(sinkList[1].textContent.trim().startsWith( | |
| 855 newSinks[2].name.trim())); | |
| 856 | |
| 857 // Cast mode is not switched back even if there are no sinks | |
| 858 // compatible with selected cast mode, because we explicitly | |
| 859 // selected that cast mode. | |
| 860 container.allSinks = []; | |
| 861 setTimeout(function() { | |
| 862 assertEquals(fakeCastModeList[1].description, | |
| 863 container.headerText); | |
| 864 assertEquals(fakeCastModeList[1].type, | |
| 865 container.shownCastModeValue_); | |
| 866 var sinkList = | |
| 867 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 868 assertEquals(0, sinkList.length); | |
| 869 done(); | |
| 870 }); | |
| 871 }); | |
| 872 }); | |
| 873 }); | |
| 874 }); | |
| 875 | |
| 876 // Container remains in auto mode even if the cast mode list changed. | |
| 877 test('cast mode list updated in auto mode', function(done) { | |
| 878 assertEquals(media_router.AUTO_CAST_MODE.description, | |
| 879 container.headerText); | |
| 880 assertEquals(media_router.CastModeType.AUTO, | |
| 881 container.shownCastModeValue_); | |
| 882 assertFalse(container.userHasSelectedCastMode_); | |
| 883 | |
| 884 container.castModeList = fakeCastModeList.slice(1); | |
| 885 setTimeout(function() { | |
| 886 assertEquals(media_router.AUTO_CAST_MODE.description, | |
| 887 container.headerText); | |
| 888 assertEquals(media_router.CastModeType.AUTO, | |
| 889 container.shownCastModeValue_); | |
| 890 assertFalse(container.userHasSelectedCastMode_); | |
| 891 done(); | |
| 892 }); | |
| 893 }); | |
| 894 | |
| 895 // If the container is not in auto mode, and the mode it is currently in | |
| 896 // no longer exists in the list of cast modes, then switch back to auto | |
| 897 // mode. | |
| 898 test('cast mode list updated in selected cast mode', function(done) { | |
| 899 assertEquals(media_router.AUTO_CAST_MODE.description, | |
| 900 container.headerText); | |
| 901 assertEquals(media_router.CastModeType.AUTO, | |
| 902 container.shownCastModeValue_); | |
| 903 assertFalse(container.userHasSelectedCastMode_); | |
| 904 | |
| 905 MockInteractions.tap(container.$['container-header']. | |
| 906 $['arrow-drop-icon']); | |
| 907 setTimeout(function() { | |
| 908 var castModeList = | |
| 909 container.$$('#cast-mode-list').querySelectorAll('paper-item'); | |
| 910 MockInteractions.tap(castModeList[0]); | |
| 911 setTimeout(function() { | |
| 912 assertEquals(fakeCastModeList[0].description, container.headerText); | |
| 913 assertEquals(fakeCastModeList[0].type, | |
| 914 container.shownCastModeValue_); | |
| 915 assertTrue(container.userHasSelectedCastMode_); | |
| 916 container.castModeList = fakeCastModeList.slice(1); | |
| 917 setTimeout(function() { | |
| 918 assertEquals(media_router.AUTO_CAST_MODE.description, | |
| 919 container.headerText); | |
| 920 assertEquals(media_router.CastModeType.AUTO, | |
| 921 container.shownCastModeValue_); | |
| 922 assertFalse(container.userHasSelectedCastMode_); | |
| 923 done(); | |
| 924 }); | |
| 925 }); | |
| 926 }); | |
| 927 }); | |
| 928 | |
| 929 test('creating route with selected cast mode', function(done) { | |
| 930 container.allSinks = fakeSinkList; | |
| 931 MockInteractions.tap(container.$['container-header']. | |
| 932 $['arrow-drop-icon']); | |
| 933 setTimeout(function() { | |
| 934 // Select cast mode 2. | |
| 935 var castModeList = | |
| 936 container.$$('#cast-mode-list').querySelectorAll('paper-item'); | |
| 937 MockInteractions.tap(castModeList[1]); | |
| 938 assertEquals(fakeCastModeList[1].description, container.headerText); | |
| 939 setTimeout(function() { | |
| 940 var sinkList = | |
| 941 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 942 container.addEventListener('create-route', function(data) { | |
| 943 assertEquals(fakeSinkList[2].id, data.detail.sinkId); | |
| 944 // Cast mode 2 is used, since we selected it explicitly. | |
| 945 assertEquals(fakeCastModeList[1].type, | |
| 946 data.detail.selectedCastModeValue); | |
| 947 done(); | |
| 948 }); | |
| 949 // All sinks are compatible with cast mode 2. | |
| 950 assertEquals(fakeSinkList.length, sinkList.length); | |
| 951 // Tap on a sink without a route, which should fire a 'create-route' | |
| 952 // event. | |
| 953 MockInteractions.tap(sinkList[2]); | |
| 954 }); | |
| 955 }); | |
| 956 }); | |
| 957 | |
| 958 // Tests that after a different cast mode is selected, the sink list will | |
| 959 // change based on the sinks compatibility with the new cast mode. | |
| 960 test('changing cast mode changes sink list', function(done) { | |
| 961 container.allSinks = fakeSinkList; | |
| 962 | |
| 963 MockInteractions.tap(container.$['container-header']. | |
| 964 $['arrow-drop-icon']); | |
| 965 setTimeout(function() { | |
| 966 var castModeList = | |
| 967 container.$$('#cast-mode-list').querySelectorAll('paper-item'); | |
| 968 MockInteractions.tap(castModeList[0]); | |
| 969 assertEquals(fakeCastModeList[0].description, container.headerText); | |
| 970 | |
| 971 setTimeout(function() { | |
| 972 var sinkList = | |
| 973 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 974 | |
| 975 // The sink list is empty because none of the sinks in fakeSinkList | |
| 976 // is compatible with cast mode 0. | |
| 977 assertEquals(0, sinkList.length); | |
| 978 MockInteractions.tap(castModeList[2]); | |
| 979 assertEquals(fakeCastModeList[2].description, container.headerText); | |
| 980 | |
| 981 setTimeout(function() { | |
| 982 var sinkList = | |
| 983 container.$['sink-list'].querySelectorAll('paper-item'); | |
| 984 assertEquals(3, sinkList.length); | |
| 985 done(); | |
| 986 }); | |
| 987 }); | |
| 988 }); | |
| 989 }); | |
| 990 }); | |
| 991 } | |
| 992 | |
| 993 return { | |
| 994 registerTests: registerTests, | |
| 995 }; | |
| 996 }); | |
| OLD | NEW |