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

Side by Side Diff: third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp

Issue 2757323002: Prevent Media Controls from hiding when the user is interacting via the keyboard (Closed)
Patch Set: johnme@ feedback and add unit tests Created 3 years, 8 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 2015 The Chromium Authors. All rights reserved. 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 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 "core/html/shadow/MediaControls.h" 5 #include "core/html/shadow/MediaControls.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <memory> 8 #include <memory>
9 #include "core/HTMLNames.h" 9 #include "core/HTMLNames.h"
10 #include "core/css/StylePropertySet.h" 10 #include "core/css/StylePropertySet.h"
11 #include "core/dom/Document.h" 11 #include "core/dom/Document.h"
12 #include "core/dom/ElementTraversal.h" 12 #include "core/dom/ElementTraversal.h"
13 #include "core/dom/StyleEngine.h" 13 #include "core/dom/StyleEngine.h"
14 #include "core/frame/Settings.h" 14 #include "core/frame/Settings.h"
15 #include "core/html/HTMLVideoElement.h" 15 #include "core/html/HTMLVideoElement.h"
16 #include "core/html/shadow/MediaControlElementTypes.h" 16 #include "core/html/shadow/MediaControlElementTypes.h"
17 #include "core/loader/EmptyClients.h" 17 #include "core/loader/EmptyClients.h"
18 #include "core/testing/DummyPageHolder.h" 18 #include "core/testing/DummyPageHolder.h"
19 #include "platform/heap/Handle.h" 19 #include "platform/heap/Handle.h"
20 #include "platform/testing/EmptyWebMediaPlayer.h" 20 #include "platform/testing/EmptyWebMediaPlayer.h"
21 #include "platform/testing/HistogramTester.h" 21 #include "platform/testing/HistogramTester.h"
22 #include "platform/testing/TestingPlatformSupport.h"
22 #include "platform/testing/UnitTestHelpers.h" 23 #include "platform/testing/UnitTestHelpers.h"
23 #include "public/platform/WebSize.h" 24 #include "public/platform/WebSize.h"
24 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h " 25 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h "
25 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h" 26 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h"
26 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
27 28
28 namespace blink { 29 namespace blink {
29 30
30 namespace { 31 namespace {
31 32
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 enum DownloadActionMetrics { 115 enum DownloadActionMetrics {
115 Shown = 0, 116 Shown = 0,
116 Clicked, 117 Clicked,
117 Count // Keep last. 118 Count // Keep last.
118 }; 119 };
119 120
120 } // namespace 121 } // namespace
121 122
122 class MediaControlsTest : public ::testing::Test { 123 class MediaControlsTest : public ::testing::Test {
123 protected: 124 protected:
124 virtual void SetUp() { 125 virtual void SetUp() { initializePage(); }
126
127 void initializePage() {
125 m_pageHolder = DummyPageHolder::create(IntSize(800, 600), nullptr, 128 m_pageHolder = DummyPageHolder::create(IntSize(800, 600), nullptr,
126 StubLocalFrameClient::create()); 129 StubLocalFrameClient::create());
127 Document& document = this->document(); 130 Document& document = this->document();
128 131
129 document.write("<video>"); 132 document.write("<video>");
130 HTMLVideoElement& video = 133 HTMLVideoElement& video =
131 toHTMLVideoElement(*document.querySelector("video")); 134 toHTMLVideoElement(*document.querySelector("video"));
132 m_mediaControls = video.mediaControls(); 135 m_mediaControls = video.mediaControls();
133 136
134 // If scripts are not enabled, controls will always be shown. 137 // If scripts are not enabled, controls will always be shown.
135 m_pageHolder->frame().settings()->setScriptEnabled(true); 138 m_pageHolder->frame().settings()->setScriptEnabled(true);
136 } 139 }
137 140
138 void simulateRouteAvailabe() { 141 void simulateRouteAvailable() {
139 m_mediaControls->mediaElement().remoteRouteAvailabilityChanged( 142 m_mediaControls->mediaElement().remoteRouteAvailabilityChanged(
140 WebRemotePlaybackAvailability::DeviceAvailable); 143 WebRemotePlaybackAvailability::DeviceAvailable);
141 } 144 }
142 145
143 void ensureSizing() { 146 void ensureSizing() {
144 // Fire the size-change callback to ensure that the controls have 147 // Fire the size-change callback to ensure that the controls have
145 // been properly notified of the video size. 148 // been properly notified of the video size.
146 m_mediaControls->notifyElementSizeChanged( 149 m_mediaControls->notifyElementSizeChanged(
147 m_mediaControls->mediaElement().getBoundingClientRect()); 150 m_mediaControls->mediaElement().getBoundingClientRect());
148 } 151 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 ensureSizing(); 238 ensureSizing();
236 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, 239 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr,
237 true); 240 true);
238 241
239 Element* castButton = getElementByShadowPseudoId( 242 Element* castButton = getElementByShadowPseudoId(
240 mediaControls(), "-internal-media-controls-cast-button"); 243 mediaControls(), "-internal-media-controls-cast-button");
241 ASSERT_NE(nullptr, castButton); 244 ASSERT_NE(nullptr, castButton);
242 245
243 ASSERT_FALSE(isElementVisible(*castButton)); 246 ASSERT_FALSE(isElementVisible(*castButton));
244 247
245 simulateRouteAvailabe(); 248 simulateRouteAvailable();
246 ASSERT_TRUE(isElementVisible(*castButton)); 249 ASSERT_TRUE(isElementVisible(*castButton));
247 } 250 }
248 251
249 TEST_F(MediaControlsTest, CastButtonDisableRemotePlaybackAttr) { 252 TEST_F(MediaControlsTest, CastButtonDisableRemotePlaybackAttr) {
250 ensureSizing(); 253 ensureSizing();
251 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, 254 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr,
252 true); 255 true);
253 256
254 Element* castButton = getElementByShadowPseudoId( 257 Element* castButton = getElementByShadowPseudoId(
255 mediaControls(), "-internal-media-controls-cast-button"); 258 mediaControls(), "-internal-media-controls-cast-button");
256 ASSERT_NE(nullptr, castButton); 259 ASSERT_NE(nullptr, castButton);
257 260
258 ASSERT_FALSE(isElementVisible(*castButton)); 261 ASSERT_FALSE(isElementVisible(*castButton));
259 simulateRouteAvailabe(); 262 simulateRouteAvailable();
260 ASSERT_TRUE(isElementVisible(*castButton)); 263 ASSERT_TRUE(isElementVisible(*castButton));
261 264
262 mediaControls().mediaElement().setBooleanAttribute( 265 mediaControls().mediaElement().setBooleanAttribute(
263 HTMLNames::disableremoteplaybackAttr, true); 266 HTMLNames::disableremoteplaybackAttr, true);
264 ASSERT_FALSE(isElementVisible(*castButton)); 267 ASSERT_FALSE(isElementVisible(*castButton));
265 268
266 mediaControls().mediaElement().setBooleanAttribute( 269 mediaControls().mediaElement().setBooleanAttribute(
267 HTMLNames::disableremoteplaybackAttr, false); 270 HTMLNames::disableremoteplaybackAttr, false);
268 ASSERT_TRUE(isElementVisible(*castButton)); 271 ASSERT_TRUE(isElementVisible(*castButton));
269 } 272 }
270 273
271 TEST_F(MediaControlsTest, CastOverlayDefault) { 274 TEST_F(MediaControlsTest, CastOverlayDefault) {
272 Element* castOverlayButton = getElementByShadowPseudoId( 275 Element* castOverlayButton = getElementByShadowPseudoId(
273 mediaControls(), "-internal-media-controls-overlay-cast-button"); 276 mediaControls(), "-internal-media-controls-overlay-cast-button");
274 ASSERT_NE(nullptr, castOverlayButton); 277 ASSERT_NE(nullptr, castOverlayButton);
275 278
276 simulateRouteAvailabe(); 279 simulateRouteAvailable();
277 ASSERT_TRUE(isElementVisible(*castOverlayButton)); 280 ASSERT_TRUE(isElementVisible(*castOverlayButton));
278 } 281 }
279 282
280 TEST_F(MediaControlsTest, CastOverlayDisableRemotePlaybackAttr) { 283 TEST_F(MediaControlsTest, CastOverlayDisableRemotePlaybackAttr) {
281 Element* castOverlayButton = getElementByShadowPseudoId( 284 Element* castOverlayButton = getElementByShadowPseudoId(
282 mediaControls(), "-internal-media-controls-overlay-cast-button"); 285 mediaControls(), "-internal-media-controls-overlay-cast-button");
283 ASSERT_NE(nullptr, castOverlayButton); 286 ASSERT_NE(nullptr, castOverlayButton);
284 287
285 ASSERT_FALSE(isElementVisible(*castOverlayButton)); 288 ASSERT_FALSE(isElementVisible(*castOverlayButton));
286 simulateRouteAvailabe(); 289 simulateRouteAvailable();
287 ASSERT_TRUE(isElementVisible(*castOverlayButton)); 290 ASSERT_TRUE(isElementVisible(*castOverlayButton));
288 291
289 mediaControls().mediaElement().setBooleanAttribute( 292 mediaControls().mediaElement().setBooleanAttribute(
290 HTMLNames::disableremoteplaybackAttr, true); 293 HTMLNames::disableremoteplaybackAttr, true);
291 ASSERT_FALSE(isElementVisible(*castOverlayButton)); 294 ASSERT_FALSE(isElementVisible(*castOverlayButton));
292 295
293 mediaControls().mediaElement().setBooleanAttribute( 296 mediaControls().mediaElement().setBooleanAttribute(
294 HTMLNames::disableremoteplaybackAttr, false); 297 HTMLNames::disableremoteplaybackAttr, false);
295 ASSERT_TRUE(isElementVisible(*castOverlayButton)); 298 ASSERT_TRUE(isElementVisible(*castOverlayButton));
296 } 299 }
297 300
298 TEST_F(MediaControlsTest, CastOverlayMediaControlsDisabled) { 301 TEST_F(MediaControlsTest, CastOverlayMediaControlsDisabled) {
299 Element* castOverlayButton = getElementByShadowPseudoId( 302 Element* castOverlayButton = getElementByShadowPseudoId(
300 mediaControls(), "-internal-media-controls-overlay-cast-button"); 303 mediaControls(), "-internal-media-controls-overlay-cast-button");
301 ASSERT_NE(nullptr, castOverlayButton); 304 ASSERT_NE(nullptr, castOverlayButton);
302 305
303 EXPECT_FALSE(isElementVisible(*castOverlayButton)); 306 EXPECT_FALSE(isElementVisible(*castOverlayButton));
304 simulateRouteAvailabe(); 307 simulateRouteAvailable();
305 EXPECT_TRUE(isElementVisible(*castOverlayButton)); 308 EXPECT_TRUE(isElementVisible(*castOverlayButton));
306 309
307 document().settings()->setMediaControlsEnabled(false); 310 document().settings()->setMediaControlsEnabled(false);
308 EXPECT_FALSE(isElementVisible(*castOverlayButton)); 311 EXPECT_FALSE(isElementVisible(*castOverlayButton));
309 312
310 document().settings()->setMediaControlsEnabled(true); 313 document().settings()->setMediaControlsEnabled(true);
311 EXPECT_TRUE(isElementVisible(*castOverlayButton)); 314 EXPECT_TRUE(isElementVisible(*castOverlayButton));
312 } 315 }
313 316
314 TEST_F(MediaControlsTest, KeepControlsVisibleIfOverflowListVisible) { 317 TEST_F(MediaControlsTest, KeepControlsVisibleIfOverflowListVisible) {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 double duration = 600; 497 double duration = 600;
495 loadMediaWithDuration(duration); 498 loadMediaWithDuration(duration);
496 499
497 // Simulate seeking the underlying range to 50%. Current time display should 500 // Simulate seeking the underlying range to 50%. Current time display should
498 // update synchronously (rather than waiting for media to finish seeking). 501 // update synchronously (rather than waiting for media to finish seeking).
499 timeline->setValueAsNumber(duration / 2, ASSERT_NO_EXCEPTION); 502 timeline->setValueAsNumber(duration / 2, ASSERT_NO_EXCEPTION);
500 timeline->dispatchInputEvent(); 503 timeline->dispatchInputEvent();
501 EXPECT_EQ(duration / 2, currentTimeDisplay->currentValue()); 504 EXPECT_EQ(duration / 2, currentTimeDisplay->currentValue());
502 } 505 }
503 506
507 TEST_F(MediaControlsTest, ControlsRemainVisibleDuringKeyboardInteraction) {
508 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
509 m_platform;
510 m_platform->advanceClockSeconds(1);
johnme 2017/04/06 17:15:28 Can you add a comment explaining why you need to a
steimel 2017/04/07 16:47:16 Done.
511
512 // Need to reinitialize page since we changed the platform.
513 initializePage();
514 ensureSizing();
515
516 Element* panel = getElementByShadowPseudoId(mediaControls(),
johnme 2017/04/06 17:15:28 Nit: you can use mediaControls().panelElement() he
steimel 2017/04/07 16:47:17 Done.
517 "-webkit-media-controls-panel");
518 ASSERT_NE(nullptr, panel);
519
520 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr,
521 true);
522 mediaControls().mediaElement().setSrc("http://example.com");
523 mediaControls().mediaElement().play();
524
525 // Controls start out visible.
526 EXPECT_TRUE(isElementVisible(*panel));
527
528 // Tabbing between controls prevents controls from hiding.
529 m_platform->runForPeriodSeconds(2);
530 mediaControls().dispatchEvent(Event::create("focusin"));
531 m_platform->runForPeriodSeconds(2);
532 EXPECT_TRUE(isElementVisible(*panel));
533
534 // Seeking on the timeline or volume bar prevents controls from hiding.
535 mediaControls().dispatchEvent(Event::create("input"));
536 m_platform->runForPeriodSeconds(2);
537 EXPECT_TRUE(isElementVisible(*panel));
538
539 // Pressing a key prevents controls from hiding.
540 mediaControls().panelElement()->dispatchEvent(Event::create("keypress"));
541 m_platform->runForPeriodSeconds(2);
542 EXPECT_TRUE(isElementVisible(*panel));
543
544 // Once user interaction stops, controls can hide.
545 m_platform->runForPeriodSeconds(2);
546 EXPECT_FALSE(isElementVisible(*panel));
547 }
548
504 } // namespace blink 549 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698