1 <html> 2 <head> 3 <style> 4 5 body { 6 display: -webkit-box; 7 margin: 0; 8 font-family: Sans-serif; 9 overflow: hidden; 10 } 11 12 #list { 13 width: 200px; 14 padding: 10px; 15 } 16 17 #list h1 { 18 margin: 0; 19 font-size: 16px; 20 padding: 0 0 14px 8px; 21 border-right: 4px solid LightGray; 22 } 23 24 #list ul { 25 margin: 0; 26 padding: 2px 0 0 0; 27 list-style: none; 28 } 29 30 #list a:target { 31 cursor: default; 32 pointer-events: none; 33 background-color: #eee; 34 border-right: 4px solid Gray; 35 } 36 37 #list li { 38 padding-bottom: 2px; 39 } 40 41 #list a { 42 padding: 8px 8px 8px 8px; 43 display: block; 44 border-right: 4px solid LightGray; 45 color: initial; 46 -webkit-transition-property: border-right, background-color; 47 -webkit-transition-duration: 0.4s; 48 } 49 50 #test { 51 display: -webkit-box; 52 -webkit-box-orient: vertical; 53 -webkit-box-flex: 0.5; 54 } 55 56 #arena { 57 -webkit-box-flex: 0.5; 58 border: none; 59 display: -webkit-box; 60 } 61 62 #description { 63 height: 200px; 64 font-size: 12px; 65 padding-right: 16px; 66 overflow: auto; 67 } 68 69 </style> 70 <!-- LayoutTests location is hard-coded to avoid duplication of code. --> 71 <script src="http://svn.webkit.org/repository/webkit/trunk/LayoutTests/media/media-file.js"></script> 72 <script> 73 74 var MEDIA_FILES_LOCATION = 'http://svn.webkit.org/repository/webkit/trunk/LayoutTests/media/content'; 75 76 var MEDIA_FILES; 77 78 var TESTS = { 79 80 'video': { 81 title: 'Typical video with controls', 82 description: '<p>Should have "Rewind", "Play", "Mute" buttons, timeline with time current and remaining shown.</p>' + 83 '<p>You may see brief resize of the video when the metadata arrives and a brief flash of the "Loading..." status.</p>' + 84 '<p>"Play" button should turn into "Pause" when playing, with current and remaining time should changing and the thumb ' + 85 'of the timeline gliding smoothly along the track, updated every 200ms or so.</p>', 86 html: '<video controls src={video}></video>', 87 }, 88 'audio': { 89 title: 'Typical audio with controls', 90 description: '<p>Should have "Rewind", "Play", "Mute" buttons, timeline with time current and remaining shown.</p>' + 91 '<p>You may see brief resize of the video when the metadata arrives and a brief flash of the "Loading..." status.</p>' + 92 '<p>"Play" button should turn into "Pause" when playing, with current and remaining time should changing and the thumb ' + 93 'of the timeline gliding smoothly along the track, updated every 200ms or so.</p>', 94 html: '<audio controls src={audio}></audio>', 95 }, 96 'video-volume': { 97 title: 'Video volume controls', 98 description: '<p>When hovering over the "Mute" button, a volume control should appear, showing its own "Mute" button and a volume slider.</p>' + 99 '<p>You should be able to control the volume with the slider and mute/unmute using the "Mute" button</p>' + 100 '<p>Moving the mouse away from the volume control should make the control disappear.</p>', 101 html: '<video controls src={video}></video>', 102 }, 103 'audio-volume': { 104 title: 'Audio volume controls', 105 description: '<p>When hovering over the "Mute" button, a volume control should appear, showing its own "Mute" button and a volume slider.</p>' + 106 '<p>You should be able to control the volume with the slider and mute/unmute using the "Mute" button</p>' + 107 '<p>Moving the mouse away from the volume control should make the control disappear.</p>', 108 html: '<audio style="padding-top: 200px;" controls src={video}></audio>', 109 }, 110 'audio-volume-neg': { 111 title: 'Audio volume controls (negative offset)', 112 description: '<p>When hovering over the "Mute" button, a volume control should appear, showing its own "Mute" button and a volume slider.</p>' + 113 '<p>In this particular layout, the volume control should be positioned directly under the "Mute" button, showing two "Mute" buttons --' + 114 'one on the main controls and another on the volume control.</p>' + 115 '<p>You should be able to control the volume with the slider and mute/unmute using the "Mute" button</p>' + 116 '<p>Moving the mouse away from the volume control or the "Mute" button should make the control disappear.</p>', 117 html: '<audio controls src={video}></audio>', 118 }, 119 'video-zoomed': { 120 title: 'Magnified video', 121 description: '<p>Should have the same appearance as a typical video, except magnified 1.5 times.</p>' + 122 '<p>Make sure that the appearance of controls does not changed when changing the page zoom.</p>', 123 html: '<video controls src={video} style="zoom:150%"></video>', 124 }, 125 'controls-fade': { 126 title: 'Fading video controls', 127 description: '<p>When the video is playing, the controls should fade out when the mouse is away from the video and fade back in when the mouse is over the video.</p>' + 128 '<p>The controls should not fade when the video is paused.</p>', 129 html: '<video controls src={video} autoplay></video>', 130 }, 131 'timeline-resize': { 132 title: 'Timeline reacting to a resize', 133 description: '<p>When changing the width of the screen, the timeline should be the only one part of the controls changing its width.</p>' + 134 '<p>At a certain minimum point, the current and remaining time should disappear, giving up their space to the timeline.</p>' + 135 '<p>Conversely, when sizing the width up, the current and remaining time should come back into their places.', 136 html: '<video controls src={video} style="width:60%"></video>', 137 }, 138 'toggle-controls': { 139 title: 'Toggling video controls', 140 description: '<p>When clicking on "Toggle Controls" button, the controls should appear and disappear.</p>' + 141 '<p>The controls should have "Rewind", "Play", "Mute" buttons, timeline with time current and remaining shown.</p>', 142 js: function(click) { 143 if (!click) 144 return; 145 146 var video = document.getElementsByTagName('video')[0]; 147 video.controls = !video.controls; 148 }, 149 html: '<video src={video}></video><br><button onclick="test(true)">Toggle Controls</button>', 150 }, 151 'toggle-controls-autoplay': { 152 title: 'Toggling video controls while playing', 153 description: '<p>When clicking on "Toggle Controls" button, the controls should appear and disappear.</p>' + 154 '<p>The controls should have "Rewind", "Pause", "Mute" buttons, timeline with time current and remaining shown,' + 155 'with current and remaining time should changing and the thumb of the timeline gliding smoothly along the track, updated every 200ms or so.</p>' + 156 '<p>The controls should fade quickly if the mouse is not over the video.</p>', 157 js: function(click) { 158 if (!click) 159 return; 160 161 var video = document.getElementsByTagName('video')[0]; 162 video.controls = !video.controls; 163 }, 164 html: '<video src={video} autoplay></video><br><button onclick="test(true)">Toggle Controls</button>', 165 }, 166 'closed-captions': { 167 title: 'Closed-captioned video', 168 description: '<p>If supported, should show a "CC" button, which should toggle display of closed captions.</p>' + 169 '<p>The state of the button should reflect the state of closed-captioning in the video (on at the start of the test).</p>', 170 js: function() { 171 var video = document.getElementsByTagName('video')[0]; 172 video.webkitClosedCaptionsVisible = true; 173 video.addEventListener('canplaythrough', function() 174 { 175 video.webkitClosedCaptionsVisible = true; 176 }, false); 177 }, 178 html: '<video controls src={video-captioned}></video>', 179 }, 180 'invalid': { 181 title: 'Video with invalid media', 182 description: 'Should have "Rewind" and "Play" buttons, and "Loading..." status ' + 183 'if supported. Should blink "Loading...", but not twitch or flash other controls if reloaded', 184 html: '<video controls src="foobar"></video>' 185 }, 186 'video-no-source': { 187 title: 'Video with no source', 188 description: 'Should have "Rewind" and "Play" buttons. Should not blink/twitch if reloaded.', 189 html: '<video controls></video>' 190 }, 191 'audio-no-source': { 192 title: 'Audio with no source', 193 description: 'Should have "Rewind" and "Play" buttons. Should not blink/twitch if reloaded.', 194 html: '<audio controls></audio>' 195 }, 196 'controls-buffer-update': { 197 title: 'Buffer progress bar updates', 198 description: '<p>The buffer progress bar should continue to update prior to video playback.</p>' + 199 '<p>Verify the progress bar representing the amount of video buffered continues to ' + 200 'update prior to video playback. Keep the mouse pointer off the progress bar during this check ' + 201 'as movement over the control will trigger a repaint which invalidates the test.</p><p>' + 202 'It\'s expected that the video may stop buffering before the entire video is loaded.</p>', 203 html: '<video controls src="http://movies.apple.com/movies/us/apple/ipoditunes/2007/touch/ads/apple_ipodtouch_touch_640x360.mov' + 204 '?prevent_caching=' + new Date().getTime() + '"></video>' 205 } 206 207 }; 208 209 function configureMediaFiles() 210 { 211 MEDIA_FILES = { 212 'audio': absoluteUrl(findMediaFile('audio', MEDIA_FILES_LOCATION + '/test')), 213 'video': absoluteUrl(findMediaFile('video', MEDIA_FILES_LOCATION + '/test')), 214 'video-captioned': absoluteUrl(MEDIA_FILES_LOCATION + '/counting-captioned.mov') 215 } 216 217 // FIXME: Add error reporting when resolving these fails. 218 219 function absoluteUrl(url) 220 { 221 var a = document.createElement('a'); 222 a.href = url; 223 return '"' + a.href + '"'; 224 } 225 } 226 227 function runTest() 228 { 229 var test = TESTS[location.hash.substr(1)]; 230 if (!test) 231 return; 232 233 var arena = document.getElementById('arena'); 234 document.getElementById('description').innerHTML = '<h2>' + test.title + '</h2>' + test.description; 235 if (test.html) { 236 arena.contentDocument.body.innerHTML = test.html.replace(/{([\w-]+)}/g, function(s, type) 237 { 238 return (MEDIA_FILES[type] || ''); 239 }); 240 } 241 242 arena.contentDocument.body.appendChild(arena.contentDocument.createElement('script')).textContent = 'window.test = ' + (test.js ? String(test.js) : 'function() {}') + ';\nwindow.test()'; 243 } 244 245 window.addEventListener('hashchange', runTest, false); 246 247 window.addEventListener('DOMContentLoaded', function() 248 { 249 configureMediaFiles(); 250 251 var list = document.getElementById('list').appendChild(document.createElement('ul')); 252 for(var key in TESTS) 253 list.appendChild(document.createElement('li')).innerHTML = '<a href="#' + key + '" id="' + key + '">' + TESTS[key].title + '</a>'; 254 runTest(); 255 }, false); 256 257 </script> 258 </head> 259 <body> 260 <div id="list"> 261 <h1>Manual Tests of Media Controls Appearance</h1> 262 </div> 263 <div id="test"> 264 <iframe id="arena"></iframe> 265 <div id="description"></div> 266 </div> 267 </body> 268 </html> 269