summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/semantics/embedded-content/media-elements
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/semantics/embedded-content/media-elements')
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_controls_present-manual.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_loop_base.html42
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_overriding_volume-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_present-manual.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_check.html58
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_loudest-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_silent-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/contains.json132
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/error-codes/error.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_canplaythrough.html52
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_playing.html52
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html52
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadstart_progress.html52
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause.html48
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play_noautoplay.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing_noautoplay.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate.html34
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_volumechange.html72
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/historical.html53
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack.html116
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/textTracks.html13
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/default.html55
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html146
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/label.html83
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/readyState.html11
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src.html43
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang.html82
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/track.html12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/activeCues.html104
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/addCue.html68
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/constants.html23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues.html100
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/label.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode.html55
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/oncuechange.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/removeCue.html50
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/endTime.html39
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/id.html39
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onenter.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onexit.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/pauseOnExit.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/startTime.html39
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/track.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getCueById.html53
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getter.html49
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/length.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getTrackById.html16
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getter.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/length.html18
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onaddtrack.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onremovetrack.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/constructor.html24
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent.html15
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/autoplay-overrides-preload.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-events-networkState.html67
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-moved.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-addEventListener.html26
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-no-listener.html26
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-onerror.html26
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html13
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor.html12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-in-sync-event.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-fragment-into-document.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-document.html12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-iframe.html23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-parent-into-document.html19
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-div.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-networkState.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html13
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-load.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause-networkState.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-play.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document-networkState.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-in-namespace.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState.html16
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html13
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-control.html26
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-br.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-source.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-text.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source-after.html56
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html43
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-text.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html24
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-src.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-source-media.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resources/delayed-broken-video.py5
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-beforeunload-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-dialogs-manual.html18
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-print-manual.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/location-of-the-media-resource/currentSrc.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html110
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_loadstart.html42
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_progress.html42
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_initial.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/duration.html11
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_false_during_play.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_true_during_pause.html46
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-to-other-document.html25
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-within-document.html25
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document.html37
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/play-in-detached-document.html23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html19
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/preload_reflects_none_autoplay.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/ready-states/autoplay.html73
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplay.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplaythrough.html46
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_playing.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_initial.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-max-value.htm23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time.htm23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/src_reflects_attribute_not_source_elements.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cloneNode.html86
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/003.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/004.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/005.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/006.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/007.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/008.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/009.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/010.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/011.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/012.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/013.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/014.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/015.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/016.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/017.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/018.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/019.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/020.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/021.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/022.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/023.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/024.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/025.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/026.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/027.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/028.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/029.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/030.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/031.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/032.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/033.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/034.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/035.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/036.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/037.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/038.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/039.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/040.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/041.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/042.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/043.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/044.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/045.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/046.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/common.js144
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/cors-tester.py51
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/remove-cookie.html6
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/set-cookie.html6
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.de.vtt4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.en.vtt4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.fr.vtt4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.vtt4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues.html52
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/user-interface/muted.html152
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_008.htm45
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_controls_present-manual.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_loop_base.html41
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_overriding_volume-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_present-manual.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_check.html58
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_loudest-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_silent-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/volume_nonfinite.html18
209 files changed, 6493 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_controls_present-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_controls_present-manual.html
new file mode 100644
index 000000000..38faa4d00
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_controls_present-manual.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_controls_present.html</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-controls" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the controls attribute is present in the audio element that expecting the user agent exposes a controller user interface" />
+ </head>
+ <body>
+ <p>Test passes if a controller user interface appears below and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <audio id="m" controls>The user agent doesn't support media element.</audio>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_loop_base.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_loop_base.html
new file mode 100644
index 000000000..4917d9c39
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_loop_base.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_loop_base</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-loop" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if audio.loop is set to true that expecting the seeking event is fired more than once" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <audio id="m" controls>The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ var name = document.getElementsByName("assert")[0].content;
+ var t = async_test(name);
+
+ var looped = false;
+
+ function startTest() {
+ if (looped) {
+ t.step(function() {
+ assert_true(true, "looped");
+ });
+ t.done();
+ media.pause();
+ }
+
+ looped = true;
+ }
+
+ media.addEventListener("seeking", startTest, false);
+ media.loop = true;
+ media.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_overriding_volume-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_overriding_volume-manual.html
new file mode 100644
index 000000000..cc1892ce8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_overriding_volume-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_muted_overriding_volume</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-muted" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the muted attribute is present in the audio element with volume is set to loudest that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the audio is playing without sound output and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <audio id="m" controls muted>The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ media.volume = 1.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_present-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_present-manual.html
new file mode 100644
index 000000000..16d6f07ee
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_present-manual.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_muted_present</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-muted" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the muted attribute is present in the audio element that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the audio is playing without sound output and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <audio id="m" controls muted>The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_check.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_check.html
new file mode 100644
index 000000000..b467c702a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_check.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_volume_check</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check that audio.volume returns the value of the muted content attribute" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <audio id="m">The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ var VOLUME = {
+ 'SILENT' : 0.0,
+ 'NORMAL' : 0.5,
+ 'LOUDEST' : 1.0,
+ 'LOWER' : -1.1,
+ 'UPPER' : 1.1,
+ };
+
+ test(function() {
+ assert_false(media.volume < VOLUME.SILENT || media.volume > VOLUME.LOUDEST, "media.volume outside the range 0.0 to 1.0 inclusive");
+ }, "Check if the intial value of the audio.volume is in the range 0.0 to 1.0 inclusive");
+
+ function volume_setting(vol, name)
+ {
+ if (vol < VOLUME.SILENT || vol > VOLUME.LOUDEST) {
+ try {
+ media.volume = vol;
+ test(function() {
+ assert_true(false, "media.volume setting exception");
+ }, name);
+ } catch(e) {
+ test(function() {
+ // 1 should be e.IndexSizeError or e.INDEX_SIZE_ERR in previous spec
+ assert_equals(e.code, 1, "media.volume setting exception");
+ }, name);
+ }
+ } else {
+ media.volume = vol;
+ test(function() {
+ assert_equals(media.volume, vol, "media.volume new value");
+ }, name);
+ }
+ }
+
+ volume_setting(VOLUME.NORMAL, "Check if audio.volume is able to set to new value in the range 0.0 to 1.0");
+ volume_setting(VOLUME.SILENT, "Check if media.volume is able to set to new value 0.0 as silent");
+ volume_setting(VOLUME.LOUDEST, "Check if media.volume is able to set to new value 1.0 as loudest");
+ volume_setting(VOLUME.LOWER, "Check if media.volume is set to new value less than 0.0 that expecting an IndexSizeError exception is to be thrown");
+ volume_setting(VOLUME.UPPER, "Check if audio.volume is set to new value greater than 1.0 that expecting an IndexSizeError exception is to be thrown");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_loudest-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_loudest-manual.html
new file mode 100644
index 000000000..a623e8f5c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_loudest-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_volume_loudest</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the volume attribute is set to 1.0 as loudest in the audio element that expecting the user hears sound loudly" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the audio is playing with sound heard and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <audio id="m" controls>The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ media.volume = 1.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_silent-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_silent-manual.html
new file mode 100644
index 000000000..257bd4628
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_silent-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_volume_silent</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the volume attribute is set to 0.0 as silent in the audio element that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the audio is playing without sound heard and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <audio id="m" controls volume=0.0>The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ media.volume = 0.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/contains.json b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/contains.json
new file mode 100644
index 000000000..9cf23296c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/contains.json
@@ -0,0 +1,132 @@
+[
+ {
+ "id": "error-codes",
+ "original_id": "error-codes"
+ },
+ {
+ "id": "location-of-the-media-resource",
+ "original_id": "location-of-the-media-resource"
+ },
+ {
+ "id": "mime-types",
+ "original_id": "mime-types"
+ },
+ {
+ "id": "network-states",
+ "original_id": "network-states"
+ },
+ {
+ "id": "loading-the-media-resource",
+ "original_id": "loading-the-media-resource"
+ },
+ {
+ "id": "offsets-into-the-media-resource",
+ "original_id": "offsets-into-the-media-resource"
+ },
+ {
+ "id": "ready-states",
+ "original_id": "ready-states"
+ },
+ {
+ "id": "playing-the-media-resource",
+ "original_id": "playing-the-media-resource"
+ },
+ {
+ "id": "seeking",
+ "original_id": "seeking"
+ },
+ {
+ "id": "media-resources-with-multiple-media-tracks",
+ "original_id": "media-resources-with-multiple-media-tracks",
+ "children": [
+ {
+ "id": "audiotracklist-and-videotracklist-objects",
+ "original_id": "audiotracklist-and-videotracklist-objects"
+ },
+ {
+ "id": "selecting-specific-audio-and-video-tracks-declaratively",
+ "original_id": "selecting-specific-audio-and-video-tracks-declaratively"
+ }
+ ]
+ },
+ {
+ "id": "synchronising-multiple-media-elements",
+ "original_id": "synchronising-multiple-media-elements",
+ "children": [
+ {
+ "id": "introduction-0",
+ "original_id": "introduction-0"
+ },
+ {
+ "id": "media-controllers",
+ "original_id": "media-controllers"
+ },
+ {
+ "id": "assigning-a-media-controller-declaratively",
+ "original_id": "assigning-a-media-controller-declaratively"
+ }
+ ]
+ },
+ {
+ "id": "timed-text-tracks",
+ "original_id": "timed-text-tracks",
+ "children": [
+ {
+ "id": "text-track-model",
+ "original_id": "text-track-model"
+ },
+ {
+ "id": "sourcing-in-band-text-tracks",
+ "original_id": "sourcing-in-band-text-tracks"
+ },
+ {
+ "id": "sourcing-out-of-band-text-tracks",
+ "original_id": "sourcing-out-of-band-text-tracks"
+ },
+ {
+ "id": "guidelines-for-exposing-cues-in-various-formats-as-text-track-cues",
+ "original_id": "guidelines-for-exposing-cues-in-various-formats-as-text-track-cues"
+ },
+ {
+ "id": "text-track-api",
+ "original_id": "text-track-api"
+ },
+ {
+ "id": "text-tracks-describing-chapters",
+ "original_id": "text-tracks-describing-chapters"
+ },
+ {
+ "id": "cue-events",
+ "original_id": "cue-events"
+ }
+ ]
+ },
+ {
+ "id": "user-interface",
+ "original_id": "user-interface"
+ },
+ {
+ "id": "time-ranges",
+ "original_id": "time-ranges"
+ },
+ {
+ "id": "event-definitions",
+ "original_id": "event-definitions"
+ },
+ {
+ "id": "mediaevents",
+ "original_id": "mediaevents"
+ },
+ {
+ "id": "security-and-privacy-considerations",
+ "original_id": "security-and-privacy-considerations"
+ },
+ {
+ "id": "best-practices-for-authors-using-media-elements",
+ "original_id": "best-practices-for-authors-using-media-elements"
+ },
+ {
+ "id": "best-practices-for-implementors-of-media-elements",
+ "original_id": "best-practices-for-implementors-of-media-elements"
+ }
+]
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/error-codes/error.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/error-codes/error.html
new file mode 100644
index 000000000..c97576041
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/error-codes/error.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>error</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<script>
+function error_test(tagName, src) {
+ test(function() {
+ assert_equals(document.createElement(tagName).error, null);
+ }, tagName + '.error initial value');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.onloadeddata = t.step_func(function() {
+ assert_equals(e.error, null);
+ t.done();
+ });
+ }, tagName + '.error after successful load');
+
+ // TODO: MEDIA_ERR_ABORTED, MEDIA_ERR_NETWORK, MEDIA_ERR_DECODE
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = '';
+ e.onerror = t.step_func(function() {
+ assert_true(e.error instanceof MediaError);
+ assert_equals(e.error.code, 4);
+ assert_equals(e.error.code, e.error.MEDIA_ERR_SRC_NOT_SUPPORTED);
+ t.done();
+ });
+ }, tagName + '.error after setting src to the empty string');
+}
+
+error_test('audio', getAudioURI('/media/sound_5'));
+error_test('video', getVideoURI('/media/movie_5'));
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay.html
new file mode 100644
index 000000000..8e1b32dcb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplay</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger canplay event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplay", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplay");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger canplay event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplay", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplay");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay_noautoplay.html
new file mode 100644
index 000000000..8f3372501
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplay</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function () {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger canplay event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplay", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplay");
+
+test(function () {
+ var t = async_test("setting src attribute on non-autoplay video should trigger canplay event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplay", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplay");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough.html
new file mode 100644
index 000000000..827e79607
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplaythrough</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger canplaythrough event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplaythrough", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplaythrough");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger canplaythrough event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplaythrough", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplaythrough");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough_noautoplay.html
new file mode 100644
index 000000000..75a70985a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplaythrough</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger canplaythrough event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplaythrough", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplaythrough");
+
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay video should trigger canplaythrough event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplaythrough", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplaythrough");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata.html
new file mode 100644
index 000000000..f0e89c3c1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadeddata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger loadeddata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadeddata", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadeddata");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger loadeddata event", {timeout:5000});
+ var a = document.getElementById("v");
+ v.addEventListener("loadeddata", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadeddata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html
new file mode 100644
index 000000000..0c81f335b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadeddata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger loadeddata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadeddata", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadeddata");
+
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay video should trigger loadeddata event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadeddata", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadeddata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata.html
new file mode 100644
index 000000000..234121e58
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadedmetadata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger loadedmetadata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadedmetadata", function() {
+ t.done();
+ a.pause();
+ });
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadedmetadata");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger loadedmetadata event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadedmetadata", function() {
+ t.done();
+ v.pause();
+ });
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadedmetadata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html
new file mode 100644
index 000000000..382f3f6fb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadedmetadata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger loadedmetadata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadedmetadata", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadedmetadata");
+
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay video should trigger loadedmetadata event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadedmetadata", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events, loadedmetadata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart.html
new file mode 100644
index 000000000..de4568212
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadstart</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger loadstart event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadstart", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadstart");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger loadstart event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadstart", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadstart");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart_noautoplay.html
new file mode 100644
index 000000000..b575e7ac8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadstart</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger loadstart event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadstart", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadstart");
+
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay video should trigger loadstart event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadstart", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadstart");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_canplaythrough.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_canplaythrough.html
new file mode 100644
index 000000000..a1e7e4155
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_canplaythrough.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplay, then canplaythrough</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger canplay then canplaythrough event", {timeout:5000});
+ var a = document.getElementById("a");
+ var found_canplay = false;
+ a.addEventListener("canplay", function() {
+ found_canplay = true;
+ });
+ a.addEventListener("canplaythrough", function() {
+ t.step(function() {
+ assert_true(found_canplay);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplay, then canplaythrough");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger canplay then canplaythrough event", {timeout:5000});
+ var v = document.getElementById("v");
+ var found_canplay = false;
+ v.addEventListener("canplay", function() {
+ found_canplay = true;
+ });
+ v.addEventListener("canplaythrough", function() {
+ t.step(function() {
+ assert_true(found_canplay);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplay, then canplaythrough");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_playing.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_playing.html
new file mode 100644
index 000000000..a5a67ddb2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_playing.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplay, then playing</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger canplay then playing event", {timeout:5000});
+ var a = document.getElementById("a");
+ var found_canplay = false;
+ a.addEventListener("canplay", function() {
+ found_canplay = true;
+ });
+ a.addEventListener("playing", function() {
+ t.step(function() {
+ assert_true(found_canplay);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplay, then playing");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger canplay then playing event", {timeout:5000});
+ var v = document.getElementById("v");
+ var found_canplay = false;
+ v.addEventListener("canplay", function() {
+ found_canplay = true;
+ });
+ v.addEventListener("playing", function() {
+ t.step(function() {
+ assert_true(found_canplay);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplay, then playing");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html
new file mode 100644
index 000000000..3aba3684f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadedmetadata, then loadeddata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger loadedmetadata then loadeddata event", {timeout:5000});
+ var a = document.getElementById("a");
+ var found_loadedmetadata = false;
+ a.addEventListener("loadedmetadata", function() {
+ found_loadedmetadata = true;
+ });
+ a.addEventListener("loadeddata", function() {
+ t.step(function() {
+ assert_true(found_loadedmetadata);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadedmetadata, then loadeddata");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger loadedmetadata then loadeddata event", {timeout:5000});
+ var v = document.getElementById("v");
+ var found_loadedmetadata = false;
+ v.addEventListener("loadedmetadata", function() {
+ found_loadedmetadata = true;
+ });
+ v.addEventListener("loadeddata", function() {
+ t.step(function() {
+ assert_true(found_loadedmetadata);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadedmetadata, then loadeddata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadstart_progress.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadstart_progress.html
new file mode 100644
index 000000000..75e3ba772
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadstart_progress.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadstart, then progress</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger loadstart then progress event", {timeout:5000});
+ var a = document.getElementById("a");
+ var found_loadstart = false;
+ a.addEventListener("loadstart", function() {
+ found_loadstart = true;
+ });
+ a.addEventListener("progress", function() {
+ t.step(function() {
+ assert_true(found_loadstart);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadstart, then progress");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger loadstart then progress event", {timeout:5000});
+ var v = document.getElementById("v");
+ var found_loadstart = false;
+ v.addEventListener("loadstart", function() {
+ found_loadstart = true;
+ });
+ v.addEventListener("progress", function() {
+ t.step(function() {
+ assert_true(found_loadstart);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadstart, then progress");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause.html
new file mode 100644
index 000000000..1f7904c3b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - pause</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("calling pause() on autoplay audio should trigger pause event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("pause", function() {
+ t.step(function() {
+ assert_true(true);
+ });
+ t.done();
+ }, false);
+ a.addEventListener("play", function() {
+ a.pause(); // pause right after play
+ });
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - pause");
+
+test(function() {
+ var t = async_test("calling pause() on autoplay video should trigger pause event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("pause", function() {
+ t.step(function() {
+ assert_true(true);
+ });
+ t.done();
+ }, false);
+ v.addEventListener("play", function() {
+ v.pause(); // pause right after play
+ });
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - pause");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay.html
new file mode 100644
index 000000000..554823483
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - pause</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("calling play() then pause() on non-autoplay audio should trigger pause event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("pause", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ a.play();
+ a.pause();
+}, "audio events - pause");
+
+test(function() {
+ var t = async_test("calling play() then pause() on non-autoplay video should trigger pause event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("pause", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ v.play();
+ v.pause();
+}, "video events - pause");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play.html
new file mode 100644
index 000000000..82b2ca407
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - play</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger play event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("play", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - play");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger play event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("play", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - play");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play_noautoplay.html
new file mode 100644
index 000000000..67285a95a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play_noautoplay.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - play</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("calling play() on audio should trigger play event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("play", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ a.play();
+}, "audio events - play");
+
+test(function() {
+ var t = async_test("calling play() on video should trigger play event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("play", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ v.play();
+}, "video events - play");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing.html
new file mode 100644
index 000000000..3741a1c98
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - playing</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger playing event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("playing", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - playing");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger playing event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("playing", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - playing");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing_noautoplay.html
new file mode 100644
index 000000000..f750085ed
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing_noautoplay.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - playing</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("calling play() on audio should trigger playing event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("playing", function() {
+ t.done();
+ a.pause();
+ });
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ a.play();
+}, "audio events - playing");
+
+test(function() {
+ var t = async_test("calling play() on video should trigger playing event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("playing", function() {
+ t.done();
+ v.pause();
+ });
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ v.play();
+}, "video events - playing");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress.html
new file mode 100644
index 000000000..269f824f7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - progress</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger progress event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("progress", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - progress");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger progress event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("progress", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - progress");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress_noautoplay.html
new file mode 100644
index 000000000..c594f3036
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - progress</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger progress event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("progress", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - progress");
+
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay video should trigger progress event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("progress", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - progress");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate.html
new file mode 100644
index 000000000..cc0a17fe2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - timeupdate</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+var ta = async_test("setting src attribute on a sufficiently long autoplay audio should trigger timeupdate event", {timeout:5000});
+var a = document.getElementById("a");
+a.addEventListener("timeupdate", function() {
+ ta.done();
+ a.pause();
+}, false);
+a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+
+var tv = async_test("setting src attribute on a sufficiently long autoplay video should trigger timeupdate event", {timeout:5000});
+var v = document.getElementById("v");
+v.addEventListener("timeupdate", function() {
+ tv.done();
+ v.pause();
+}, false);
+v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html
new file mode 100644
index 000000000..feb4b8568
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - timeupdate</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("calling play() on a sufficiently long audio should trigger timeupdate event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("timeupdate", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ a.play();
+}, "audio events - timeupdate");
+
+test(function() {
+ var t = async_test("calling play() on a sufficiently long video should trigger timeupdate event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("timeupdate", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ v.play();
+}, "video events - timeupdate");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_volumechange.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_volumechange.html
new file mode 100644
index 000000000..3481947e8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_volumechange.html
@@ -0,0 +1,72 @@
+<!doctype html>
+<title>volumechange event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+function volumechange_test(tagName) {
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ assert_equals(e.volume, 1);
+ e.volume = 0.5;
+ assert_equals(e.volume, 0.5);
+ e.onvolumechange = t.step_func(function() {
+ assert_equals(e.volume, 0.5);
+ e.volume = 1;
+ assert_equals(e.volume, 1);
+ e.onvolumechange = t.step_func(function() {
+ assert_equals(e.volume, 1);
+ t.done();
+ });
+ });
+ }, "setting " + tagName + ".volume fires volumechange");
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ assert_false(e.muted);
+ e.muted = true;
+ assert_true(e.muted);
+ e.onvolumechange = t.step_func(function() {
+ assert_true(e.muted);
+ e.muted = false;
+ assert_false(e.muted);
+ e.onvolumechange = t.step_func(function() {
+ assert_false(e.muted);
+ t.done();
+ });
+ });
+ }, "setting " + tagName + ".muted fires volumechange");
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.volume = e.volume;
+ e.muted = e.muted;
+ e.onvolumechange = t.step_func(function() {
+ assert_unreached();
+ });
+ var e2 = document.createElement(tagName);
+ e2.muted = !e2.muted;
+ e2.onvolumechange = t.step_func(function() {
+ t.done();
+ });
+ }, "setting " + tagName + ".volume/muted to the same value does not fire volumechange");
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.muted = !e.muted;
+ e.volume = 1 - e.volume;
+ e.muted = !e.muted;
+ e.volume = 1 - e.volume;
+ var volumechange_count = 0;
+ e.onvolumechange = t.step_func(function() {
+ volumechange_count++;
+ if (volumechange_count == 4) {
+ t.done();
+ }
+ });
+ }, "setting " + tagName + ".volume/muted repeatedly fires volumechange repeatedly");
+}
+
+volumechange_test("audio");
+volumechange_test("video");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/historical.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/historical.html
new file mode 100644
index 000000000..451923408
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/historical.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<title>Historical media element features should not be supported</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function t(property, tagName) {
+ var tagNames = tagName ? [tagName] : ['audio', 'video'];
+ tagNames.forEach(function(tagName) {
+ test(function() {
+ assert_false(property in document.createElement(tagName));
+ }, tagName + '.' + property + ' should not be supported');
+ });
+}
+
+t('bufferingRate'); // added in r678, removed in r2872.
+t('start'); // added in r692, removed in r2401.
+t('end'); // added in r692, removed in r2401.
+t('loopStart'); // added in r692, removed in r2401.
+t('loopEnd'); // added in r692, removed in r2401.
+t('loopCount'); // added in r692, replaced with playCount in r1105.
+t('currentLoop'); // added in r692, removed in r2401.
+t('addCuePoint'); // added in r721, replaced with addCueRange in r1106.
+t('removeCuePoint'); // added in r721, replaced with removeCueRanges in r1106.
+t('playCount'); // added in r1105, removed in r2401.
+t('addCueRange'); // added in r1106, removed in r5070.
+t('removeCueRanges'); // added in r1106, removed in r5070.
+t('pixelratio', 'source'); // added in r1629, removed in r2493.
+t('bufferedBytes'); // added in r1630, removed in r2405.
+t('totalBytes'); // added in r1630, removed in r2405.
+t('bufferingThrottled'); // added in r1632, removed in r2872.
+t('autobuffer'); // added in r2855, replaced with preload in r4811.
+t('startTime'); // added in r3035, replaced with initialTime in r5310.
+t('startOffsetTime'); // added in r5310, replaced with startDate in r7045.
+t('initialTime'); // added in r5310, removed in r7046.
+t('audio', 'video'); // added in r5636, replaced with muted in r5991.
+t('startDate'); // added in r7045, replaced with getStartDate() in r8113.
+
+// TextTrackCue constructor: added in r5723, removed in r7742.
+test(function() {
+ assert_throws(new TypeError(), function() {
+ new TextTrackCue(0, 0, '');
+ });
+}, 'TextTrackCue constructor should not be supported');
+
+// added in https://github.com/whatwg/html/commit/66c5b32240c202c74f475872e7ea2cd163777b4a
+// removed in https://github.com/whatwg/html/commit/634698e70ea4586d58c989fa7d2cbfcad20d33e6
+t('mediaGroup');
+t('controller');
+test(function() {
+ assert_false('MediaController' in window);
+}, 'MediaController constructor should not be supported');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack.html
new file mode 100644
index 000000000..2a76b0a66
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack.html
@@ -0,0 +1,116 @@
+<!doctype html>
+<title>HTMLMediaElement.addTextTrack</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+var video = document.createElement('video');
+test(function(){
+ assert_throws(new TypeError(), function(){
+ video.addTextTrack('foo');
+ });
+ assert_throws(new TypeError(), function(){
+ video.addTextTrack(undefined);
+ });
+ assert_throws(new TypeError(), function(){
+ video.addTextTrack(null);
+ });
+}, document.title + ' bogus first arg');
+
+test(function(){
+ assert_throws(new TypeError(), function(){
+ video.addTextTrack('SUBTITLES');
+ });
+}, document.title + ' uppercase first arg');
+
+test(function(){
+ var t = video.addTextTrack('subtitles');
+ assert_equals(t.kind, 'subtitles');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' subtitles first arg');
+
+test(function(){
+ var t = video.addTextTrack('captions');
+ assert_equals(t.kind, 'captions');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' captions first arg');
+
+test(function(){
+ var t = video.addTextTrack('descriptions');
+ assert_equals(t.kind, 'descriptions');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' descriptions first arg');
+
+test(function(){
+ var t = video.addTextTrack('chapters');
+ assert_equals(t.kind, 'chapters');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' chapters first arg');
+
+test(function(){
+ var t = video.addTextTrack('metadata');
+ assert_equals(t.kind, 'metadata');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' metadata first arg');
+
+test(function(){
+ var t = video.addTextTrack('subtitles', undefined, undefined);
+ assert_equals(t.kind, 'subtitles');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' undefined second and third arg');
+
+test(function(){
+ var t = video.addTextTrack('subtitles', null, null);
+ assert_equals(t.kind, 'subtitles');
+ assert_equals(t.label, 'null');
+ assert_equals(t.language, 'null');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' null second and third arg');
+
+test(function(){
+ var t = video.addTextTrack('subtitles', 'foo', 'bar');
+ assert_equals(t.kind, 'subtitles');
+ assert_equals(t.label, 'foo');
+ assert_equals(t.language, 'bar');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' foo and bar second and third arg');
+
+test(function(){
+ var t = video.addTextTrack('subtitles', 'foo');
+ assert_equals(t.kind, 'subtitles');
+ assert_equals(t.label, 'foo');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' foo second arg, third arg omitted');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/textTracks.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/textTracks.html
new file mode 100644
index 000000000..0f183b7e1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/textTracks.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>HTMLMediaElement.textTracks</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+var video = document.createElement('video');
+test(function(){
+ assert_equals(video.textTracks, video.textTracks);
+ assert_equals(video.textTracks.length, 0);
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/default.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/default.html
new file mode 100644
index 000000000..05fd0f7f7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/default.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<title>HTMLTrackElement.default</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track['default'], false);
+ assert_equals(track.getAttribute('default'), null);
+}, document.title + ' missing value');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('default', '');
+ assert_equals(track['default'], true);
+ assert_equals(track.getAttribute('default'), '');
+}, document.title + ' empty string content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track['default'] = '';
+ assert_equals(track['default'], false);
+ assert_equals(track.getAttribute('default'), null);
+}, document.title + ' empty string IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('default', 'foo');
+ assert_equals(track['default'], true);
+ assert_equals(track.getAttribute('default'), 'foo');
+}, document.title + ' foo in content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track['default'] = 'foo';
+ assert_equals(track['default'], true);
+ assert_equals(track.getAttribute('default'), '');
+}, document.title + ' foo in IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track['default'] = true;
+ assert_equals(track['default'], true);
+ assert_equals(track.getAttribute('default'), '');
+}, document.title + ' true in IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('default', '');
+ track['default'] = false;
+ assert_equals(track['default'], false);
+ assert_equals(track.getAttribute('default'), null);
+}, document.title + ' false in IDL attribute');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html
new file mode 100644
index 000000000..78c3bff51
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html
@@ -0,0 +1,146 @@
+<!doctype html>
+<title>HTMLTrackElement.kind</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.kind, 'subtitles');
+ assert_equals(track.getAttribute('kind'), null);
+}, document.title + ' missing value');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'invalid');
+ assert_equals(track.kind, 'metadata');
+ assert_equals(track.getAttribute('kind'), 'invalid');
+}, document.title + ' invalid value in content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'CAPTIONS');
+ assert_equals(track.kind, 'captions');
+ assert_equals(track.getAttribute('kind'), 'CAPTIONS');
+}, document.title + ' content attribute uppercase');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'CAPT\u0130ONS');
+ assert_equals(track.kind, 'metadata');
+ assert_equals(track.getAttribute('kind'), 'CAPT\u0130ONS');
+}, document.title + ' content attribute with uppercase turkish I (with dot)');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'capt\u0131ons');
+ assert_equals(track.kind, 'metadata');
+ assert_equals(track.getAttribute('kind'), 'capt\u0131ons');
+}, document.title + ' content attribute with lowercase turkish i (dotless)');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'subtitles');
+ assert_equals(track.kind, 'subtitles');
+ assert_equals(track.getAttribute('kind'), 'subtitles');
+}, document.title + ' content attribute "subtitles"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'captions');
+ assert_equals(track.kind, 'captions');
+ assert_equals(track.getAttribute('kind'), 'captions');
+}, document.title + ' content attribute "captions"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'descriptions');
+ assert_equals(track.kind, 'descriptions');
+ assert_equals(track.getAttribute('kind'), 'descriptions');
+}, document.title + ' content attribute "descriptions"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'chapters');
+ assert_equals(track.kind, 'chapters');
+ assert_equals(track.getAttribute('kind'), 'chapters');
+}, document.title + ' content attribute "chapters"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'metadata');
+ assert_equals(track.kind, 'metadata');
+ assert_equals(track.getAttribute('kind'), 'metadata');
+}, document.title + ' content attribute "metadata"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'captions\u0000');
+ assert_equals(track.kind, 'metadata');
+ assert_equals(track.getAttribute('kind'), 'captions\u0000');
+}, document.title + ' content attribute "captions\\u0000"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'subtitles';
+ assert_equals(track.getAttribute('kind'), 'subtitles');
+ assert_equals(track.kind, 'subtitles');
+}, document.title + ' setting IDL attribute to "subtitles"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'captions';
+ assert_equals(track.getAttribute('kind'), 'captions');
+ assert_equals(track.kind, 'captions');
+}, document.title + ' setting IDL attribute to "captions"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'descriptions';
+ assert_equals(track.getAttribute('kind'), 'descriptions');
+ assert_equals(track.kind, 'descriptions');
+}, document.title + ' setting IDL attribute to "descriptions"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'chapters';
+ assert_equals(track.getAttribute('kind'), 'chapters');
+ assert_equals(track.kind, 'chapters');
+}, document.title + ' setting IDL attribute to "chapters"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'metadata';
+ assert_equals(track.getAttribute('kind'), 'metadata');
+ assert_equals(track.kind, 'metadata');
+}, document.title + ' setting IDL attribute to "metadata"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'CAPTIONS';
+ assert_equals(track.getAttribute('kind'), 'CAPTIONS');
+ assert_equals(track.kind, 'captions');
+}, document.title + ' setting IDL attribute to "CAPTIONS"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'CAPT\u0130ONS';
+ assert_equals(track.getAttribute('kind'), 'CAPT\u0130ONS');
+ assert_equals(track.kind, 'metadata');
+}, document.title + ' setting IDL attribute with uppercase turkish I (with dot)');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'capt\u0131ons';
+ assert_equals(track.getAttribute('kind'), 'capt\u0131ons');
+ assert_equals(track.kind, 'metadata');
+}, document.title + ' setting IDL attribute with lowercase turkish I (dotless)');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'captions\u0000';
+ assert_equals(track.getAttribute('kind'), 'captions\u0000');
+ assert_equals(track.kind, 'metadata');
+}, document.title + ' setting IDL attribute with \\u0000');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/label.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/label.html
new file mode 100644
index 000000000..b2360315c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/label.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<title>HTMLTrackElement.label</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.label, '');
+ assert_equals(track.getAttribute('label'), null);
+}, document.title + ' missing value');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('label', '');
+ assert_equals(track.label, '');
+ assert_equals(track.getAttribute('label'), '');
+}, document.title + ' empty string content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.label = '';
+ assert_equals(track.label, '');
+ assert_equals(track.getAttribute('label'), '');
+}, document.title + ' empty string IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('label', 'foo');
+ assert_equals(track.label, 'foo');
+ assert_equals(track.getAttribute('label'), 'foo');
+}, document.title + ' lowercase content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('label', 'FOO');
+ assert_equals(track.label, 'FOO');
+ assert_equals(track.getAttribute('label'), 'FOO');
+}, document.title + ' uppercase content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('label', '\u0000');
+ assert_equals(track.label, '\u0000');
+ assert_equals(track.getAttribute('label'), '\u0000');
+}, document.title + '\\u0000 in content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.label = 'foo';
+ assert_equals(track.label, 'foo');
+ assert_equals(track.getAttribute('label'), 'foo');
+}, document.title + ' lowercase IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.label = 'FOO';
+ assert_equals(track.label, 'FOO');
+ assert_equals(track.getAttribute('label'), 'FOO');
+}, document.title + ' uppercase IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('label', ' foo \n');
+ assert_equals(track.label, ' foo \n');
+ assert_equals(track.getAttribute('label'), ' foo \n');
+}, document.title + ' whitespace in content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.label = ' foo \n';
+ assert_equals(track.label, ' foo \n');
+ assert_equals(track.getAttribute('label'), ' foo \n');
+}, document.title + ' whitespace in IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.label = '\u0000';
+ assert_equals(track.label, '\u0000');
+ assert_equals(track.getAttribute('label'), '\u0000');
+}, document.title + ' \\u0000 in IDL attribute');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/readyState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/readyState.html
new file mode 100644
index 000000000..e18f21934
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/readyState.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>HTMLTrackElement.readyState</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.readyState, 0);
+}, document.title + ' default value');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src.html
new file mode 100644
index 000000000..4089913cb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<title>HTMLTrackElement.src</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.src, '');
+ assert_equals(track.getAttribute('src'), null);
+}, document.title + ' missing value');
+
+function resolve(url) {
+ var link = document.createElement('a');
+ link.setAttribute('href', url);
+ return link.href;
+}
+
+var tests = [
+ {input:'', expectedIDL:resolve(''), desc:'empty string'},
+ {input:'http://foo bar', expectedIDL:'http://foo bar', desc:'unresolvable value'},
+ {input:'test', expectedIDL:resolve('test'), desc:'resolvable value'},
+ // Leading and trailing C0 controls and space is stripped per url spec.
+ {input:'\u0000', expectedIDL:resolve(''), desc:'\\u0000'},
+ {input:'foo\u0000bar', expectedIDL:resolve('foo%00bar'), desc:'foo\\u0000bar'},
+];
+
+tests.forEach(function(t) {
+ test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('src', t.input);
+ assert_equals(track.src, t.expectedIDL);
+ assert_equals(track.getAttribute('src'), t.input);
+ }, [document.title, t.desc, 'in content attribute'].join(' '));
+
+ test(function(){
+ var track = document.createElement('track');
+ track.src = t.input;
+ assert_equals(track.src, t.expectedIDL);
+ assert_equals(track.getAttribute('src'), t.input);
+ }, [document.title, 'assigning', t.desc, 'to IDL attribute'].join(' '));
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang.html
new file mode 100644
index 000000000..b5071e0c3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<title>HTMLTrackElement.srclang</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.srclang, '');
+ assert_equals(track.getAttribute('srclang'), null);
+}, document.title + ' missing value');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('srclang', '');
+ assert_equals(track.srclang, '');
+ assert_equals(track.getAttribute('srclang'), '');
+}, document.title + ' empty string content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.srclang = '';
+ assert_equals(track.srclang, '');
+ assert_equals(track.getAttribute('srclang'), '');
+}, document.title + ' empty string IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('srclang', 'foo');
+ assert_equals(track.srclang, 'foo');
+ assert_equals(track.getAttribute('srclang'), 'foo');
+}, document.title + ' lowercase content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('srclang', 'FOO');
+ assert_equals(track.srclang, 'FOO');
+ assert_equals(track.getAttribute('srclang'), 'FOO');
+}, document.title + ' uppercase content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('srclang', '\u0000');
+ assert_equals(track.srclang, '\u0000');
+ assert_equals(track.getAttribute('srclang'), '\u0000');
+}, document.title + ' \\u0000 content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.srclang = 'foo';
+ assert_equals(track.srclang, 'foo');
+ assert_equals(track.getAttribute('srclang'), 'foo');
+}, document.title + ' lowercase IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.srclang = 'FOO';
+ assert_equals(track.srclang, 'FOO');
+ assert_equals(track.getAttribute('srclang'), 'FOO');
+}, document.title + ' uppercase IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('srclang', ' foo \n');
+ assert_equals(track.srclang, ' foo \n');
+ assert_equals(track.getAttribute('srclang'), ' foo \n');
+}, document.title + ' whitespace in content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.srclang = ' foo \n';
+ assert_equals(track.srclang, ' foo \n');
+ assert_equals(track.getAttribute('srclang'), ' foo \n');
+}, document.title + ' whitespace in IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.srclang = '\u0000';
+ assert_equals(track.srclang, '\u0000');
+ assert_equals(track.getAttribute('srclang'), '\u0000');
+}, document.title + ' \\u0000 in IDL attribute');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/track.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/track.html
new file mode 100644
index 000000000..1de0a8804
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/track.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>HTMLTrackElement.track</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.track, track.track, 'same object should be returned');
+ assert_true(track.track instanceof TextTrack, 'returned object should be a TextTrack');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/activeCues.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/activeCues.html
new file mode 100644
index 000000000..689ec12be
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/activeCues.html
@@ -0,0 +1,104 @@
+<!doctype html>
+<title>TextTrack.activeCues</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/common/media.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ window.track = document.createElement('track');
+ track['default'] = true;
+ video.appendChild(track);
+ window.t2 = track.track;
+ t2.mode = 'showing';
+ window.t1_cues = t1.activeCues;
+ window.t2_cues = t2.activeCues;
+ document.body.appendChild(video);
+ if (!t1)
+ throw new Error('t1 was undefined')
+}, {timeout:25000});
+function smoke_test() {
+ assert_true('HTMLTrackElement' in window, 'track not supported');
+}
+
+test(function(){
+ smoke_test();
+ assert_equals(t1.activeCues, t1_cues, 't1.activeCues should return same object');
+ assert_equals(t2.activeCues, t2_cues, 't2.activeCues should return same object');
+ assert_not_equals(t1.activeCues, t2.activeCues, 't1.activeCues and t2.activeCues should be different objects');
+ assert_not_equals(t1.activeCues, null, 't1.activeCues should not be null');
+ assert_not_equals(t2.activeCues, null, 't2.activeCues should not be null');
+ assert_equals(t1.activeCues.length, 0, 't1.activeCues should have length 0');
+ assert_equals(t2.activeCues.length, 0, 't2.activeCues should have length 0');
+}, document.title+', empty list');
+test(function(){
+ smoke_test();
+ var c = new VTTCue(0, 1, "text");
+ t1.addCue(c);
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return same object");
+ assert_equals(t1.activeCues.length, 0, "t1.activeCues.length");
+ var c2 = new VTTCue(1, 2, "text2");
+ t1.addCue(c2);
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return the same object after adding a second cue");
+ assert_equals(t1.activeCues.length, 0, "t1.activeCues.length after adding a second cue");
+}, document.title+', after addCue()');
+test(function(){
+ smoke_test();
+ t1.mode = 'showing';
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return the same object after setting mode to showing");
+ t1.mode = 'hidden';
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return the same object after setting mode to hidden");
+ t1.mode = 'disabled';
+ assert_equals(t1.activeCues, null, "t1.activeCues should be null when mode is disabled");
+ assert_equals(t1_cues.length, 0, "t1_cues should still be intact after setting mode to disabled");
+}, document.title+', different modes');
+
+// ok now let's load in a video
+var test1 = async_test(document.title+', video loading', {timeout:20000});
+var test2 = async_test(document.title+', video playing', {timeout:20000});
+var test3 = async_test(document.title+', adding cue during playback', {timeout:20000});
+test1.step(smoke_test);
+test2.step(smoke_test);
+test3.step(smoke_test);
+test1.step(function(){
+ t1.mode = 'showing';
+ video.onloadeddata = test1.step_func(function(e) {
+ video.onplaying = test2.step_func(function(e) {
+ try {
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return the same object after playing a video");
+ assert_equals(t1.activeCues.length, 1, "t1.activeCues.length after the video has started playing");
+ } catch(ex) {
+ test2.step(function() { throw ex; });
+ test3.step(function() { assert_unreached(); });
+ return;
+ }
+ test3.step(function(){
+ var c3 = new VTTCue(0, 2, "text3");
+ t1.addCue(c3);
+ assert_equals(t1.activeCues.length, 1, "t1.activeCues.length after adding a cue in the same script");
+ setTimeout(test3.step_func(function(){
+ assert_equals(t1.activeCues.length, 2, "t1.activeCues.length after the event loop has spun");
+ test3.done();
+ }, 0));
+ });
+ test2.done();
+ });
+ try {
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return the same object after loading a video");
+ assert_equals(t2.activeCues, t2_cues, "t2.activeCues should return the same object after loading a video");
+ assert_equals(t1.activeCues.length, 0, "t1.activeCues.length before the video has started playing");
+ assert_equals(t2.activeCues.length, 0, "t1.activeCues.length before the video has started playing");
+ } catch(ex) {
+ test1.step(function() { throw ex; });
+ test2.step(function() { assert_unreached(); });
+ test3.step(function() { assert_unreached(); });
+ return;
+ }
+ video.play();
+ test1.done();
+ });
+ video.src = getVideoURI("/media/movie_5");
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/addCue.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/addCue.html
new file mode 100644
index 000000000..267941334
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/addCue.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<title>TextTrack.addCue()</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ document.body.appendChild(video);
+}, {timeout:5000});
+test(function() {
+ var t1 = video.addTextTrack('subtitles');
+ var t2 = video.addTextTrack('subtitles');
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ t2.addCue(c1);
+ assert_equals(c1.track, t2);
+}, document.title+', adding a cue to two different tracks');
+test(function() {
+ var t1 = video.addTextTrack('subtitles');
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(c1.track, t1);
+ t1.addCue(c1);
+ assert_equals(c1.track, t1);
+}, document.title+', adding a cue to a track twice');
+test(function() {
+ var t1 = video.addTextTrack('subtitles');
+ var t2 = video.addTextTrack('subtitles');
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(c1.track, t1);
+ t1.removeCue(c1);
+ assert_equals(c1.track, null);
+ t2.addCue(c1);
+ assert_equals(c1.track, t2);
+}, document.title+', adding a removed cue to a different track');
+test(function() {
+ var t1 = video.addTextTrack('subtitles');
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(t1.cues.length, 1, 't1.cues.length after first addition');
+ t1.removeCue(c1);
+ assert_equals(t1.cues.length, 0, 't1.cues.length after removal');
+ t1.addCue(c1);
+ assert_equals(t1.cues.length, 1, 't1.cues.length after second addition');
+}, document.title+', adding an associated but removed cue to the same track');
+
+var t = async_test(document.title+', adding a cue associated with a track element to other track');
+t.step(function(){
+ var t1 = video.addTextTrack('subtitles');
+ var track = document.createElement('track');
+ track.onload = t.step_func(function(){
+ var cue = track.track.cues[0];
+ track.track.removeCue(cue);
+ t1.addCue(cue);
+ assert_equals(cue.track, t1);
+ t.done();
+ });
+ track.onerror = t.step_func(function() {
+ assert_unreached('got error event');
+ });
+ track.src= 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:01.000\ntest\n');
+ track.kind = 'subtitles';
+ track.track.mode = 'hidden';
+ video.appendChild(track);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/constants.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/constants.html
new file mode 100644
index 000000000..3c8046cdc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/constants.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>TextTrack constants</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+});
+test(function(){
+ assert_equals(t1.DISABLED, undefined, "t1.DISABLED");
+ assert_equals(t1.HIDDEN, undefined, "t1.HIDDEN");
+ assert_equals(t1.SHOWING, undefined, "t1.SHOWING");
+ assert_equals(TextTrack.prototype.DISABLED, undefined, "TextTrack.prototype.DISABLED");
+ assert_equals(TextTrack.prototype.HIDDEN, undefined, "TextTrack.prototype.HIDDEN");
+ assert_equals(TextTrack.prototype.SHOWING, undefined, "TextTrack.prototype.SHOWING");
+ assert_equals(TextTrack.DISABLED, undefined, "TextTrack.DISABLED");
+ assert_equals(TextTrack.HIDDEN, undefined, "TextTrack.HIDDEN");
+ assert_equals(TextTrack.SHOWING, undefined, "TextTrack.SHOWING");
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues.html
new file mode 100644
index 000000000..4b7808c96
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues.html
@@ -0,0 +1,100 @@
+<!doctype html>
+<title>TextTrack.cues</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ assert_equals(t1.cues, t1.cues, 't1.cues should return same object');
+ assert_not_equals(t1.cues, null, 't1.cues should not be null');
+ assert_true(t1.cues instanceof TextTrackCueList, 't1.cues instanceof TextTrackCueList');
+ assert_equals(t1.cues.length, 0, 't1.cues.length');
+}, document.title+', empty list');
+
+function addCue(texttrack, start, end, text, id) {
+ var c = new VTTCue(start, end, text);
+ c.id = id;
+ texttrack.addCue(c);
+ return c;
+}
+
+test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ var t1_cues = t1.cues;
+ var c = addCue(t1, 0, 1, 'text', 'id');
+ assert_equals(t1.cues, t1_cues, "t1.cues should return same object");
+ assert_equals(t1.cues.length, 1, "t1.cues.length");
+ var c2 = addCue(t1, 1, 2, 'text2', 'id2');
+ assert_equals(t1.cues, t1_cues, "t1.cues should return the same object after adding a second cue");
+ assert_equals(t1.cues.length, 2, "t1.cues.length after adding a second cue");
+ assert_equals(t1.cues[0].id, "id");
+ assert_equals(t1.cues[1].id, "id2");
+}, document.title+', after addCue()');
+
+test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ var t1_cues = t1.cues;
+ var c = addCue(t1, 0, 1, 'text', 'id');
+ var c2 = addCue(t1, 1, 2, 'text2', 'id2');
+ t1.mode = 'showing';
+ assert_equals(t1.cues, t1_cues, "t1.cues should return the same object after setting mode to 'showing'");
+ t1.mode = 'hidden';
+ assert_equals(t1.cues, t1_cues, "t1.cues should return the same object after setting mode to 'hidden'");
+ t1.mode = 'disabled';
+ assert_equals(t1.cues, null, "t1.cues should be null when mode is 'disabled'");
+ assert_equals(t1_cues.length, 2, "t1_cues should still be intact after setting mode to 'disabled'");
+ assert_equals(t1_cues[0].id, "id", "t1_cues first cue should still be intact after setting mode to 'disabled'");
+ assert_equals(t1_cues[1].id, "id2", "t1_cues second cue should still be intact after setting mode to 'disabled'");
+ t1.mode = 'hidden';
+ assert_equals(t1.cues, t1_cues, "t1.cues should return the same object after setting mode to 'disabled' and then 'hidden'");
+ t1.mode = 'disabled';
+ assert_equals(t1.cues, null, "t1.cues should be null when mode is set to 'disabled' again");
+ assert_equals(t1_cues.length, 2, "t1_cues should still be intact after setting mode to 'disabled' again");
+ assert_equals(t1_cues[0].id, "id", "t1_cues first cue should still be intact after setting mode to 'disabled' again");
+ assert_equals(t1_cues[1].id, "id2", "t1_cues second cue should still be intact after setting mode to 'disabled' again");
+ t1.mode = 'showing';
+ assert_equals(t1.cues, t1_cues, "t1.cues should return the same object after setting mode to 'disabled' and then 'showing'");
+}, document.title+', different modes');
+
+test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ var t1_cues = t1.cues;
+ var c = addCue(t1, 0, 1, 'text', 'id');
+ var c2 = addCue(t1, 1, 2, 'text2', 'id2');
+ t1.mode = 'showing';
+ t1.cues[1].startTime = 0; // this should change the text track cue order
+ assert_equals(t1.cues[0].id, 'id2');
+ assert_equals(t1.cues[1].id, 'id');
+ t1.cues[0].startTime = 0.5; // this should change it back
+ assert_equals(t1.cues[0].id, 'id');
+ assert_equals(t1.cues[1].id, 'id2');
+}, document.title+', changing order');
+
+async_test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ var t1_cues = t1.cues;
+ t1.mode = 'hidden';
+ var track = document.createElement('track');
+ track['default'] = true;
+ video.appendChild(track); // queues a task to "honor user preferences...", media element event task source
+ var t2 = track.track;
+ assert_equals(t2.cues, null, 't2.cues should be null');
+ // We need to wait until the "honor user preferences..." steps have run so we invoke play()
+ // which queues an event with the same task source.
+ video.onplay = this.step_func(function(){
+ assert_equals(t2.cues, t2.cues, 't2.cues should return same object');
+ assert_not_equals(t1.cues, t2.cues, 't1.cues and t2.cues should be different objects');
+ assert_not_equals(t2.cues, null, 't2.cues should not be null');
+ assert_true(t2.cues instanceof TextTrackCueList, 't2.cues instanceof TextTrackCueList');
+ assert_equals(t2.cues.length, 0, 't2.cues should have length 0');
+ this.done();
+ });
+ video.play(); // queues a task to fire 'play', media element event task source
+}, document.title+', default attribute');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html
new file mode 100644
index 000000000..d5dbc8342
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>TextTrack.kind</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ var t2 = video.addTextTrack('captions');
+ var t3 = video.addTextTrack('descriptions');
+ var t4 = video.addTextTrack('chapters');
+ var t5 = video.addTextTrack('metadata');
+ assert_equals(t1.kind, 'subtitles');
+ assert_equals(t2.kind, 'captions');
+ assert_equals(t3.kind, 'descriptions');
+ assert_equals(t4.kind, 'chapters');
+ assert_equals(t5.kind, 'metadata');
+}, document.title+', addTextTrack');
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'CAPTIONS');
+ var t = track.track;
+ assert_equals(t.kind, 'captions');
+}, document.title+', track element');
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'captions\u0000';
+ assert_equals(track.track.kind, 'metadata');
+}, document.title+', \\u0000');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/label.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/label.html
new file mode 100644
index 000000000..c60e85c21
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/label.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>TextTrack.label</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles', 'foo');
+ window.track = document.createElement('track');
+ track.setAttribute('label', 'bar');
+ video.appendChild(track);
+ window.t2 = track.track;
+});
+test(function(){
+ assert_equals(t1.label, 'foo');
+ assert_equals(t2.label, 'bar');
+ track.label = 'baz';
+ assert_equals(t2.label, 'baz');
+ track.removeAttribute('label');
+ assert_equals(t2.label, '');
+});
+test(function(){
+ track.label = '\u0000a';
+ assert_equals(t2.label, '\u0000a');
+ track.setAttribute('label', '\u0000b', 'IDL attribute');
+ assert_equals(t2.label, '\u0000b', 'content attribute');
+}, document.title+', \\u0000');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language.html
new file mode 100644
index 000000000..eda3653de
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>TextTrack.language</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles', 'foo', 'foo');
+ window.track = document.createElement('track');
+ track.setAttribute('srclang', 'bar');
+ video.appendChild(track);
+ window.t2 = track.track;
+});
+test(function(){
+ assert_equals(t1.language, 'foo');
+ assert_equals(t2.language, 'bar');
+ track.srclang = 'baz';
+ assert_equals(t2.language, 'baz');
+ track.removeAttribute('srclang');
+ assert_equals(t2.language, '');
+});
+test(function(){
+ track.srclang = '\u0000a';
+ assert_equals(t2.language, '\u0000a', 'IDL attribute');
+ track.setAttribute('srclang', '\u0000b');
+ assert_equals(t2.language, '\u0000b', 'content attribute');
+}, document.title+', \\u0000');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode.html
new file mode 100644
index 000000000..9f9415670
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<title>TextTrack.mode</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.track.mode, 'disabled', 'initial');
+ track.track.mode = 1;
+ assert_equals(track.track.mode, 'disabled', '1');
+ track.track.mode = '';
+ assert_equals(track.track.mode, 'disabled', '""');
+ track.track.mode = null;
+ assert_equals(track.track.mode, 'disabled', 'null');
+ track.track.mode = undefined;
+ assert_equals(track.track.mode, 'disabled', 'undefined');
+ track.track.mode = 'showing';
+ assert_equals(track.track.mode, 'showing', 'showing (correct value)');
+ track.track.mode = 'DISABLED';
+ assert_equals(track.track.mode, 'showing', '"DISABLED"');
+ track.track.mode = 'd\u0130sabled'; // dotted uppercase i
+ assert_equals(track.track.mode, 'showing', '"d\u0130sabled" (dotted uppercase i)');
+ track.track.mode = 'd\u0131sabled'; // dotless lowercase i
+ assert_equals(track.track.mode, 'showing', '"d\u0131sabled" (dotless lowercase i)');
+ track.track.mode = 'disabled ';
+ assert_equals(track.track.mode, 'showing', '"disabled "');
+ track.track.mode = ' disabled';
+ assert_equals(track.track.mode, 'showing', '" disabled"');
+ track.track.mode = {};
+ assert_equals(track.track.mode, 'showing', '{}');
+ track.track.mode = 'HIDDEN';
+ assert_equals(track.track.mode, 'showing', '"HIDDEN"');
+ track.track.mode = 'h\u0130dden'; // dotted uppercase i
+ assert_equals(track.track.mode, 'showing', '"h\u0130dden" (dotted uppercase i)');
+ track.track.mode = 'h\u0131dden'; // dotless lowercase i
+ assert_equals(track.track.mode, 'showing', '"h\u0131dden" (dotless lowercase i)');
+}, document.title+', wrong value');
+test(function() {
+ var track = document.createElement('track');
+ assert_equals(track.track.mode, 'disabled', 'initial');
+ track.track.mode = 'disabled'; // no-op
+ assert_equals(track.track.mode, 'disabled', 'disabled (1)');
+ track.track.mode = 'hidden';
+ assert_equals(track.track.mode, 'hidden', 'hidden (1)');
+ track.track.mode = 'hidden'; // no-op
+ assert_equals(track.track.mode, 'hidden', 'hidden (2)');
+ track.track.mode = 'showing';
+ assert_equals(track.track.mode, 'showing', 'showing (1)');
+ track.track.mode = 'showing'; // no-op
+ assert_equals(track.track.mode, 'showing', 'showing (2)');
+ track.track.mode = {toString:function() { return 'disabled'; }};
+ assert_equals(track.track.mode, 'disabled', '{toString:...}');
+}, document.title+', correct value');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/oncuechange.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/oncuechange.html
new file mode 100644
index 000000000..16c76f948
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/oncuechange.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>TextTrack.oncuechange</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ window.ev = new Event('cuechange');
+ window.ran = false;
+ window.cb = function() { ran = true; };
+});
+test(function(){
+ assert_equals(t1.oncuechange, null);
+ t1.oncuechange = cb;
+ t1.dispatchEvent(ev);
+ assert_true(ran);
+ t1.oncuechange = null;
+ ran = false;
+ t1.dispatchEvent(ev);
+ assert_false(ran);
+});
+test(function(){
+ t1.addEventListener('cuechange', cb, false);
+ t1.dispatchEvent(ev);
+ assert_true(ran);
+ t1.removeEventListener('cuechange', cb, false);
+ ran = false;
+ t1.dispatchEvent(ev);
+ assert_false(ran);
+}, 'TextTrack.addEventListener/removeEventListener');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/removeCue.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/removeCue.html
new file mode 100644
index 000000000..3623f44bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/removeCue.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<title>TextTrack.removeCue()</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ document.body.appendChild(video);
+}, {timeout:5000});
+test(function() {
+ var t1 = video.addTextTrack('subtitles');
+ var t2 = video.addTextTrack('subtitles');
+ var c1 = new VTTCue(0, 1, 'text1');
+ assert_throws("NOT_FOUND_ERR", function() {
+ t1.removeCue(c1);
+ }, 'standalone');
+ t1.addCue(c1);
+ assert_throws("NOT_FOUND_ERR", function() {
+ t2.removeCue(c1);
+ }, 'listed in t1, remove from t2');
+ t1.removeCue(c1);
+ assert_throws("NOT_FOUND_ERR", function() {
+ t1.removeCue(c1);
+ }, 'standalone, remove from t1');
+ assert_throws("NOT_FOUND_ERR", function() {
+ t2.removeCue(c1);
+ }, 'standalone, remove from t2');
+}, document.title+', two elementless tracks');
+var t = async_test(document.title+', cue from track element');
+t.step(function(){
+ var t1 = video.addTextTrack('subtitles');
+ var track = document.createElement('track');
+ track.onload = t.step_func(function(){
+ var cue = track.track.cues[0];
+ assert_throws('NOT_FOUND_ERR', function() { t1.removeCue(cue); }, 'listed in track.track, remove from t1');
+ track.track.removeCue(cue);
+ assert_throws('NOT_FOUND_ERR', function() { track.track.removeCue(cue); }, 'standalone, remove from track.track');
+ assert_throws('NOT_FOUND_ERR', function() { t1.removeCue(cue); }, 'standalone, remove from t1');
+ t.done();
+ });
+ track.onerror = t.step_func(function() {
+ assert_unreached('got error event');
+ });
+ track.src= 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:01.000\ntest\n');
+ track.kind = 'subtitles';
+ track.track.mode = 'hidden';
+ video.appendChild(track);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/endTime.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/endTime.html
new file mode 100644
index 000000000..b99a12e05
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/endTime.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>TextTrackCue.endTime</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var c1 = new VTTCue(-2, -1, 'text1');
+ assert_equals(c1.endTime, -1);
+ c1.endTime = c1.endTime;
+ assert_equals(c1.endTime, -1);
+ assert_throws(new TypeError(), function(){ c1.endTime = NaN; });
+ assert_throws(new TypeError(), function(){ c1.endTime = +Infinity; });
+ assert_throws(new TypeError(), function(){ c1.endTime = -Infinity; });
+}, document.title+', script-created cue');
+
+var t_parsed = async_test(document.title+', parsed cue');
+t_parsed.step(function(){
+ var t = document.createElement('track');
+ t.onload = this.step_func(function(){
+ var c = t.track.cues;
+ assert_equals(c[0].endTime, 0.001);
+ assert_equals(c[1].endTime, 3600.001);
+ this.done();
+ });
+ t.onerror = this.step_func(function() {
+ assert_unreached('got error event');
+ });
+ t.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:00.001\ntest'+
+ '\n\nfoobar\n01:00:00.000 --> 01:00:00.001\ntest');
+ t.track.mode = 'showing';
+ video.appendChild(t);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/id.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/id.html
new file mode 100644
index 000000000..a88f94766
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/id.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>TextTrackCue.id</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var c1 = new VTTCue(0, 1, 'text1');
+ c1.id = 'id1\r\n\u0000';
+ assert_equals(c1.id, 'id1\r\n\u0000');
+ c1.id = c1.id;
+ assert_equals(c1.id, 'id1\r\n\u0000');
+ c1.id = null;
+ assert_equals(c1.id, 'null');
+}, document.title+', script-created cue');
+
+var t_parsed = async_test(document.title+', parsed cue');
+t_parsed.step(function(){
+ var t = document.createElement('track');
+ t.onload = this.step_func(function(){
+ var c = t.track.cues;
+ assert_equals(c[0].id, '');
+ assert_equals(c[1].id, 'foobar');
+ this.done();
+ });
+ t.onerror = this.step_func(function() {
+ assert_unreached('got error event');
+ });
+ t.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:00.001\ntest'+
+ '\n\nfoobar\n00:00:00.000 --> 00:00:00.001\ntest');
+ t.track.mode = 'showing';
+ video.appendChild(t);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onenter.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onenter.html
new file mode 100644
index 000000000..17deed053
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onenter.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<title>TextTrackCue.onenter</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.c1 = new VTTCue(0, 1, 'text1');
+ window.ev = new Event('enter');
+ window.ran = false;
+ window.cb = function() { ran = true; };
+});
+test(function(){
+ assert_equals(c1.onenter, null, 'initial value');
+ c1.onenter = undefined;
+ assert_equals(c1.onenter, null, 'assigning undefined');
+ c1.onenter = cb;
+ assert_equals(c1.onenter, cb, 'assigning onenter');
+ c1.dispatchEvent(ev);
+ assert_true(ran, 'dispatching event');
+ c1.onenter = null;
+ assert_equals(c1.onenter, null, 'assigning null');
+ ran = false;
+ c1.dispatchEvent(ev);
+ assert_false(ran, 'dispatching event after nulling onenter');
+});
+test(function(){
+ c1.addEventListener('enter', cb, false);
+ c1.dispatchEvent(ev);
+ assert_true(ran);
+ c1.removeEventListener('enter', cb, false);
+ ran = false;
+ c1.dispatchEvent(ev);
+ assert_false(ran);
+}, 'TextTrackCue.addEventListener/removeEventListener');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onexit.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onexit.html
new file mode 100644
index 000000000..815377e4d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onexit.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<title>TextTrackCue.onexit</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.c1 = new VTTCue(0, 1, 'text1');
+ window.ev = new Event('exit');
+ window.ran = false;
+ window.cb = function() { ran = true; };
+});
+test(function(){
+ assert_equals(c1.onexit, null, 'initial value');
+ c1.onexit = undefined;
+ assert_equals(c1.onexit, null, 'assigning undefined');
+ c1.onexit = cb;
+ assert_equals(c1.onexit, cb, 'assigning onexit');
+ c1.dispatchEvent(ev);
+ assert_true(ran, 'dispatching event');
+ c1.onexit = null;
+ assert_equals(c1.onexit, null, 'assigning null');
+ ran = false;
+ c1.dispatchEvent(ev);
+ assert_false(ran, 'dispatching event after nulling onexit');
+});
+test(function(){
+ c1.addEventListener('exit', cb, false);
+ c1.dispatchEvent(ev);
+ assert_true(ran);
+ c1.removeEventListener('exit', cb, false);
+ ran = false;
+ c1.dispatchEvent(ev);
+ assert_false(ran);
+}, 'TextTrackCue.addEventListener/removeEventListener');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/pauseOnExit.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/pauseOnExit.html
new file mode 100644
index 000000000..31ea4c63b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/pauseOnExit.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<title>TextTrackCue.pauseOnExit</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var c1 = new VTTCue(0, 1, 'text1');
+ assert_equals(c1.pauseOnExit, false);
+ c1.pauseOnExit = null;
+ assert_equals(c1.pauseOnExit, false);
+ c1.pauseOnExit = 'foo';
+ assert_equals(c1.pauseOnExit, true);
+}, document.title+', script-created cue');
+
+var t_parsed = async_test(document.title+', parsed cue');
+t_parsed.step(function(){
+ var t = document.createElement('track');
+ t.onload = this.step_func(function(){
+ var c1 = t.track.cues[0];
+ assert_equals(c1.pauseOnExit, false);
+ c1.pauseOnExit = null;
+ assert_equals(c1.pauseOnExit, false);
+ c1.pauseOnExit = 'foo';
+ assert_equals(c1.pauseOnExit, true);
+ this.done();
+ });
+ t.onerror = this.step_func(function() {
+ assert_unreached('got error event');
+ });
+ t.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:00.001\ntest');
+ t.track.mode = 'showing';
+ video.appendChild(t);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/startTime.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/startTime.html
new file mode 100644
index 000000000..232a7f23b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/startTime.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>TextTrackCue.startTime</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var c1 = new VTTCue(-1, 1, 'text1');
+ assert_equals(c1.startTime, -1);
+ c1.startTime = c1.startTime;
+ assert_equals(c1.startTime, -1);
+ assert_throws(new TypeError(), function(){ c1.startTime = NaN; });
+ assert_throws(new TypeError(), function(){ c1.startTime = +Infinity; });
+ assert_throws(new TypeError(), function(){ c1.startTime = -Infinity; });
+}, document.title+', script-created cue');
+
+var t_parsed = async_test(document.title+', parsed cue');
+t_parsed.step(function(){
+ var t = document.createElement('track');
+ t.onload = this.step_func(function(){
+ var c = t.track.cues;
+ assert_equals(c[0].startTime, 0);
+ assert_equals(c[1].startTime, 3600);
+ this.done();
+ });
+ t.onerror = this.step_func(function() {
+ assert_unreached('got error event');
+ });
+ t.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:00.001\ntest'+
+ '\n\nfoobar\n01:00:00.000 --> 01:00:00.001\ntest');
+ t.track.mode = 'showing';
+ video.appendChild(t);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/track.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/track.html
new file mode 100644
index 000000000..219e3e703
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/track.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>TextTrackCue.track</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var c1 = new VTTCue(0, 1, 'text1');
+ assert_equals(c1.track, null);
+ t1.addCue(c1);
+ assert_equals(c1.track, t1);
+ t1.removeCue(c1);
+ assert_equals(c1.track, null);
+}, document.title+', script-created cue');
+
+var t_parsed = async_test(document.title+', parsed cue');
+t_parsed.step(function(){
+ var t = document.createElement('track');
+ t.onload = this.step_func(function(){
+ var c = t.track.cues[0];
+ assert_equals(c.track, t.track);
+ t.track.removeCue(c);
+ assert_equals(c.track, null);
+ this.done();
+ });
+ t.onerror = this.step_func(function() {
+ assert_unreached('got error event');
+ });
+ t.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:00.001\ntest');
+ t.track.mode = 'showing';
+ video.appendChild(t);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getCueById.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getCueById.html
new file mode 100644
index 000000000..8184189b0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getCueById.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<title>TextTrackCueList.getCueById</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var video = document.createElement('video');
+ var t = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+ var cues = t.cues;
+ var c = new VTTCue(0, 1, 'text1');
+ t.addCue(c);
+ assert_equals(cues.getCueById(""), null, '""');
+ assert_equals(cues.getCueById(null), null, 'null');
+ assert_equals(cues.getCueById(undefined), null, 'undefined');
+}, document.title+ ', no id');
+test(function(){
+ var video = document.createElement('video');
+ var t = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+ var cues = t.cues;
+ var c = new VTTCue(0, 1, 'text1');
+ c.id = 'foo';
+ t.addCue(c);
+ assert_equals(cues.getCueById(""), null, '""');
+ assert_equals(cues.getCueById("foo"), c, '"foo"');
+ assert_equals(cues.getCueById({toString:function(){return "foo"}}), c, 'object');
+}, document.title+ ', id foo');
+test(function(){
+ var video = document.createElement('video');
+ var t = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+ var cues = t.cues;
+ var c = new VTTCue(0, 1, 'text1');
+ c.id = '1';
+ t.addCue(c);
+ assert_equals(cues.getCueById(""), null, '""');
+ assert_equals(cues.getCueById("1"), c, '"1"');
+ assert_equals(cues.getCueById(1), c, '1');
+}, document.title+ ', no 1');
+test(function(){
+ var video = document.createElement('video');
+ var t = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+ var cues = t.cues;
+ var c = new VTTCue(0, 1, 'text1');
+ c.id = 'a\u0000b';
+ t.addCue(c);
+ assert_equals(cues.getCueById("a\u0000b"), c, '"a\\u0000b"');
+ assert_equals(cues.getCueById("a"), null, '"a"');
+}, document.title+ ', id a\\u0000b');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getter.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getter.html
new file mode 100644
index 000000000..d9cd87172
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getter.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<title>TextTrackCueList getter</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var cues = t1.cues;
+ assert_equals(cues[0], undefined, 'cues[0] before');
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(cues[0], c1, 'cues[0]');
+ assert_equals(cues[1], undefined, 'cues[1]');
+ assert_equals(cues[-1], undefined, 'cues[-1]');
+ t1.removeCue(c1);
+ assert_equals(cues[0], undefined, 'cues[0] after');
+});
+test(function(){
+ var cues = t1.cues;
+ assert_equals(cues[0], undefined);
+ cues[0] = 'foo';
+ assert_equals(cues[0], undefined);
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(cues[0], c1);
+ cues[0] = 'foo';
+ assert_equals(cues[0], c1);
+ t1.removeCue(c1);
+}, document.title+', no indexed set/create');
+test(function(){
+ 'use strict';
+ var cues = t1.cues;
+ assert_equals(cues[0], undefined);
+ assert_throws(new TypeError(), function() { cues[0] = 'foo'; });
+ assert_equals(cues[0], undefined);
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(cues[0], c1);
+ assert_throws(new TypeError(), function() { cues[0] = 'foo'; });
+ assert_equals(cues[0], c1);
+ t1.removeCue(c1);
+}, document.title+', no indexed set/create (strict)');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/length.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/length.html
new file mode 100644
index 000000000..91e6e7ff9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/length.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>TextTrackCueList.length</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var cues = t1.cues;
+ assert_equals(cues.length, 0);
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(cues.length, 1);
+ t1.removeCue(c1);
+ assert_equals(cues.length, 0);
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getTrackById.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getTrackById.html
new file mode 100644
index 000000000..b701dd5e7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getTrackById.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>TextTrackList.getTrackById</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var video = document.createElement('video');
+ var track1 = video.addTextTrack('subtitles');
+ var track2 = video.addTextTrack('subtitles');
+ assert_equals(track1.id, '');
+ assert_equals(track2.id, '');
+ assert_equals(video.textTracks.getTrackById(''), track1);
+ assert_equals(video.textTracks.getTrackById('fake-id'), null);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getter.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getter.html
new file mode 100644
index 000000000..8c5fb3759
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getter.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<title>TextTrackList getter</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ video.addTextTrack('subtitles', 'b');
+ window.track = document.createElement('track');
+ track.label = 'a';
+ video.appendChild(track);
+ video.addTextTrack('subtitles', 'c');
+});
+test(function(){
+ assert_equals(video.textTracks[0].label, 'a');
+ assert_equals(video.textTracks[1].label, 'b');
+ assert_equals(video.textTracks[2].label, 'c');
+});
+test(function(){
+ var track_before = video.textTracks[0];
+ video.textTracks[0] = 'foo';
+ assert_equals(video.textTracks[0], track_before);
+}, document.title+', no indexed set/create');
+test(function(){
+ 'use strict';
+ var track_before = video.textTracks[0];
+ assert_throws(new TypeError(), function(){ video.textTracks[0] = 'foo'; });
+ assert_equals(video.textTracks[0], track_before);
+}, document.title+', no indexed set/create (strict)');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/length.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/length.html
new file mode 100644
index 000000000..7a24130d1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/length.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>TextTrackList.length</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ video.addTextTrack('subtitles');
+ window.track = document.createElement('track');
+ video.appendChild(track);
+ video.addTextTrack('subtitles');
+});
+test(function(){
+ assert_equals(video.textTracks.length, 3);
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onaddtrack.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onaddtrack.html
new file mode 100644
index 000000000..114ca8904
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onaddtrack.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>TextTrackList.onaddtrack</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.tracks = document.createElement('video').textTracks;
+ window.ev = new Event('addtrack');
+ window.ran = false;
+ window.cb = function() { ran = true; };
+});
+test(function(){
+ assert_equals(tracks.onaddtrack, null);
+ tracks.onaddtrack = cb;
+ assert_equals(tracks.onaddtrack, cb);
+ tracks.dispatchEvent(ev);
+ assert_true(ran);
+ tracks.onaddtrack = null;
+ ran = false;
+ tracks.dispatchEvent(ev);
+ assert_false(ran);
+});
+test(function(){
+ tracks.addEventListener('addtrack', cb, false);
+ tracks.dispatchEvent(ev);
+ assert_true(ran);
+ tracks.removeEventListener('addtrack', cb, false);
+ ran = false;
+ tracks.dispatchEvent(ev);
+ assert_false(ran);
+}, 'TextTrackList.addEventListener/removeEventListener');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onremovetrack.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onremovetrack.html
new file mode 100644
index 000000000..b8da16ce2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onremovetrack.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>TextTrackList.onremovetrack</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.tracks = document.createElement('video').textTracks;
+ window.ev = new Event('removetrack');
+ window.ran = false;
+ window.cb = function() { ran = true; };
+});
+test(function(){
+ assert_equals(tracks.onremovetrack, null);
+ tracks.onremovetrack = cb;
+ assert_equals(tracks.onremovetrack, cb);
+ tracks.dispatchEvent(ev);
+ assert_true(ran);
+ tracks.onremovetrack = null;
+ ran = false;
+ tracks.dispatchEvent(ev);
+ assert_false(ran);
+});
+test(function(){
+ tracks.addEventListener('removetrack', cb, false);
+ tracks.dispatchEvent(ev);
+ assert_true(ran);
+ tracks.removeEventListener('removetrack', cb, false);
+ ran = false;
+ tracks.dispatchEvent(ev);
+ assert_false(ran);
+}, 'TextTrackList.addEventListener/removeEventListener');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/constructor.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/constructor.html
new file mode 100644
index 000000000..54567d14a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/constructor.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>TrackEvent constructor</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var ev = new TrackEvent('foo');
+ assert_true(ev instanceof TrackEvent, 'ev instanceof TrackEvent');
+ assert_true(ev instanceof Event, 'ev instanceof Event');
+ assert_equals(ev.track, null, 'ev.track');
+ ev.track = {};
+ assert_equals(ev.track, null, 'ev.track after assignment');
+}, document.title+', one arg');
+test(function(){
+ var obj = {};
+ var ev = new TrackEvent('foo', {track:obj});
+ assert_true(ev instanceof TrackEvent, 'ev instanceof TrackEvent');
+ assert_true(ev instanceof Event, 'ev instanceof Event');
+ assert_equals(ev.track, obj, 'ev.track');
+ ev.track = {};
+ assert_equals(ev.track, obj, 'ev.track after assignment');
+}, document.title+', two args');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent.html
new file mode 100644
index 000000000..9bf763f1f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<title>TrackEvent created with createEvent</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=17268
+ assert_throws('NOT_SUPPORTED_ERR', function() {
+ var ev = document.createEvent('TrackEvent');
+ });
+ var ev = new TrackEvent('foo');
+ assert_false('initTrackEvent' in ev, 'initTrackEvent');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/autoplay-overrides-preload.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/autoplay-overrides-preload.html
new file mode 100644
index 000000000..91103c586
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/autoplay-overrides-preload.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<title>autoplay overrides preload</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+['none', 'metadata'].forEach(function(preload) {
+ ['first', 'last'].forEach(function(order) {
+ async_test(function(t) {
+ var a = document.createElement('audio');
+ a.src = getAudioURI('/media/sound_5');
+ if (order == 'first') {
+ a.autoplay = true;
+ a.preload = preload;
+ } else {
+ a.preload = preload;
+ a.autoplay = true;
+ }
+ a.addEventListener('playing', t.step_func(function() {
+ assert_equals(a.readyState, a.HAVE_ENOUGH_DATA);
+ assert_false(a.paused);
+ t.done();
+ }));
+ }, 'autoplay (set ' + order + ') overrides preload "' + preload + '"');
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-events-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-events-networkState.html
new file mode 100644
index 000000000..8c12011ef
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-events-networkState.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<title>load() fires abort/emptied events when networkState is not NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+function load_test(t, v) {
+ assert_not_equals(v.networkState, v.NETWORK_EMPTY);
+
+ var expected_events = [];
+ if (v.networkState == v.NETWORK_LOADING || v.networkState == v.NETWORK_IDLE) {
+ expected_events.push('abort');
+ }
+ if (v.networkState != v.NETWORK_EMPTY) {
+ expected_events.push('emptied');
+ }
+
+ var actual_events = [];
+ v.onabort = v.onemptied = t.step_func(function(e) {
+ actual_events.push(e.type);
+ });
+
+ v.onloadstart = t.step_func(function() {
+ assert_array_equals(actual_events, expected_events);
+ t.done();
+ });
+
+ v.load();
+
+ assert_array_equals(actual_events, [], 'events should be fired in queued tasks');
+}
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ // suspend is fired optionally "if the user agent intends to not attempt to
+ // fetch the resource" or "once the entire media resource has been fetched"
+ v.preload = 'none';
+ v.src = getAudioURI('/media/sound_5');
+ v.onsuspend = t.step_func(function() {
+ v.onsuspend = null;
+ assert_equals(v.networkState, v.NETWORK_IDLE);
+ load_test(t, v);
+ });
+}, 'NETWORK_IDLE');
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = 'resources/delayed-broken-video.py';
+ v.onloadstart = t.step_func(function() {
+ v.onloadstart = null;
+ assert_equals(v.networkState, v.NETWORK_LOADING);
+ load_test(t, v);
+ });
+}, 'NETWORK_LOADING');
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = 'data:,';
+ v.onerror = t.step_func(function() {
+ v.onerror = null;
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE);
+ load_test(t, v);
+ });
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE);
+}, 'NETWORK_NO_SOURCE');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html
new file mode 100644
index 000000000..54d5c28da
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<title>load() removes queued error event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+// The loadstart and error event firing tasks are queued in the synchronous
+// section of the resource selection algorithm, so no tasks can come between
+// them. Calling load() in the loadstart event handler removes the queued error
+// event task at very latest opportunity, failing any implementation that fires
+// the events in the same task.
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ var events = [];
+ v.onloadstart = v.onerror = t.step_func(function(e) {
+ events.push(e.type);
+ if (events.length == 1) {
+ v.load();
+ } else if (events.length == 3) {
+ assert_array_equals(events, ['loadstart', 'loadstart', 'error']);
+ t.done();
+ }
+ });
+ v.src = '';
+}, 'video error event');
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ var s = document.createElement('source');
+ var events = [];
+ v.onloadstart = s.onerror = t.step_func(function(e) {
+ events.push(e.type);
+ if (events.length == 1) {
+ v.load();
+ } else if (events.length == 3) {
+ assert_array_equals(events, ['loadstart', 'loadstart', 'error']);
+ t.done();
+ }
+ });
+ v.onerror = t.step_func(function() { assert_unreached(); });
+ v.appendChild(s);
+}, 'source error event');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html
new file mode 100644
index 000000000..39c988750
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>inserting another source before the candidate</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+function createSource(src) {
+ var source = document.createElement('source');
+ source.src = src;
+ return source;
+}
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.addEventListener('loadstart', t.step_func(function() {
+ assert_equals(v.currentSrc.substr(v.currentSrc.lastIndexOf('#')), '#a');
+ t.done();
+ }), false);
+ v.appendChild(createSource('#a')); // invokes resource selection
+});
+</script>
+<!-- now resource selection algorithm will continue its sync section (the </script> tag below provides a stable state) -->
+<!-- #a is candidate -->
+<!-- pointer is between #a and the end of the list -->
+<script>
+t.step(function() {
+ v.insertBefore(createSource('#b'), v.firstChild); // pointer is unchanged, #a is still candidate
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-moved.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-moved.html
new file mode 100644
index 000000000..f59452e0d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-moved.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>moving the candidate source</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var s;
+var t = async_test(function(t) {
+ var v = document.createElement('video');
+ s = document.createElement('source');
+ s.src = 'resources/delayed-broken-video.py';
+ s.onerror = t.step_func(function() { t.done(); });
+ v.appendChild(s); // invokes resource selection
+ onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
+<script>
+t.step(function() {
+ document.body.appendChild(s);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-addEventListener.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-addEventListener.html
new file mode 100644
index 000000000..0c1e6f0ad
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-addEventListener.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>removing the candidate source, addEventListener</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+function createSource(src) {
+ var source = document.createElement('source');
+ source.src = src;
+ return source;
+}
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.appendChild(createSource('resources/delayed-broken-video.py')); // invokes resource selection
+ v.firstChild.addEventListener('error', t.step_func(function() { t.done(); }), false);
+});
+</script>
+<!-- now resource selection algorithm will continue its sync section (the </script> tag below provides a stable state) -->
+<!-- the <source> is candidate -->
+<!-- pointer is between the <source> and the end of the list -->
+<script>
+t.step(function() {
+ v.removeChild(v.firstChild); // tests that we fire 'error' on it despite being removed
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-no-listener.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-no-listener.html
new file mode 100644
index 000000000..f384eb312
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-no-listener.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>removing the candidate source, no listener</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+function createSource(src) {
+ var source = document.createElement('source');
+ source.src = src;
+ return source;
+}
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.appendChild(createSource('resources/delayed-broken-video.py')); // invokes resource selection
+});
+</script>
+<!-- now resource selection algorithm will continue its sync section (the </script> tag below provides a stable state) -->
+<!-- the <source> is candidate -->
+<!-- pointer is between the <source> and the end of the list -->
+<script>
+t.step(function() {
+ v.removeChild(v.firstChild); // just tests that we don't crash
+ onload = t.step_func(function() { t.done(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-onerror.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-onerror.html
new file mode 100644
index 000000000..c295c85bf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-onerror.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>removing the candidate source, onerror</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+function createSource(src) {
+ var source = document.createElement('source');
+ source.src = src;
+ return source;
+}
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.appendChild(createSource('resources/delayed-broken-video.py')); // invokes resource selection
+ v.firstChild.onerror = t.step_func(function() { t.done(); });
+});
+</script>
+<!-- now resource selection algorithm will continue its sync section (the </script> tag below provides a stable state) -->
+<!-- the <source> is candidate -->
+<!-- pointer is between the <source> and the end of the list -->
+<script>
+t.step(function() {
+ v.removeChild(v.firstChild); // tests that we fire 'error' on it despite being removed
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html
new file mode 100644
index 000000000..cb2a57959
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>NOT invoking resource selection with new Audio() sans src</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var a = new Audio();
+ assert_equals(a.networkState, a.NETWORK_EMPTY);
+ a.onloadstart = t.step_func(function() { assert_unreached(); });
+ window.onload = t.step_func(function() { t.done(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor.html
new file mode 100644
index 000000000..662129756
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>invoking resource selection with new Audio(src)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var a = new Audio('');
+ a.onloadstart = t.step_func(function() { t.done(); });
+ window.onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-in-sync-event.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-in-sync-event.html
new file mode 100644
index 000000000..55fc7c20d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-in-sync-event.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<title>await a stable state and sync event handlers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.querySelector('video');
+ var a = document.createElement('a');
+ a.onclick = t.step_func(function() {
+ v.setAttribute('src', '#'); // invokes media load which invokes resource selection
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState in onclick handler');
+ });
+ a.click(); // sync fires click, so sets src
+ // now we should still await a stable state because the script hasn't
+ // finished, the event handler has just returned
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after click()');
+ v.removeAttribute('src');
+});
+</script>
+<script>
+t.step(function() {
+ // now the sync section of resource selection should have run and should
+ // have found no src="" or <source> thus networkState being set to NETWORK_EMPTY.
+ // if the sync section was run when onclick returned, then networkState
+ // would be either NETWORK_LOADING or NETWORK_NO_SOURCE.
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-fragment-into-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-fragment-into-document.html
new file mode 100644
index 000000000..5d4c32f67
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-fragment-into-document.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting document fragment into a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ var fragment = document.createDocumentFragment();
+ fragment.appendChild(v);
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after fragment.appendChild(v)');
+ document.body.appendChild(fragment);
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after document.body.appendChild(fragment)');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-document.html
new file mode 100644
index 000000000..2f9ec978a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-document.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting into a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function(t) {
+ var v = document.createElement('video');
+ document.body.appendChild(v);
+ assert_equals(v.networkState, v.NETWORK_EMPTY);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-iframe.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-iframe.html
new file mode 100644
index 000000000..45d133d87
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-iframe.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting into other document with src set</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<iframe hidden></iframe>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = 'data:,';
+ v.onerror = t.step_func(function() {
+ assert_equals(v.readyState, v.HAVE_NOTHING);
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE);
+ var iframe = document.querySelector('iframe');
+ iframe.contentDocument.body.appendChild(v);
+ v.onloadstart = t.step_func(function() { assert_unreached(); });
+ // wait for an event after the above
+ var v2 = document.createElement('video');
+ v2.src = 'data:,';
+ v2.onloadstart = t.step_func(function() { t.done(); });
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-parent-into-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-parent-into-document.html
new file mode 100644
index 000000000..6da34344f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-parent-into-document.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting parent into a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ var div = document.createElement('div');
+ div.appendChild(v);
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after div.appendChild(v)');
+ document.body.appendChild(div);
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after document.body.appendChild(div)');
+ window.onload = t.step_func(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in window.onload');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-div.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-div.html
new file mode 100644
index 000000000..b79bea52f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-div.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting &lt;source> in &lt;div> in &lt;video></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video><div></div></video>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.onloadstart = t.step_func(function() { assert_unreached(); });
+ v.firstChild.appendChild(document.createElement('source'));
+ window.onload = t.step_func(function() { t.done(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html
new file mode 100644
index 000000000..b73f229ec
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting &lt;source> in the wrong namespace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.onloadstart = t.step_func(function() { assert_unreached(); });
+ v.appendChild(document.createElementNS('bogus','source'));
+ window.onload = t.step_func(function() { t.done(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-networkState.html
new file mode 100644
index 000000000..5ef6e4cb3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-networkState.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting &lt;source> when networkState is not NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var loadstartCount = 0;
+var s1ErrorCount = 0;
+var s2ErrorCount = 0;
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.onloadstart = function() { loadstartCount++; };
+ var s1 = document.createElement('source');
+ s1.src = 'resources/delayed-broken-video.py';
+ s1.onerror = function() { s1ErrorCount++; };
+ v.appendChild(s1); // invokes resource selection
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState in first script');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_LOADING, 'networkState in second script');
+ assert_equals(s1ErrorCount, 0, 's1ErrorCount in second script');
+ var s2 = document.createElement('source');
+ s2.onerror = t.step_func(function() {
+ s2ErrorCount++;
+ assert_equals(s1ErrorCount, 1, 's1ErrorCount in s2.onerror');
+ });
+ v.appendChild(s2);
+ onload = t.step_func(function() {
+ assert_equals(s2ErrorCount, 1, 's2ErrorCount in window.onload');
+ assert_equals(loadstartCount, 1, 'loadstartCount in window.onload'); // reliable if https://www.w3.org/Bugs/Public/show_bug.cgi?id=24353 is fixed
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState in window.onload'); // See Waiting step
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html
new file mode 100644
index 000000000..2007b2e8b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>invoking resource selection by inserting &lt;source> in video not in a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.onloadstart = t.step_func(function() { t.done(); });
+ v.appendChild(document.createElement('source'));
+ window.onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html
new file mode 100644
index 000000000..969daad62
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>invoking resource selection by inserting &lt;source></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.onloadstart = t.step_func(function() { t.done(); });
+ v.appendChild(document.createElement('source'));
+ window.onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-load.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-load.html
new file mode 100644
index 000000000..909c72cd1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-load.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>invoking resource selection with load()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after creating v');
+ v.load();
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after v.load()');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause-networkState.html
new file mode 100644
index 000000000..18561a264
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause-networkState.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>NOT invoking resource selection with pause() when networkState is not NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.querySelector('video');
+ v.src = 'data:,';
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after setting src');
+ var errorCount = 0;
+ v.onerror = t.step_func(function() {
+ errorCount++;
+ if (errorCount == 1) {
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState in onerror');
+ v.pause(); // should not invoke RSA. if it does, error will be fired again.
+ } else {
+ assert_unreached();
+ }
+ });
+ onload = t.step_func(function() {
+ assert_equals(errorCount, 1, 'errorCount');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause.html
new file mode 100644
index 000000000..4f1bca74d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>invoking resource selection with pause()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after creating v');
+ v.pause();
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after v.pause()');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-play.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-play.html
new file mode 100644
index 000000000..64a440080
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-play.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>invoking resource selection with play()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after creating v');
+ v.play();
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after v.play()');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document-networkState.html
new file mode 100644
index 000000000..1eed276b2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document-networkState.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>NOT invoking resource selection with implicit pause() when networkState is not NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.querySelector('video');
+ v.src = 'data:,';
+ document.body.appendChild(v);
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after setting src');
+ var errorCount = 0;
+ v.onerror = t.step_func(function() {
+ errorCount++;
+ if (errorCount == 1) {
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState in onerror');
+ document.body.removeChild(v); // invokes pause() which should not invoke RSA. if it does, error will be fired again.
+ } else {
+ assert_unreached();
+ }
+ });
+ onload = t.step_func(function() {
+ assert_equals(errorCount, 1, 'errorCount');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document.html
new file mode 100644
index 000000000..23e7104ca
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>NOT invoking resource selection by removing from document with NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ document.body.appendChild(v);
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after appending v to document');
+ v.parentNode.removeChild(v); // search for "When a media element is removed from a Document,"
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after removing v');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html
new file mode 100644
index 000000000..6302ffeac
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>NOT invoking media load or resource selection when removing the src attribute</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.setAttribute('src', ''); // invokes media load
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after setting src');
+ var s = document.createElement('source');
+ s.onerror = this.step_func(function() { assert_unreached(); });
+ v.appendChild(s); // src is present so nothing happens here
+ onload = this.step_func(function() { t.done(); });
+});
+</script>
+<script>
+t.step(function() {
+ v.removeAttribute('src'); // nothing should happen
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-in-namespace.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-in-namespace.html
new file mode 100644
index 000000000..438db124d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-in-namespace.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>NOT invoking load by setting src in the wrong namespace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.onloadstart = t.step_func(function() { assert_unreached(); });
+ v.setAttributeNS('bogus','src', '');
+ window.onload = t.step_func(function() { t.done(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState.html
new file mode 100644
index 000000000..e195dedb0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>invoking load by setting src when networkState is not NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function(t) {
+ var v = document.createElement('video');
+ v.play(); // invokes resource selection and sets .paused to false
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState');
+ assert_false(v.paused, 'paused');
+ v.setAttribute('src', ''); // invokes media load which sets .paused to true
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after setting src');
+ assert_true(v.paused, 'paused after setting src');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html
new file mode 100644
index 000000000..f6c4f2406
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>invoking load by setting src on video not in a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.onloadstart = t.step_func(function() { t.done(); });
+ v.setAttribute('src','');
+ window.onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src.html
new file mode 100644
index 000000000..e04b1b058
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>invoking load by setting src</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.onloadstart = t.step_func(function() { t.done(); });
+ v.setAttribute('src', '');
+ window.onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-control.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-control.html
new file mode 100644
index 000000000..dad5e5fd0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-control.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>pointer updates (control test)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+</script>
+<video
+ ><source onerror=a++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=c++
+ ></video
+>
+<script>
+async_test(function(t) {
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-br.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-br.html
new file mode 100644
index 000000000..3ee141e30
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-br.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>pointer updates (adding br elements)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+</script>
+<video
+ ><source onerror=a++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=c++
+ ></video
+>
+<script>
+async_test(function(t) {
+ var video = document.querySelector('video');
+ // add br elements
+ var br = document.createElement('br');
+ video.insertBefore(br, video.querySelector('[onerror="a++"]'));
+ video.insertBefore(br.cloneNode(false), video.querySelector('[onerror="b++"]'));
+ video.insertBefore(br.cloneNode(false), video.querySelector('[onerror="c++"]'));
+ video.appendChild(br.cloneNode(false));
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-source.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-source.html
new file mode 100644
index 000000000..2d32e6fca
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-source.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<title>pointer updates (adding source elements)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+var x1 = 0;
+var x2 = 0;
+var x3 = 0;
+var x4 = 0;
+</script>
+<video
+ ><source onerror=a++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=c++
+ ></video
+>
+<script>
+async_test(function(t) {
+ var video = document.querySelector('video');
+ // add source elements
+ var source1 = document.createElement('source'); source1.onerror = function() { x1++; };
+ var source2 = document.createElement('source'); source2.onerror = function() { x2++; };
+ var source3 = document.createElement('source'); source3.onerror = function() { x3++; };
+ var source4 = document.createElement('source'); source4.onerror = function() { x4++; };
+ video.insertBefore(source1, video.querySelector('[onerror="a++"]'));
+ video.insertBefore(source2, video.querySelector('[onerror="b++"]'));
+ video.insertBefore(source3, video.querySelector('[onerror="c++"]'));
+ video.appendChild(source4);
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ assert_equals(x1, 0, 'error events on x1');
+ assert_equals(x2, 0, 'error events on x2');
+ assert_equals(x3, 1, 'error events on x3');
+ assert_equals(x4, 1, 'error events on x4');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-text.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-text.html
new file mode 100644
index 000000000..15a4e4be0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-text.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>pointer updates (adding text nodes)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+</script>
+<video
+ ><source onerror=a++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=c++
+ ></video
+>
+<script>
+async_test(function(t) {
+ var video = document.querySelector('video');
+ // add text nodes
+ var text = document.createTextNode('x');
+ video.insertBefore(text, video.querySelector('[onerror="a++"]'));
+ video.insertBefore(text.cloneNode(false), video.querySelector('[onerror="b++"]'));
+ video.insertBefore(text.cloneNode(false), video.querySelector('[onerror="c++"]'));
+ video.appendChild(text.cloneNode(false));
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source-after.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source-after.html
new file mode 100644
index 000000000..0d1c94037
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source-after.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<title>pointer updates (removing source element after pointer)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+var x1 = 0;
+var x2 = 0;
+var x3 = 0;
+var x4 = 0;
+</script>
+<video
+ ><source onerror=a++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=x1++
+ ><source onerror=x2++
+ ><source onerror=x3++
+ ><source onerror=x4++
+ ><source onerror=c++
+ ></video
+>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.querySelector('video');
+ v.removeChild(document.querySelector('[onerror="x1++"]'));
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ assert_equals(x1, 0, 'error events on x1');
+ assert_equals(x2, 0, 'error events on x2');
+ assert_equals(x3, 0, 'error events on x3');
+ assert_equals(x4, 0, 'error events on x4');
+ t.done();
+ });
+});
+</script>
+<script>
+t.step(function() {
+ v.removeChild(document.querySelector('[onerror="x2++"]'));
+});
+</script>
+<script>
+t.step(function() {
+ v.removeChild(document.querySelector('[onerror="x3++"]'));
+});
+</script>
+<script>
+t.step(function() {
+ v.removeChild(document.querySelector('[onerror="x4++"]'));
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html
new file mode 100644
index 000000000..191f9b5e2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<title>pointer updates (removing source elements)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+var x1 = 0;
+var x2 = 0;
+var x3 = 0;
+var x4 = 0;
+</script>
+<video
+ ><source onerror=x1++
+ ><source onerror=a++
+ ><source onerror=x2++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=x3++
+ ><source onerror=c++
+ ><source onerror=x4++
+ ></video
+>
+<script>
+async_test(function(t) {
+ var video = document.querySelector('video');
+ // remove the xn elements
+ [].forEach.call(document.querySelectorAll('[onerror^="x"]'), function(elm) {
+ video.removeChild(elm);
+ });
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ assert_equals(x1, 1, 'error events on x1');
+ assert_equals(x2, 1, 'error events on x2');
+ assert_equals(x3, 0, 'error events on x3');
+ assert_equals(x4, 0, 'error events on x4');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-text.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-text.html
new file mode 100644
index 000000000..f0fe5da90
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-text.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>pointer updates (removing text nodes)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+</script>
+<video
+ >x<source onerror=a++
+ >x<source onerror=b++ src='resources/delayed-broken-video.py'
+ >x<source onerror=c++
+ >x</video
+>
+<script>
+async_test(function(t) {
+ var video = document.querySelector('video');
+ // remove the text nodes
+ [].forEach.call(video.childNodes, function(node) {
+ if (node.nodeType == node.TEXT_NODE) {
+ video.removeChild(node);
+ }
+ });
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html
new file mode 100644
index 000000000..fbeead019
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>Changes to networkState when inserting and removing a &lt;source></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState when creating the element');
+ v.appendChild(document.createElement('source')); // runs resource selection algorithm
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState when inserting a source element');
+ v.removeChild(v.firstChild);
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after removing the source element');
+});
+</script>
+<!-- now resource selection will continue its sync section (the </script> tag below provides a stable state) -->
+<!-- will find neither src nor source, so sets networkState to NETWORK_EMPTY -->
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after letting the sync section of resource selection run');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-src.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-src.html
new file mode 100644
index 000000000..4d7887182
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-src.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>invoking resource selection by setting src; await stable state</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.onloadstart = t.step_func(function() { assert_unreached(); });
+ v.setAttribute('src', ''); // runs resource selection algorithm, but it will wait running the sync section until this script has finished
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE);
+ v.removeAttribute('src'); // will make resource selection algorithm revert to NETWORK_EMPTY and abort (in the sync section)
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE);
+ window.onload = t.step_func(function() { t.done(); });
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-source-media.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-source-media.html
new file mode 100644
index 000000000..6332f0890
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-source-media.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>the &lt;source> media attribute has no effect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video><source src="resources/delayed-broken-video.py" media="none"></video>
+<script>
+test(function() {
+ var v = document.querySelector('video');
+ var s = document.querySelector('source');
+ assert_equals(v.networkState, v.NETWORK_LOADING);
+ assert_equals(v.currentSrc, s.src);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resources/delayed-broken-video.py b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resources/delayed-broken-video.py
new file mode 100644
index 000000000..88e502794
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resources/delayed-broken-video.py
@@ -0,0 +1,5 @@
+import time
+
+def main(request, response):
+ time.sleep(0.1)
+ return [("Content-Type", "text/plain")], "FAIL"
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-beforeunload-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-beforeunload-manual.html
new file mode 100644
index 000000000..61ed225fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-beforeunload-manual.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>stable state in beforeunload</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<button>click this button and cancel navigation</button>
+<a href="data:text/plain,FAIL: did not cancel navigation"></a>
+<script>
+async_test(function(t) {
+ window.onbeforeunload = t.step_func(function(event) {
+ var message = "foo bar";
+ event.returnValue = message;
+ return message;
+ });
+ var button = document.querySelector('button');
+ var link = document.querySelector('a');
+ button.onclick = t.step_func(function() {
+ v = document.createElement('video');
+ v.src = 'data:,';
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState before dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc before dialog');
+ link.click();
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc after dialog');
+ t.done();
+ window.onbeforeonload = null;
+ button.remove();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-dialogs-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-dialogs-manual.html
new file mode 100644
index 000000000..267dde913
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-dialogs-manual.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>stable state in dialogs</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+['alert', 'confirm', 'prompt'].forEach(function(dialog) {
+ test(function() {
+ v = document.createElement('video');
+ v.src = 'data:,';
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState before dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc before dialog');
+ window[dialog]('dismiss this dialog');
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc after dialog');
+ }, 'stable state in ' + dialog + '()');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-print-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-print-manual.html
new file mode 100644
index 000000000..1261a0079
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-print-manual.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>stable state in print()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<button>click this button and dismiss the print dialog</button>
+<script>
+async_test(function(t) {
+ var button = document.querySelector('button');
+ button.onclick = t.step_func(function() {
+ v = document.createElement('video');
+ v.src = 'data:,';
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState before dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc before dialog');
+ print();
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc after dialog');
+ t.done();
+ button.remove();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/location-of-the-media-resource/currentSrc.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/location-of-the-media-resource/currentSrc.html
new file mode 100644
index 000000000..2ca0a5180
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/location-of-the-media-resource/currentSrc.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<title>currentSrc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+['audio', 'video'].forEach(function(tagName) {
+ test(function() {
+ assert_equals(document.createElement(tagName).currentSrc, '');
+ }, tagName + '.currentSrc initial value');
+
+ ['', '.', ' ', 'data:,'].forEach(function(src) {
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ assert_equals(e.currentSrc, '');
+ setTimeout(t.step_func(function() {
+ if (src == '') {
+ assert_equals(e.currentSrc, '');
+ } else {
+ assert_equals(e.currentSrc, e.src);
+ }
+ t.done();
+ }), 0);
+ }, tagName + '.currentSrc after setting src attribute "' + src + '"');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ var s = document.createElement('source');
+ s.src = src;
+ e.appendChild(s);
+ assert_equals(e.currentSrc, '');
+ setTimeout(t.step_func(function() {
+ if (src == '') {
+ assert_equals(e.currentSrc, '');
+ } else {
+ assert_equals(e.currentSrc, s.src);
+ }
+ t.done();
+ }), 0);
+ }, tagName + '.currentSrc after adding source element with src attribute "' + src + '"');
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html
new file mode 100644
index 000000000..c5d37e752
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html
@@ -0,0 +1,110 @@
+<!doctype html>
+<title>canPlayType</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+function t(type, expected) {
+ assert_equals(canPlayType(type), expected, type);
+}
+
+function mime(type, codecs) {
+ if (codecs.length) {
+ return type + '; codecs="' + codecs.join(', ') + '"';
+ }
+ return type;
+}
+
+test(function() {
+ assert_equals(mime('video/webm', []), 'video/webm');
+ assert_equals(mime('video/webm', ['vp8']), 'video/webm; codecs="vp8"');
+ assert_equals(mime('video/webm', ['vp8', 'vorbis']), 'video/webm; codecs="vp8, vorbis"');
+}, 'utility code');
+
+function canPlayType(type) {
+ var canPlay = document.createElement('audio').canPlayType(type);
+ assert_equals(canPlay, document.createElement('video').canPlayType(type),
+ 'audio.canPlayType() and video.canPlayType() agree');
+ assert_in_array(canPlay, ['', 'maybe', 'probably'],
+ 'return value is one of "", "maybe" and "probably"');
+ return canPlay;
+}
+
+test(function() {
+ t('application/octet-stream', '');
+ t('application/octet-stream; codecs="vorbis"', '');
+ t('application/octet-stream; codecs="vp8, vorbis"', '');
+ t('application/octet-stream; codecs="mp4a.40.2"', '');
+ t('application/octet-stream; codecs="theora, vorbis"', '');
+ t('application/octet-stream; codecs="avc1.42E01E, mp4a.40.2"', '');
+}, 'application/octet-stream');
+
+test(function() {
+ t('video/x-new-fictional-format', '');
+ t('video/x-new-fictional-format;codecs="kittens,bunnies"', '');
+}, 'video/x-new-fictional-format');
+
+function type_codecs_test(type, audioCodecs, videoCodecs) {
+ var typeSupported = false;
+ var codecSupported = false;
+
+ test(function() {
+ // Spec: Generally, a user agent should never return "probably" for a type
+ // that allows the codecs parameter if that parameter is not present.
+ t(type, 'maybe');
+ typeSupported = true;
+ }, type + ' (optional)');
+
+ function test_codec(codec) {
+ var typeWithCodec = mime(type, [codec]);
+ test(function() {
+ t(typeWithCodec, 'probably');
+ codecSupported = true;
+ }, typeWithCodec + ' (optional)');
+ }
+
+ audioCodecs.forEach(test_codec);
+ videoCodecs.forEach(test_codec);
+
+ if (audioCodecs.length > 0 && videoCodecs.length > 0) {
+ test(function() {
+ audioCodecs.forEach(function(ac) {
+ videoCodecs.forEach(function(vc) {
+ var canPlayBoth = canPlayType(mime(type, [ac, vc]));
+ if (canPlayBoth) {
+ t(mime(type, [ac]), canPlayBoth);
+ t(mime(type, [vc]), canPlayBoth);
+ }
+ });
+ });
+ }, type + ' codecs subset');
+
+ test(function() {
+ audioCodecs.forEach(function(ac) {
+ videoCodecs.forEach(function(vc) {
+ assert_equals(canPlayType(mime(type, [ac, vc])),
+ canPlayType(mime(type, [vc, ac])));
+ });
+ });
+ }, type + ' codecs order');
+ }
+
+ test(function() {
+ t(mime(type, ['bogus']), '');
+ }, type + ' with bogus codec');
+
+ test(function() {
+ // At least one known codec must be supported if the container format is.
+ assert_equals(typeSupported, codecSupported);
+ }, type + ' with and without codecs');
+}
+
+type_codecs_test('audio/mp4', ['mp4a.40.2'], []);
+type_codecs_test('audio/ogg', ['opus', 'vorbis'], []);
+type_codecs_test('audio/wav', ['1'], []);
+type_codecs_test('audio/webm', ['opus', 'vorbis'], []);
+type_codecs_test('video/3gpp', ['samr'], ['mp4v.20.8']);
+type_codecs_test('video/mp4', ['mp4a.40.2'], ['avc1.42E01E', 'avc1.4D401E', 'avc1.58A01E', 'avc1.64001E', 'mp4v.20.8', 'mp4v.20.240']);
+type_codecs_test('video/ogg', ['opus', 'vorbis'], ['theora']);
+type_codecs_test('video/webm', ['opus', 'vorbis'], ['vp8', 'vp8.0', 'vp9', 'vp9.0']);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_loadstart.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_loadstart.html
new file mode 100644
index 000000000..8f0fffc61
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_loadstart.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.networkState - NETWORK_LOADING</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-networkstate">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+var ta = async_test("audioElement.networkState should be NETWORK_LOADING during loadstart event", {timeout:5000});
+var a = document.getElementById("a");
+a.addEventListener("loadstart", function() {
+ ta.step(function() {
+ assert_equals(a.networkState,
+ a.NETWORK_LOADING);
+ });
+ ta.done();
+ a.pause();
+}, false);
+a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+
+var tv = async_test("videoElement.networkState should be NETWORK_LOADING during loadstart event", {timeout:5000});
+var v = document.getElementById("v");
+v.addEventListener("loadstart", function() {
+ tv.step(function() {
+ assert_equals(a.networkState,
+ v.NETWORK_LOADING);
+ });
+ tv.done();
+ v.pause();
+}, false);
+v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_progress.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_progress.html
new file mode 100644
index 000000000..cf23e822c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_progress.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.networkState - NETWORK_LOADING</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-networkstate">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+var ta = async_test("audioElement.networkState should be NETWORK_LOADING during progress event", {timeout:5000});
+var a = document.getElementById("a");
+a.addEventListener("progress", function() {
+ ta.step(function() {
+ assert_equals(a.networkState,
+ a.NETWORK_LOADING);
+ });
+ ta.done();
+ a.pause();
+}, false);
+a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+
+var tv = async_test("videoElement.networkState should be NETWORK_LOADING during progress event", {timeout:5000});
+var v = document.getElementById("v");
+v.addEventListener("progress", function() {
+ tv.step(function() {
+ assert_equals(v.networkState,
+ v.NETWORK_LOADING);
+ });
+ tv.done();
+ v.pause();
+}, false);
+v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_initial.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_initial.html
new file mode 100644
index 000000000..0a203e654
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_initial.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.networkState - default state</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-networkstate">spec reference</a></p>
+ <audio id="a">
+ </audio>
+ <video id="v">
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var a = document.getElementById("a");
+ assert_equals(
+ a.networkState,
+ a.NETWORK_EMPTY,
+ "audioElement.networkState should be NETWORK_EMPTY to begin with");
+}, "audio.networkState - default state");
+
+test(function() {
+ var v = document.getElementById("v");
+ assert_equals(
+ v.networkState,
+ v.NETWORK_EMPTY,
+ "videoElement.networkState should be NETWORK_EMPTY to begin with");
+}, "video.networkState - default state");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime.html
new file mode 100644
index 000000000..e9b658994
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<title>currentTime</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var v = document.createElement('video');
+ assert_equals(v.currentTime, 0);
+}, 'currentTime initial value');
+
+test(function() {
+ var v = document.createElement('video');
+ assert_equals(v.readyState, v.HAVE_NOTHING);
+ v.currentTime = Number.MAX_VALUE;
+ assert_equals(v.currentTime, Number.MAX_VALUE);
+ assert_false(v.seeking);
+}, 'setting currentTime when readyState is HAVE_NOTHING');
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = getVideoURI('/media/movie_5');
+ v.onloadedmetadata = t.step_func(function() {
+ assert_greater_than(v.readyState, v.HAVE_NOTHING);
+ assert_false(v.seeking);
+ v.currentTime = 1;
+ assert_true(v.seeking);
+ t.done();
+ });
+}, 'setting currentTime when readyState is greater than HAVE_NOTHING');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/duration.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/duration.html
new file mode 100644
index 000000000..0ac26eddb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/duration.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>duration</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var v = document.createElement('video');
+ assert_true(isNaN(v.duration));
+}, 'duration initial value');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_false_during_play.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_false_during_play.html
new file mode 100644
index 000000000..28c563333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_false_during_play.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - paused property</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.paused should be false during play event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("play", function() {
+ t.step(function() {
+ assert_false(a.paused);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - paused property");
+
+test(function() {
+ var t = async_test("video.paused should be false during play event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("play", function() {
+ t.step(function() {
+ assert_false(v.paused);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - paused property");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_true_during_pause.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_true_during_pause.html
new file mode 100644
index 000000000..6c4eb7c0c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_true_during_pause.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - paused property</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.paused should be true during pause event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("pause", function() {
+ t.step(function() {
+ assert_true(a.paused);
+ });
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ a.play();
+ a.pause();
+}, "audio events - paused property");
+
+test(function() {
+ var t = async_test("video.paused should be true during pause event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("pause", function() {
+ t.step(function() {
+ assert_true(v.paused);
+ });
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ v.play();
+ v.pause();
+}, "video events - paused property");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-to-other-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-to-other-document.html
new file mode 100644
index 000000000..342771dbd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-to-other-document.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>paused state when moving to other document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<video hidden></video>
+<iframe hidden></iframe>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.src = getVideoURI('/media/movie_300');
+ v.play();
+ v.onplaying = t.step_func(function() {
+ assert_false(v.paused, 'paused after playing');
+ document.querySelector('iframe').contentDocument.body.appendChild(v);
+ assert_false(v.paused, 'paused after moving');
+ setTimeout(t.step_func(function() {
+ assert_false(v.paused, 'paused after stable state')
+ t.done();
+ }), 0);
+ });
+ v.onpause = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-within-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-within-document.html
new file mode 100644
index 000000000..a28322d4d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-within-document.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>paused state when moving within a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<video hidden></video>
+<div id="elsewhere"></div>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.src = getVideoURI('/media/movie_300');
+ v.play();
+ v.onplaying = t.step_func(function() {
+ assert_false(v.paused, 'paused after playing');
+ document.getElementById('elsewhere').appendChild(v);
+ assert_false(v.paused, 'paused after moving');
+ setTimeout(t.step_func(function() {
+ assert_false(v.paused, 'paused after stable state')
+ t.done();
+ }), 0);
+ });
+ v.onpause = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html
new file mode 100644
index 000000000..3b5849a35
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>paused state when removing from a document when networkState is NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<video hidden></video>
+<script>
+// Negative test for the specified behavior prior to HTML r8447.
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.play();
+ setTimeout(t.step_func(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY,
+ 'networkState after stable state');
+ assert_false(v.paused, 'paused after stable state');
+ v.parentNode.removeChild(v);
+ assert_false(v.paused, 'paused after removing');
+ v.onpause = t.step_func(function() { t.done(); });
+ }), 0);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document.html
new file mode 100644
index 000000000..7a4b0bc0d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<title>paused state when removing from a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<video hidden></video>
+<script>
+function afterStableState(func) {
+ var a = new Audio();
+ a.volume = 0;
+ a.addEventListener('volumechange', func);
+}
+
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.src = getVideoURI('/media/movie_300');
+ v.play();
+ v.onplaying = t.step_func(function() {
+ assert_false(v.paused, 'paused after playing');
+ v.parentNode.removeChild(v);
+ assert_false(v.paused, 'paused after removing');
+ afterStableState(t.step_func(function() {
+ assert_true(v.paused, 'paused after stable state');
+ v.onpause = t.step_func(function() {
+ assert_true(v.paused, 'paused in pause event');
+ // re-insert and verify that it stays paused
+ document.body.appendChild(v);
+ setTimeout(t.step_func(function() {
+ assert_true(v.paused, 'paused after re-inserting');
+ t.done();
+ }), 0);
+ });
+ }));
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/play-in-detached-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/play-in-detached-document.html
new file mode 100644
index 000000000..9c6fd5fab
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/play-in-detached-document.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>play() in detached document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<script>
+// Negative test for failure to play in a detached document.
+async_test(function(t)
+{
+ var doc = document.implementation.createHTMLDocument("");
+ var v = doc.createElement("video");
+ doc.body.appendChild(v);
+ v.src = getVideoURI("/media/movie_5");
+ v.play();
+ v.addEventListener("timeupdate", t.step_func(function() {
+ assert_false(v.paused);
+ if (v.currentTime > 0) {
+ t.done();
+ }
+ }));
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html
new file mode 100644
index 000000000..fa11d9944
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>playbackRate</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var v = document.createElement('video');
+ assert_equals(v.playbackRate, 1);
+}, 'playbackRate initial value');
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.playbackRate = 2;
+ v.addEventListener('ratechange', t.step_func(function() {
+ t.done();
+ }));
+}, 'setting playbackRate');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/preload_reflects_none_autoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/preload_reflects_none_autoplay.html
new file mode 100644
index 000000000..2670b0dd8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/preload_reflects_none_autoplay.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.preload - reflection test</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-preload">spec reference</a></p>
+ <audio id="audio" autoplay preload="none">
+ </audio>
+ <video id="video" autoplay preload="none">
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ assert_equals(
+ document.getElementById("audio").preload,
+ "none",
+ "audioElement.preload reflects 'none' value even if autoplay attribute is present");
+}, "audio.preload - reflection test");
+
+test(function() {
+ assert_equals(
+ document.getElementById("video").preload,
+ "none",
+ "videoElement.preload reflects 'none' value even if autoplay attribute is present");
+}, "video.preload - reflection test");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/ready-states/autoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/ready-states/autoplay.html
new file mode 100644
index 000000000..76aef1dbc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/ready-states/autoplay.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<title>autoplay</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<script>
+function autoplay_test(tagName, src) {
+ function expect_events(t, e, expected_events) {
+ var actual_events = [];
+ var callback = t.step_func(function(ev) {
+ actual_events.push(ev.type);
+ assert_array_equals(actual_events,
+ expected_events.slice(0, actual_events.length));
+ if (expected_events.length == actual_events.length) {
+ t.done();
+ }
+ });
+ ['canplay', 'canplaythrough',
+ 'pause', 'play', 'playing'].forEach(function(type) {
+ e.addEventListener(type, callback);
+ });
+ }
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.autoplay = true;
+ expect_events(t, e, ['canplay', 'play', 'playing', 'canplaythrough']);
+ }, tagName + '.autoplay');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.autoplay = true;
+ e.pause(); // sets the autoplaying flag to false
+ e.load(); // sets the autoplaying flag to true
+ expect_events(t, e, ['canplay', 'play', 'playing', 'canplaythrough']);
+ }, tagName + '.autoplay and load()');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.autoplay = true;
+ e.play(); // sets the autoplaying flag to false
+ // play() also sets the paused attribute to false; there is no way for the
+ // autoplaying flag to be true when the paused attribute is false.
+ assert_equals(e.paused, false);
+ expect_events(t, e, ['play', 'canplay', 'playing', 'canplaythrough']);
+ }, tagName + '.autoplay and play()');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.autoplay = true;
+ e.pause(); // sets the autoplaying flag to false
+ expect_events(t, e, ['canplay', 'canplaythrough']);
+ }, tagName + '.autoplay and pause()');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.autoplay = true;
+ document.body.appendChild(e);
+ document.body.removeChild(e);
+ // in stable state, internal pause steps sets the autoplaying flag to false
+ expect_events(t, e, ['canplay', 'canplaythrough']);
+ }, tagName + '.autoplay and internal pause steps');
+}
+
+autoplay_test('audio', getAudioURI('/media/sound_5'));
+autoplay_test('video', getVideoURI('/media/movie_5'));
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplay.html
new file mode 100644
index 000000000..09ad89f8b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplay.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - readyState property during canplay</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.readyState should be >= HAVE_FUTURE_DATA during canplay event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplay", function() {
+ t.step(function() {
+ assert_greater_than_equal(a.readyState, a.HAVE_FUTURE_DATA);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - readyState property during canplay");
+
+test(function() {
+ var t = async_test("video.readyState should be >= HAVE_FUTURE_DATA during canplay event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplay", function() {
+ t.step(function() {
+ assert_greater_than_equal(v.readyState, v.HAVE_FUTURE_DATA);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - readyState property during canplay");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplaythrough.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplaythrough.html
new file mode 100644
index 000000000..7ef7b5f74
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplaythrough.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - readyState property during canplaythrough</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.readyState should be HAVE_ENOUGH_DATA during canplaythrough event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplaythrough", function() {
+ t.step(function() {
+ assert_equals(a.readyState,
+ a.HAVE_ENOUGH_DATA);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - readyState property during canplaythrough");
+
+test(function() {
+ var t = async_test("video.readyState should be HAVE_ENOUGH_DATA during canplaythrough event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplaythrough", function() {
+ t.step(function() {
+ assert_equals(v.readyState,
+ v.HAVE_ENOUGH_DATA);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - readyState property during canplaythrough");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html
new file mode 100644
index 000000000..1de85eb86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - readyState property during loadeddata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.readyState should be >= HAVE_CURRENT_DATA during loadeddata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadeddata", function() {
+ t.step(function() {
+ assert_greater_than_equal(a.readyState, a.HAVE_CURRENT_DATA);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - readyState property during loadeddata");
+
+test(function() {
+ var t = async_test("video.readyState should be >= HAVE_CURRENT_DATA during loadeddata event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadeddata", function() {
+ t.step(function() {
+ assert_greater_than_equal(v.readyState, v.HAVE_CURRENT_DATA);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - readyState property during loadeddata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html
new file mode 100644
index 000000000..85db8afb7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - readyState property during loadedmetadata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.readyState should be >= HAVE_METADATA during loadedmetadata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadedmetadata", function() {
+ t.step(function() {
+ assert_greater_than_equal(a.readyState, a.HAVE_METADATA);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - readyState property during loadedmetadata");
+
+test(function() {
+ var t = async_test("video.readyState should be >= HAVE_METADATA during loadedmetadata event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadedmetadata", function() {
+ t.step(function() {
+ assert_greater_than_equal(v.readyState, v.HAVE_METADATA);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - readyState property during loadedmetadata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_playing.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_playing.html
new file mode 100644
index 000000000..92a1b7f50
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_playing.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - readyState property during playing</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.readyState should be >= HAVE_FUTURE_DATA during playing event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("playing", function() {
+ t.step(function() {
+ assert_greater_than_equal(a.readyState, a.HAVE_FUTURE_DATA);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - readyState property during playing");
+
+test(function() {
+ var t = async_test("video.readyState should be >= HAVE_FUTURE_DATA during playing event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("playing", function() {
+ t.step(function() {
+ assert_greater_than_equal(v.readyState, v.HAVE_FUTURE_DATA);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - readyState property during playing");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_initial.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_initial.html
new file mode 100644
index 000000000..e9c112bd2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_initial.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.readyState - default state</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-networkstate">spec reference</a></p>
+ <audio id="a">
+ </audio>
+ <video id="v">
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var a = document.getElementById("a");
+ assert_equals(
+ a.readyState,
+ a.HAVE_NOTHING,
+ "audioElement.readyState should be HAVE_NOTHING to begin with");
+}, "audio.readyState - default state");
+
+test(function() {
+ var v = document.getElementById("v");
+ assert_equals(
+ v.readyState,
+ v.HAVE_NOTHING,
+ "videoElement.readyState should be HAVE_NOTHING to begin with");
+}, "video.readyState - default state");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime.html
new file mode 100644
index 000000000..3d577dac9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>seek to currentTime</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = getVideoURI('/media/movie_5');
+ v.onloadedmetadata = t.step_func(function() {
+ assert_greater_than(v.readyState, v.HAVE_NOTHING, 'readyState');
+ assert_greater_than(v.seekable.length, 0, 'seekable ranges');
+ assert_false(v.seeking, 'seeking before setting currentTime');
+ v.currentTime = v.currentTime;
+ assert_true(v.seeking, 'seeking after setting currentTime');
+ var events = [];
+ v.onseeking = v.ontimeupdate = v.onseeked = t.step_func(function(e) {
+ events.push(e.type);
+ // v.seeking can be true or false in the seeking event, see
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=24774
+ if (e.type != 'seeking') {
+ assert_equals(v.seeking, false, 'seeking in ' + e.type + ' event');
+ }
+ if (e.type == 'seeked') {
+ assert_array_equals(events, ['seeking', 'timeupdate', 'seeked'],
+ 'fired events');
+ t.done();
+ }
+ });
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-max-value.htm b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-max-value.htm
new file mode 100644
index 000000000..a31f6c07a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-max-value.htm
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>seek to Number.MAX_VALUE</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = getVideoURI('/media/movie_5');
+ v.onloadedmetadata = t.step_func(function() {
+ assert_equals(v.seekable.length, 1);
+ v.currentTime = Number.MAX_VALUE;
+ assert_true(v.seeking, 'seeking after setting');
+ assert_equals(v.currentTime, v.seekable.end(0), 'currentTime after setting');
+ v.onseeked = t.step_func(function(e) {
+ assert_false(v.seeking, 'seeking in seeked event');
+ assert_equals(v.currentTime, v.seekable.end(0), 'currentTime in seeked event');
+ t.done();
+ });
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time.htm b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time.htm
new file mode 100644
index 000000000..56a99028d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time.htm
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>seek to negative time</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = getVideoURI('/media/movie_5');
+ v.onloadedmetadata = t.step_func(function() {
+ assert_equals(v.seekable.start(0), 0, 'earliest seekable time');
+ v.currentTime = -1;
+ assert_true(v.seeking, 'seeking after setting');
+ assert_equals(v.currentTime, 0, 'currentTime after setting');
+ v.onseeked = t.step_func(function(e) {
+ assert_false(v.seeking, 'seeking in seeked event');
+ assert_equals(v.currentTime, 0, 'currentTime in seeked event');
+ t.done();
+ });
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/src_reflects_attribute_not_source_elements.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/src_reflects_attribute_not_source_elements.html
new file mode 100644
index 000000000..3dd43cc3f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/src_reflects_attribute_not_source_elements.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.src - reflection test</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-src">spec reference</a></p>
+ <audio id="audio" src="foo">
+ <source src="barbaz" />
+ </audio>
+ <video id="video" src="foo">
+ <source src="barbaz" />
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ assert_equals(
+ document.getElementById("audio").src.indexOf("barbaz"),
+ -1,
+ "audioElement.src should reflect src attribute, not source child elements");
+}, "audio.src - reflection test");
+
+test(function() {
+ assert_equals(
+ document.getElementById("video").src.indexOf("barbaz"),
+ -1,
+ "videoElement.src should reflect src attribute, not source child elements");
+}, "video.src - reflection test");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cloneNode.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cloneNode.html
new file mode 100644
index 000000000..1159a52ff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cloneNode.html
@@ -0,0 +1,86 @@
+<!doctype html>
+<title>track element cloneNode</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var elm = document.createElement('track');
+ assert_equals(elm.readyState, elm.NONE, 'elm.readyState after element creation');
+ var clone = elm.cloneNode(true);
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after element creation');
+ assert_not_equals(clone.track, elm.track, 'clone.track and elm.track');
+}, document.title+', not loaded');
+
+async_test(function(t) {
+ var elm = document.createElement('track');
+ var video = document.createElement('video');
+ video.appendChild(elm);
+ elm.track.mode = 'showing';
+ assert_equals(elm.readyState, elm.NONE, 'elm.readyState after appening to video setting mode');
+ elm.src = 'resources/track.vtt?pipe=trickle(d1)';
+ assert_equals(elm.readyState, elm.NONE, 'elm.readyState after setting src');
+ setTimeout(t.step_func_done(function() {
+ assert_equals(elm.readyState, elm.LOADING, 'elm.readyState in setTimeout');
+ var clone = elm.cloneNode(true);
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after element creation');
+ video.appendChild(clone);
+ clone.track.mode = 'showing';
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after appending to video and setting mode');
+ assert_not_equals(clone.track, elm.track, 'clone.track and elm.track');
+ }), 0);
+}, document.title+', loading');
+
+async_test(function(t) {
+ var elm = document.createElement('track');
+ var video = document.createElement('video');
+ video.appendChild(elm);
+ elm.track.mode = 'showing';
+ elm.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:01.000\nfoo');
+ assert_equals(elm.readyState, elm.NONE, 'elm.readyState after setting src');
+ elm.onload = this.step_func(function() {
+ assert_equals(elm.readyState, elm.LOADED, 'elm.readyState');
+ assert_equals(elm.track.cues.length, 1, 'elm.track.cues.length');
+ assert_equals(elm.track.cues[0].startTime, 0, 'elm.track.cues[0].startTime');
+ assert_equals(elm.track.cues[0].endTime, 1, 'elm.track.cues[0].endTime');
+ assert_equals(elm.track.cues[0].text, 'foo', 'elm.track.cues[0].text');
+ var clone = elm.cloneNode(true);
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after element creation');
+ video.appendChild(clone);
+ clone.track.mode = 'showing';
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after appending to video and setting mode');
+ assert_not_equals(clone.track, elm.track, 'clone.track and elm.track');
+ clone.onload = this.step_func(function(){
+ assert_equals(clone.readyState, clone.LOADED, 'clone.readyState');
+ assert_not_equals(clone.track, elm.track, 'clone.track and elm.track');
+ assert_not_equals(clone.track.cues, elm.track.cues, 'clone.track.cues and elm.track.cues');
+ assert_equals(clone.track.cues.length, 1, 'clone.track.cues.length');
+ assert_not_equals(clone.track.cues[0], elm.track.cues[0], 'cues[0]');
+ assert_equals(clone.track.cues[0].startTime, 0, 'clone.track.cues[0].startTime');
+ assert_equals(clone.track.cues[0].endTime, 1, 'clone.track.cues[0].endTime');
+ assert_equals(clone.track.cues[0].text, 'foo', 'clone.track.cues[0].text');
+ this.done();
+ });
+ clone.onerror = this.step_func(function() { assert_unreached('clone got error'); });
+ });
+ elm.onerror = this.step_func(function() { assert_unreached('elm got error'); });
+}, document.title+', loaded');
+
+async_test(function(t) {
+ var elm = document.createElement('track');
+ var video = document.createElement('video');
+ video.appendChild(elm);
+ elm.track.mode = 'showing';
+ elm.onerror = t.step_func(function() {
+ assert_equals(elm.readyState, elm.ERROR, 'elm.readyState in onerror');
+ var clone = elm.cloneNode(true);
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after element creation');
+ video.appendChild(clone);
+ clone.track.mode = 'showing';
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after appending to video and setting mode');
+ assert_not_equals(clone.track, elm.track, 'clone.track and elm.track');
+ clone.onerror = t.step_func_done();
+ });
+ elm.src = 'javascript:"network error"';
+}, document.title+', failed to load');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/003.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/003.html
new file mode 100644
index 000000000..4236df29b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/003.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/004.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/004.html
new file mode 100644
index 000000000..4f86d011a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/004.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/005.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/005.html
new file mode 100644
index 000000000..e6a693400
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/005.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/006.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/006.html
new file mode 100644
index 000000000..351b97d67
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/006.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/007.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/007.html
new file mode 100644
index 000000000..4ccc6b66a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/007.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/008.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/008.html
new file mode 100644
index 000000000..0444a8308
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/008.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/009.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/009.html
new file mode 100644
index 000000000..dd6223275
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/009.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/010.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/010.html
new file mode 100644
index 000000000..d75d6f4d6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/010.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/011.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/011.html
new file mode 100644
index 000000000..6d0fae6de
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/011.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/012.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/012.html
new file mode 100644
index 000000000..110497b49
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/012.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/013.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/013.html
new file mode 100644
index 000000000..d2a9ddb19
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/013.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/014.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/014.html
new file mode 100644
index 000000000..a1d6a8b29
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/014.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/015.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/015.html
new file mode 100644
index 000000000..2850a24e1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/015.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, same-origin, with headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/016.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/016.html
new file mode 100644
index 000000000..5cd5a85d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/016.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/017.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/017.html
new file mode 100644
index 000000000..0ec5bc329
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/017.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/018.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/018.html
new file mode 100644
index 000000000..f639d043a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/018.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/019.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/019.html
new file mode 100644
index 000000000..45e1291c9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/019.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, with headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/020.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/020.html
new file mode 100644
index 000000000..e1153b681
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/020.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'no'}]}; // redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/021.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/021.html
new file mode 100644
index 000000000..ec2e9d8bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/021.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, with headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'no'}, {cors:'null', cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/022.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/022.html
new file mode 100644
index 000000000..e8fb0c3d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/022.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, with headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'no'}, {cors:'null', cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/023.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/023.html
new file mode 100644
index 000000000..ac9bb3546
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/023.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'yes'}]}; // redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/024.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/024.html
new file mode 100644
index 000000000..302340022
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/024.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, with headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'yes'}, {cors:'null', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/025.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/025.html
new file mode 100644
index 000000000..5cbe8528e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/025.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, with headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'yes'}, {cors:'null', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/026.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/026.html
new file mode 100644
index 000000000..c8386ffff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/026.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, same-origin, with headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}]}; // redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/027.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/027.html
new file mode 100644
index 000000000..5fe4760e6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/027.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/028.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/028.html
new file mode 100644
index 000000000..6019d37b6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/028.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, with headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/029.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/029.html
new file mode 100644
index 000000000..7fa85456d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/029.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/030.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/030.html
new file mode 100644
index 000000000..f7abf3b1e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/030.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, with headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/031.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/031.html
new file mode 100644
index 000000000..d709d0bc4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/031.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, no headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'no'}]}; // redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/032.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/032.html
new file mode 100644
index 000000000..62b1008a4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/032.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, with headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'no'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/033.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/033.html
new file mode 100644
index 000000000..215cae241
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/033.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, with headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'no'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/034.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/034.html
new file mode 100644
index 000000000..bebb43ba8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/034.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, no headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'yes'}]}; // redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/035.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/035.html
new file mode 100644
index 000000000..a17fb7dfc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/035.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, with headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/036.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/036.html
new file mode 100644
index 000000000..52411177e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/036.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, with headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/037.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/037.html
new file mode 100644
index 000000000..675b913a1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/037.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to not same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}]}; // second redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/038.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/038.html
new file mode 100644
index 000000000..a29b2bdea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/038.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, with headers, redirects to not same-origin, with headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}, {cors:'null', cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/039.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/039.html
new file mode 100644
index 000000000..fcd4871dd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/039.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to not same-origin, with headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}, {cors:'null', cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/040.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/040.html
new file mode 100644
index 000000000..3c819684c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/040.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to not same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}]}; // second redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/041.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/041.html
new file mode 100644
index 000000000..f0f81953f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/041.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, with headers, redirects to not same-origin, with headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}, {cors:'null', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/042.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/042.html
new file mode 100644
index 000000000..c1ffa5f1e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/042.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to not same-origin, with headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}, {cors:'null', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/043.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/043.html
new file mode 100644
index 000000000..09072a989
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/043.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to same-origin, no headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/044.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/044.html
new file mode 100644
index 000000000..0d4a9fefb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/044.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to same-origin, no headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/045.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/045.html
new file mode 100644
index 000000000..7151364f9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/045.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to same-origin, no headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/046.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/046.html
new file mode 100644
index 000000000..e28646281
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/046.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to same-origin, no headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/common.js b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/common.js
new file mode 100644
index 000000000..9d48abde0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/common.js
@@ -0,0 +1,144 @@
+setup(function(){
+ window.id = token();
+ var p = document.createElement('p');
+ p.innerHTML = 'Test id: <samp>'+id+'</samp>';
+ document.body.appendChild(p);
+ window.actual = {event:null, requests:[]};
+ window.errors = [];
+ window.origin = location.protocol+'//'+location.host;
+ window.escapedOrigin = encodeURIComponent(origin);
+ window.sameOriginURL = "http://{{domains[]}}:{{ports[http][0]}}" + location.pathname.replace(/\/[^\/]+$/, '/');
+ window.otherOriginURL = "http://{{domains[www1]}}:{{ports[http][0]}}" + location.pathname.replace(/\/[^\/]+$/, '/');
+}, {timeout:10000, explicit_done:true});
+
+onload = function() {
+ (async_test(document.title, {timeout:10000})).step(function() {
+ // fail early if track isn't supported
+ assert_true('HTMLTrackElement' in window, 'track not supported');
+ window.corsMode = document.title.match(/^track CORS: (No CORS|Anonymous|Use Credentials)/)[1];
+ var requests_tmp = document.title.substr(('track CORS: '+corsMode+', ').length).split(/, redirects to /g);
+ window.requests = [];
+ requests_tmp.forEach(function(r) {
+ var parts = r.split(', ');
+ requests.push({sameOrigin:parts[0] == 'same-origin', withHeaders:parts[1] == 'with headers'});
+ });
+ if (document.title.indexOf('not same-origin') > -1) {
+ window.hasCrossDomainCookie = true;
+ this.step(setCrossDomainCookie);
+ } else {
+ window.hasCrossDomainCookie = false;
+ this.step(loadTrack);
+ }
+ });
+ done();
+};
+
+function setCrossDomainCookie() {
+ var iframe = document.createElement('iframe');
+ iframe.onload = this.step_func(loadTrack);
+ iframe.src = otherOriginURL + 'support/set-cookie.html#'+id;
+ document.body.appendChild(iframe);
+}
+
+function loadTrack() {
+ var video = document.createElement('video');
+ window.track = document.createElement('track');
+ if (corsMode == 'Anonymous')
+ video.setAttribute('crossorigin', 'anonymous');
+ else if (corsMode == 'Use Credentials')
+ video.setAttribute('crossorigin', 'use-credentials');
+ // else No CORS, omit the crossorigin attribute
+ video.appendChild(track);
+ document.body.appendChild(video);
+ track.track.mode = 'showing';
+ document.cookie = id+'=yes;path=/;max-age=10';
+ var url = '';
+ var r;
+ while (r = requests.pop()) {
+ url = (r.sameOrigin ? sameOriginURL : otherOriginURL) +
+ 'support/cors-tester.py?id=' + id +
+ (r.withHeaders ? '&origin=' + escapedOrigin : '') +
+ (url === '' ? '' : '&redirect=' + encodeURIComponent(url));
+ }
+ track.src = url;
+ track.onerror = track.onload = this.step_func(function(e) {
+ actual.event = e.type;
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', 'support/cors-tester.py?read=true&id=' + id, true);
+ xhr.onload = this.step_func(function() {
+ if (xhr.status == 200) {
+ var lines = xhr.responseText.split('\n');
+ lines.forEach(function(line) {
+ var chunks = line.split(' | ');
+ var current = {};
+ actual.requests.push(current);
+ chunks.forEach(function(chunk) {
+ var nameval = chunk.split(' = ');
+ var name = nameval[0];
+ var value = nameval[1];
+ current[name] = value;
+ });
+ });
+ } else if (xhr.status == 404) {
+ //No stash was found
+ } else {
+ errors.push('got unexpected xhr status: '+xhr.status);
+ }
+ this.step(removeCookies);
+ });
+ xhr.onerror = this.step_func(function() {
+ errors.push('got xhr error');
+ this.step(removeCookies);
+ });
+ xhr.send();
+ });
+}
+
+function removeCookies() {
+ document.cookie = id+'=;path=/;max-age=0';
+ var nextStep = checkData;
+ if (hasCrossDomainCookie) {
+ var iframe = document.createElement('iframe');
+ iframe.onload = this.step_func(nextStep);
+ iframe.src = otherOriginURL + 'support/cors-tester.py?delete-cookie&id=' + id;
+ document.body.appendChild(iframe);
+ } else {
+ this.step(nextStep);
+ }
+}
+
+function removeLog() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', 'support/cors-tester.py?cleanup&id='+id, true);
+ xhr.onload = this.step_func(function() {
+ assert_equals(xhr.responseText, 'OK', 'failed to clean up log: '+id);
+ this.step(checkData);
+ });
+ xhr.onerror = this.step_func(function() {
+ assert_unreached('failed to clean up log: '+id);
+ });
+ xhr.send();
+}
+
+function checkData() {
+ assert_equals(errors.length, 0, errors);
+ try {
+ if (actual.event == 'load' && expected.event == 'error')
+ assert_unreached('Security problem: got load event but expected error event');
+ assert_object_equals(actual, expected);
+ } catch(ex) {
+ var style = document.createElement('style');
+ style.textContent = '.json-diffs td { vertical-align:top } .json-diffs pre { margin:0 }';
+ document.head.appendChild(style);
+ var table = document.createElement('table');
+ table.border = "";
+ table.className = 'json-diffs';
+ table.innerHTML = '<tr><th>Actual<th>Expected<tr><td><pre></pre><td><pre></pre>';
+ table.getElementsByTagName('pre')[0].textContent = JSON.stringify(actual, null, 2);
+ table.getElementsByTagName('pre')[1].textContent = JSON.stringify(expected, null, 2);
+ document.body.insertBefore(table, document.getElementById('log'));
+ throw ex;
+ }
+ assert_equals(track.track.cues.length, expected.event == 'load' ? 1 : 0, 'track.track.cues.length');
+ this.done();
+}
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/cors-tester.py b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/cors-tester.py
new file mode 100644
index 000000000..1c27a0d14
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/cors-tester.py
@@ -0,0 +1,51 @@
+from wptserve.handlers import HTTPException
+import urllib
+
+def main(request, response):
+ if request.method != "GET":
+ raise HTTPException(400, message="Method was not GET")
+
+ if not "id" in request.GET:
+ raise HTTPException(400, message="No id")
+
+ id = request.GET['id']
+
+ if "read" in request.GET:
+ data = request.server.stash.take(id)
+ if data is None:
+ response.set_error(404, "Tried to read data not yet set")
+ return
+ return [("Content-Type", "text/plain")], data
+
+ elif "cleanup" in request.GET:
+ request.server.stash.take(id)
+ return "OK"
+
+ elif "delete-cookie" in request.GET:
+ response.delete_cookie(id)
+ return [("Content-Type", "text/plain")], "OK"
+
+ if "origin" in request.GET:
+ response.headers.set('Access-Control-Allow-Origin', request.GET['origin'])
+ response.headers.set('Access-Control-Allow-Credentials', 'true')
+
+ cors = request.headers.get("origin", "no")
+
+ cookie = request.cookies.first(id, "no")
+
+ line = 'cors = ' + cors + ' | cookie = ' + cookie.value;
+
+ data = request.server.stash.take(id)
+ if data is not None:
+ line = data + "\n" + line
+
+ request.server.stash.put(id, line)
+
+ if "redirect" in request.GET:
+ response.status = 302
+ response.headers.set('Location', request.GET['redirect'])
+ else:
+ return """WEBVTT
+
+00:00:00.000 --> 00:00:10.000
+Test"""
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/remove-cookie.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/remove-cookie.html
new file mode 100644
index 000000000..00430e3f0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/remove-cookie.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<title>Remove cookie from location.hash</title>
+<script>
+if (location.hash)
+ document.cookie = decodeURIComponent(location.hash.substr(1))+'=yes;path=/;max-age=0';
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/set-cookie.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/set-cookie.html
new file mode 100644
index 000000000..cc1c92638
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/set-cookie.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<title>Set cookie from location.hash</title>
+<script>
+if (location.hash)
+ document.cookie = decodeURIComponent(location.hash.substr(1))+'=yes;path=/;max-age=15';
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.de.vtt b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.de.vtt
new file mode 100644
index 000000000..9eaf3d31e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.de.vtt
@@ -0,0 +1,4 @@
+WEBVTT
+
+00:00:00.000 --> 00:00:01.000
+German
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.en.vtt b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.en.vtt
new file mode 100644
index 000000000..4241f35b5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.en.vtt
@@ -0,0 +1,4 @@
+WEBVTT
+
+00:00:00.000 --> 00:00:01.000
+English
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.fr.vtt b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.fr.vtt
new file mode 100644
index 000000000..5523224e0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.fr.vtt
@@ -0,0 +1,4 @@
+WEBVTT
+
+00:00:00.000 --> 00:00:01.000
+french
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.vtt b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.vtt
new file mode 100644
index 000000000..c916c0983
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.vtt
@@ -0,0 +1,4 @@
+WEBVTT
+
+00:00:00.000 --> 00:00:01.000
+test
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues.html
new file mode 100644
index 000000000..3ba8c9db8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<title>track element changing "track URL" and clearing cues</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+(async_test(document.title+', set mode, add cue, set src')).step(function(){
+ var track = document.createElement('track');
+ var c = new VTTCue(0, 1, 'foo');
+ c.id = 'id';
+ track.track.addCue(c);
+ assert_equals(track.track.cues, null, 'cues before setting src or mode');
+ track.track.mode = 'showing';
+ assert_equals(track.track.cues.length, 1, 'cues after setting mode');
+ var cues = track.track.cues;
+ track.src = 'data:,a';
+ assert_equals(track.track.cues.length, 0, 'cues.length after setting src');
+ assert_equals(track.track.cues, cues, 'track.track.cues sameness after setting src');
+ assert_equals(c.id, 'id', 'liveness of removed cue');
+ this.done();
+});
+
+(async_test(document.title+', set mode, set src, add cue, change src')).step(function(){
+ var track = document.createElement('track');
+ track.track.mode = 'showing';
+ track.src = 'data:,a';
+ var c = new VTTCue(0, 1, 'foo');
+ c.id = 'id';
+ track.track.addCue(c);
+ assert_equals(track.track.cues.length, 1, 'cues.length before changing src');
+ var cues = track.track.cues;
+ track.src = 'data:,b';
+ assert_equals(track.track.cues.length, 0, 'cues.length after changing src');
+ assert_equals(track.track.cues, cues, 'track.track.cues sameness after changing src');
+ assert_equals(c.id, 'id', 'liveness of removed cue');
+ this.done();
+});
+
+(async_test(document.title+', set mode, add cue, change mode to disabled, set src')).step(function(){
+ var track = document.createElement('track');
+ track.track.mode = 'showing';
+ var c = new VTTCue(0, 1, 'foo');
+ c.id = 'id';
+ track.track.addCue(c);
+ var cues = track.track.cues;
+ track.track.mode = 'disabled';
+ track.src = 'data:,a';
+ assert_equals(cues.length, 0, 'cues.length after changing src');
+ assert_equals(c.id, 'id', 'liveness of removed cue');
+ this.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html
new file mode 100644
index 000000000..b2840d235
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Track element - text tracks API test</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#text-track-api">
+<link rel="author" title="Hyunjin Cho">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<h1>Track element and API Test</h1>
+<div style="display:none;">
+ <video id="tracktest" src="/media/movie_300.mp4">
+ <track kind="subtitles" src="resources/track.en.vtt" srclang="en" label="English">
+ <track kind="captions" src="resources/track.en.vtt" srclang="en" label="English with Captions">
+ <track id="french" kind="subtitles" src="resources/track.fr.vtt" srclang="fr" label="Francais">
+ <track kind="subtitles" src="resources/track.de.vtt" srclang="de" label="Deutsch">
+ </video>
+</div>
+<div id="log"></div>
+<script>
+test(function() {
+ var t1 = document.getElementById('tracktest').textTracks;
+ assert_not_equals(t1, undefined, "textTracks member should not be undefined");
+}, "Check the track elements");
+test(function() {
+ var t2 = document.getElementById('tracktest').textTracks.getTrackById("french");
+ assert_not_equals(t2, undefined, "textTracks member should not be undefined");
+}, "Check getTrackById method");
+test(function() {
+ var t3 = document.getElementById('tracktest').textTracks.length;
+ assert_equals(t3, 4, "textTracks List should be 4");
+}, "Count track list");
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/user-interface/muted.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/user-interface/muted.html
new file mode 100644
index 000000000..906350d88
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/user-interface/muted.html
@@ -0,0 +1,152 @@
+<!doctype html>
+<title>muted</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<style>video { display: none; }</style>
+<div id=log></div>
+
+<script>
+function test_setting(e, muted, hasAttribute) {
+ assert_equals(e.muted, muted);
+ assert_equals(e.hasAttribute('muted'), hasAttribute);
+
+ e.muted = !e.muted;
+ assert_equals(e.muted, !muted);
+ assert_equals(e.hasAttribute('muted'), hasAttribute);
+
+ e.muted = !e.muted;
+ assert_equals(e.muted, muted);
+ assert_equals(e.hasAttribute('muted'), hasAttribute);
+}
+</script>
+
+<!-- These tests are inside <audio>/<video> so that the steps for updating the
+ muted IDL attribute cannot be delayed until the end tag is parsed. -->
+
+<audio id=a1>
+<script>
+var a1 = document.getElementById('a1');
+
+test(function() {
+ assert_false(a1.muted);
+}, 'getting audio.muted (parser-created)');
+
+test(function() {
+ test_setting(a1, false, false);
+}, 'setting audio.muted (parser-created)');
+</script>
+</audio>
+
+<audio id=a2 muted>
+<script>
+var a2 = document.getElementById('a2');
+
+test(function() {
+ assert_true(a2.muted);
+}, 'getting audio.muted with muted="" (parser-created)');
+
+test(function() {
+ test_setting(a2, true, true);
+}, 'setting audio.muted with muted="" (parser-created)');
+</script>
+</audio>
+
+<video id=v1>
+<script>
+var v1 = document.getElementById('v1');
+
+test(function() {
+ assert_false(v1.muted);
+}, 'getting video.muted (parser-created)');
+
+test(function() {
+ test_setting(v1, false, false);
+}, 'setting video.muted (parser-created)');
+</script>
+</video>
+
+<video id=v2 muted>
+<script>
+var v2 = document.getElementById('v2');
+
+test(function() {
+ assert_true(v2.muted);
+}, 'getting video.muted with muted="" (parser-created)');
+
+test(function() {
+ test_setting(v2, true, true);
+}, 'setting video.muted with muted="" (parser-created)');
+</script>
+</video>
+
+<!-- Negative test to ensure that the load algorithm does not update the
+ muted IDL attribute to match the content attribute. -->
+
+<video id=v3 muted></video>
+<script>
+async_test(function(t) {
+ var v = document.getElementById('v3');
+ assert_true(v.muted);
+ v.muted = false;
+ v.src = 'data:,'; // invokes load()
+ v.addEventListener('error', t.step_func(function() {
+ assert_false(v.muted);
+ t.done();
+ }));
+}, 'getting video.muted with muted="" after load (parser-created)');
+</script>
+
+<script>
+['audio', 'video'].forEach(function(tagName) {
+ test(function() {
+ var m = document.createElement(tagName);
+ assert_false(m.muted);
+ }, 'getting ' + tagName + '.muted (script-created)');
+
+ test(function() {
+ var m = document.createElement(tagName);
+ test_setting(m, false, false);
+ }, 'setting ' + tagName + '.muted (script-created)');
+
+ test(function() {
+ var m = document.createElement(tagName);
+ m.setAttribute('muted', '');
+ assert_false(m.muted);
+ }, 'getting ' + tagName + '.muted with muted="" (script-created)');
+
+ test(function() {
+ var m = document.createElement(tagName);
+ m.setAttribute('muted', '');
+ test_setting(m, false, true);
+ }, 'setting ' + tagName + '.muted with muted="" (script-created)');
+
+ // Spec bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25153
+ /*
+ test(function() {
+ var m = document.createElement(tagName);
+ m.setAttribute('muted', '');
+ m = m.cloneNode(false);
+ assert_true(m.hasAttribute('muted'));
+ assert_false(m.muted);
+ }, 'getting ' + tagName + '.muted with muted="" (cloneNode-created)');
+ */
+
+ test(function() {
+ var div = document.createElement('div');
+ div.innerHTML = '<' + tagName + ' muted>';
+ m = div.firstChild;
+ assert_true(m.hasAttribute('muted'));
+ assert_true(m.muted);
+ }, 'getting ' + tagName + '.muted with muted="" (innerHTML-created)');
+
+ test(function() {
+ var id = tagName;
+ assert_equals(document.getElementById(id), null);
+ document.write('<' + tagName + ' id=' + id + ' muted>');
+ m = document.getElementById(id);
+ assert_true(m.hasAttribute('muted'));
+ assert_true(m.muted);
+ }, 'getting ' + tagName + '.muted with muted="" (document.write-created)');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_008.htm b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_008.htm
new file mode 100644
index 000000000..dff49d824
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_008.htm
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>HTML5 Media Elements: 'media' attribute</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/html5/video.html#the-source-element" />
+ <meta name="assert" content="'media' attribute is 'all' by default." />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript" src="/common/media.js"></script>
+ <script type="text/javascript">
+ var videotest = async_test();
+
+ function do_play(event)
+ {
+ videotest.step(function() {
+ var vid = document.getElementById("video0");
+ assert_true(vid.currentSrc.indexOf("movie_300") > 0);
+ });
+ videotest.done();
+ }
+
+ </script>
+ </head>
+ <body>
+ <div id='log'></div>
+
+ <video id="video0" autoplay onplay="do_play(event);">
+ <script type="text/javascript">
+
+ document.write(
+ "<source media='not all' src='" + getVideoURI("/media/movie_300") + "'" +
+ " />"
+ );
+ document.write(
+ "<source src='" + getVideoURI("/media/movie_5") + "'" +
+ " media='all' />"
+ );
+
+ </script>
+ Your browser does not support media elements.
+ </video>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_controls_present-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_controls_present-manual.html
new file mode 100644
index 000000000..8e44951d7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_controls_present-manual.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_controls_present.html</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-controls" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the controls attribute is present in the video element that expecting the user agent exposes a controller user interface" />
+ </head>
+ <body>
+ <p>Test passes if a controller user interface appears below and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <video id="m" controls>The user agent doesn't support media element.</video>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_loop_base.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_loop_base.html
new file mode 100644
index 000000000..348f1cdae
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_loop_base.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_loop_base</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-loop" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if video.loop is set to true that expecting the seeking event is fired more than once" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <video id="m" controls>The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ var name = document.getElementsByName("assert")[0].content;
+ var t = async_test(name);
+ var looped = false;
+
+ function startTest() {
+ if (looped) {
+ t.step(function() {
+ assert_true(true, "looped");
+ });
+ t.done();
+ media.pause();
+ }
+
+ looped = true;
+ }
+
+ media.addEventListener("seeking", startTest, false);
+ media.loop = true;
+ media.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_overriding_volume-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_overriding_volume-manual.html
new file mode 100644
index 000000000..6d770666c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_overriding_volume-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_muted_overriding_volume</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-muted" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the muted attribute is present in the video element with volume is set to loudest that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the video is playing without sound output and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <video id="m" controls muted>The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ media.volume = 1.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_present-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_present-manual.html
new file mode 100644
index 000000000..bc8082777
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_present-manual.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_muted_present</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-muted" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the muted attribute is present in the video element that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the video is playing without sound output and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <video id="m" controls muted>The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_check.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_check.html
new file mode 100644
index 000000000..1a45358a7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_check.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_volume_check</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check that video.volume returns the value of the muted content attribute" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <video id="m">The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ var VOLUME = {
+ 'SILENT' : 0.0,
+ 'NORMAL' : 0.5,
+ 'LOUDEST' : 1.0,
+ 'LOWER' : -1.1,
+ 'UPPER' : 1.1,
+ };
+
+ test(function() {
+ assert_false(media.volume < VOLUME.SILENT || media.volume > VOLUME.LOUDEST, "media.volume outside the range 0.0 to 1.0 inclusive");
+ }, "Check if the intial value of the video.volume is in the range 0.0 to 1.0 inclusive");
+
+ function volume_setting(vol, name)
+ {
+ if (vol < VOLUME.SILENT || vol > VOLUME.LOUDEST) {
+ try {
+ media.volume = vol;
+ test(function() {
+ assert_true(false, "media.volume setting exception");
+ }, name);
+ } catch(e) {
+ test(function() {
+ // 1 should be e.IndexSizeError or e.INDEX_SIZE_ERR in previous spec
+ assert_equals(e.code, 1, "media.volume setting exception");
+ }, name);
+ }
+ } else {
+ media.volume = vol;
+ test(function() {
+ assert_equals(media.volume, vol, "media.volume new value");
+ }, name);
+ }
+ }
+
+ volume_setting(VOLUME.NORMAL, "Check if video.volume is able to set to new value in the range 0.0 to 1.0");
+ volume_setting(VOLUME.SILENT, "Check if media.volume is able to set to new value 0.0 as silent");
+ volume_setting(VOLUME.LOUDEST, "Check if media.volume is able to set to new value 1.0 as loudest");
+ volume_setting(VOLUME.LOWER, "Check if media.volume is set to new value less than 0.0 that expecting an IndexSizeError exception is to be thrown");
+ volume_setting(VOLUME.UPPER, "Check if video.volume is set to new value greater than 1.0 that expecting an IndexSizeError exception is to be thrown");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_loudest-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_loudest-manual.html
new file mode 100644
index 000000000..747578120
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_loudest-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_volume_loudest</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the volume attribute is set to 1.0 as loudest in the video element that expecting the user hears sound loudly" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the video is playing with sound heard and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <video id="m" controls>The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ media.volume = 1.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_silent-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_silent-manual.html
new file mode 100644
index 000000000..1768dd4d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_silent-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_volume_silent</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the volume attribute is set to 0.0 as silent in the video element that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the video is playing without sound heard and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <video id="m" controls volume=0.0>The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ media.volume = 0.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/volume_nonfinite.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/volume_nonfinite.html
new file mode 100644
index 000000000..6e90a2ebc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/volume_nonfinite.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Setting HTMLMediaElement.volume to non-finite numbers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+["audio", "video"].forEach(function(aElement) {
+ [NaN, Infinity, -Infinity].forEach(function(aValue) {
+ test(function() {
+ var el = document.createElement(aElement);
+ assert_throws(new TypeError(), function() {
+ el.volume = aValue;
+ });
+ }, "Setting " + aElement + ".volume to " + String(aValue) + " should throw a TypeError");
+ });
+});
+</script>