-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Web Platform Tests for HTML video element lazy loading via the loading attribute #57051
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
6119c88
0b1b671
bb70f86
958e09b
12e5e03
2c8ab51
93197db
75414dc
b463e44
c285504
53a9a24
772ebf5
95fdaae
136a26b
a302230
e2e728c
aafc795
8460c52
3b761e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| <!DOCTYPE html> | ||
| <link rel="author" title="Squarespace" href="https://www.squarespace.com/"> | ||
| <script src="/resources/testharness.js"></script> | ||
| <script src="/resources/testharnessreport.js"></script> | ||
|
|
||
| <video id="target"></video> | ||
|
|
||
| <script> | ||
| const video = document.getElementById("target"); | ||
|
|
||
| test(() => { | ||
| assert_equals( | ||
| video.loading, | ||
| "eager", | ||
| "Video loading property should be 'eager' when attribute is not set" | ||
| ); | ||
| }, "Video loading attribute default should be eager when not set"); | ||
| </script> | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| <!DOCTYPE html> | ||
| <link rel="author" title="Squarespace" href="https://www.squarespace.com/"> | ||
| <script src="/resources/testharness.js"></script> | ||
| <script src="/resources/testharnessreport.js"></script> | ||
|
|
||
| <video id="target" loading="lazy"></video> | ||
|
|
||
| <script> | ||
| const video = document.getElementById("target"); | ||
|
|
||
| test(() => { | ||
| assert_equals( | ||
| video.loading, | ||
| "lazy", | ||
| "Video loading attribute should be 'lazy' when set to 'lazy'" | ||
| ); | ||
| }, "Video loading attribute should reflect the loading content attribute"); | ||
| </script> | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| <!DOCTYPE html> | ||
| <link rel="author" title="Squarespace" href="https://www.squarespace.com/"> | ||
| <script src="/resources/testharness.js"></script> | ||
| <script src="/resources/testharnessreport.js"></script> | ||
|
|
||
| <video id="target"></video> | ||
|
|
||
| <script> | ||
| const video = document.getElementById("target"); | ||
|
|
||
| test(() => { | ||
| video.removeAttribute("loading"); | ||
| assert_equals(video.loading, "eager", "Default value should be 'eager'"); | ||
| }, "Video loading attribute default value is 'eager'"); | ||
|
|
||
| test(() => { | ||
| video.setAttribute("loading", "lazy"); | ||
| assert_equals(video.loading, "lazy", "loading='lazy' should reflect as 'lazy'"); | ||
| }, "Video loading attribute reflects 'lazy'"); | ||
|
|
||
| test(() => { | ||
| video.setAttribute("loading", "eager"); | ||
| assert_equals(video.loading, "eager", "loading='eager' should reflect as 'eager'"); | ||
| }, "Video loading attribute reflects 'eager'"); | ||
|
|
||
| test(() => { | ||
| video.setAttribute("loading", "invalid"); | ||
| assert_equals(video.loading, "eager", "Invalid value should reflect as 'eager'"); | ||
| }, "Video loading attribute with invalid value reflects as 'eager'"); | ||
|
|
||
| test(() => { | ||
| video.setAttribute("loading", ""); | ||
| assert_equals(video.loading, "eager", "Empty string should reflect as 'eager'"); | ||
| }, "Video loading attribute with empty string reflects as 'eager'"); | ||
|
|
||
| test(() => { | ||
| video.setAttribute("loading", "LAZY"); | ||
| assert_equals(video.loading, "lazy", "Uppercase 'LAZY' should reflect as 'lazy'"); | ||
| }, "Video loading attribute is case-insensitive for 'lazy'"); | ||
|
|
||
| test(() => { | ||
| video.setAttribute("loading", "EAGER"); | ||
| assert_equals(video.loading, "eager", "Uppercase 'EAGER' should reflect as 'eager'"); | ||
| }, "Video loading attribute is case-insensitive for 'eager'"); | ||
|
|
||
| test(() => { | ||
| video.loading = "lazy"; | ||
| assert_equals(video.getAttribute("loading"), "lazy", "Setting IDL to 'lazy' should set content attribute"); | ||
| assert_equals(video.loading, "lazy", "IDL should reflect 'lazy'"); | ||
| }, "Setting video.loading IDL attribute to 'lazy'"); | ||
|
|
||
| test(() => { | ||
| video.loading = "eager"; | ||
| assert_equals(video.getAttribute("loading"), "eager", "Setting IDL to 'eager' should set content attribute"); | ||
| assert_equals(video.loading, "eager", "IDL should reflect 'eager'"); | ||
| }, "Setting video.loading IDL attribute to 'eager'"); | ||
|
|
||
| test(() => { | ||
| video.loading = "invalid"; | ||
| assert_equals(video.getAttribute("loading"), "invalid", "Setting IDL to 'invalid' should set content attribute"); | ||
| assert_equals(video.loading, "eager", "IDL should reflect 'eager' for invalid content attribute"); | ||
| }, "Setting video.loading IDL attribute to invalid value"); | ||
| </script> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| <!DOCTYPE html> | ||
| <link rel="author" title="Squarespace" href="https://www.squarespace.com/"> | ||
| <script src="/resources/testharness.js"></script> | ||
| <script src="/resources/testharnessreport.js"></script> | ||
|
|
||
| <style> | ||
| #target { | ||
| position: absolute; | ||
| top: 1000vh; | ||
| } | ||
| </style> | ||
|
|
||
| <video id="target" src="/media/A4.mp4" loading="lazy" muted playsinline autoplay></video> | ||
|
|
||
| <script> | ||
| const t = async_test( | ||
| "Video with loading=lazy and autoplay that is not visible in viewport does not load video data or autoplay" | ||
| ); | ||
|
|
||
| const video = document.getElementById("target"); | ||
|
|
||
| video.addEventListener("loadstart", () => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having the video element in markup and adding a listener in a script afterwards can miss the event. Either create the video in script or have a capturing listener before the video element exists. (Same in some other tests.) |
||
| t.step(() => { | ||
| assert_unreached("Video should not fire loadstart event when not visible in viewport"); | ||
| }); | ||
| }); | ||
|
|
||
| t.step_timeout(() => { | ||
| assert_equals(video.readyState, HTMLMediaElement.HAVE_NOTHING); | ||
| assert_true(video.paused, "Video should not autoplay when not visible in viewport"); | ||
| t.done(); | ||
| }, 2000); | ||
| </script> | ||
| </body> | ||
| </html> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| <!DOCTYPE html> | ||
| <link rel="author" title="Squarespace" href="https://www.squarespace.com/"> | ||
| <script src="/resources/testharness.js"></script> | ||
| <script src="/resources/testharnessreport.js"></script> | ||
|
|
||
| <style> | ||
| .below-viewport { | ||
| position: absolute; | ||
| top: 1000vh; | ||
| } | ||
| </style> | ||
|
|
||
| <video id="below_viewport" class="below-viewport" src="/media/A4.mp4?pipe=trickle(d2)" loading="eager"></video> | ||
|
|
||
| <script> | ||
| const belowViewportVideo = document.getElementById("below_viewport"); | ||
| let dataLoaded = false; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not used; remove. |
||
|
|
||
| async_test(t => { | ||
| belowViewportVideo.addEventListener("loadeddata", t.step_func(() => { | ||
| dataLoaded = true; | ||
| t.done(); | ||
| })); | ||
|
|
||
| //if data is not loaded after 5 seconds, assert unreached | ||
| t.step_timeout(() => { | ||
| assert_unreached("Eager video should load data immediately"); | ||
| }, 5000); | ||
| }, "Videos with loading='eager' load immediately regardless of viewport position"); | ||
| </script> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| <!DOCTYPE html> | ||
| <link rel="author" title="Squarespace" href="https://www.squarespace.com/"> | ||
| <script src="/resources/testharness.js"></script> | ||
| <script src="/resources/testharnessreport.js"></script> | ||
|
|
||
| <style> | ||
| #target { | ||
| position: absolute; | ||
| top: 1000vh; | ||
| } | ||
| </style> | ||
|
|
||
| <video id="target" src="/media/A4.mp4" loading="lazy" muted playsinline autoplay width="100" height="100"></video> | ||
|
|
||
| <script> | ||
| const video = document.getElementById("target"); | ||
|
|
||
| const t = async_test( | ||
| "Video with loading=lazy and autoplay does not play while not visible, then plays once scrolled into view" | ||
| ); | ||
| let scrolledIntoView = false; | ||
|
|
||
| t.step_timeout(() => { | ||
| // Verify video has not played before scrolling | ||
| t.step(() => { | ||
| assert_true(video.paused, "Video should be paused when not visible in viewport"); | ||
| }); | ||
|
|
||
| // bind to play event to assert true that play has begun after scroll has been called | ||
| video.addEventListener("play", () => { | ||
| t.step(() => { | ||
| assert_true(scrolledIntoView, "Video should fire play event after scrolling into view"); | ||
| }); | ||
| t.done(); | ||
| }); | ||
|
|
||
| // scroll into view and set scrolledIntoView to true | ||
| step_timeout(() => { | ||
| scrolledIntoView = true; | ||
| video.scrollIntoView(); | ||
| }, 1000); | ||
| }, 2000); | ||
|
|
||
|
|
||
| </script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <!DOCTYPE html> | ||
| <link rel="author" title="Squarespace" href="https://www.squarespace.com/"> | ||
| <script src="/resources/testharness.js"></script> | ||
| <script src="/resources/testharnessreport.js"></script> | ||
|
|
||
| <video id="target" src="/media/A4.mp4?pipe=trickle(d2)" loading="lazy"></video> | ||
|
|
||
| <script> | ||
| const video = document.getElementById("target"); | ||
|
|
||
| let windowLoadFired = false; | ||
|
|
||
| async_test(t => { | ||
| window.addEventListener("load", t.step_func(() => { | ||
| windowLoadFired = true; | ||
| })); | ||
|
|
||
| video.addEventListener("loadstart", t.step_func(() => { | ||
| assert_true(windowLoadFired, "Window load event should fire before loadstart for lazy video in viewport"); | ||
| t.done(); | ||
| })); | ||
|
|
||
| }, "In-viewport video with loading='lazy' fires window load before loadstart"); | ||
| </script> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| <!DOCTYPE html> | ||
| <link rel="author" title="Squarespace" href="https://www.squarespace.com/"> | ||
| <script src="/resources/testharness.js"></script> | ||
| <script src="/resources/testharnessreport.js"></script> | ||
|
|
||
| <style> | ||
| #target { | ||
| position: absolute; | ||
| top: 1000vh; | ||
| } | ||
| </style> | ||
|
|
||
| <video id="target" controls src="/media/A4.mp4" loading="lazy"></video> | ||
|
|
||
| <script> | ||
| const video = document.getElementById("target"); | ||
|
|
||
| const t = async_test( | ||
| "Video with loading=lazy does not fetch video while not visible, then fetches video once scrolled into view" | ||
| ); | ||
|
|
||
| // Step 1: Not visible => check initial dimensions. | ||
| t.step_timeout(() => { | ||
| t.step(() => { | ||
| const initialWidth = video.offsetWidth; | ||
| const initialHeight = video.offsetHeight; | ||
|
|
||
| // Step 2: Scroll into view => video should load and dimensions should change. | ||
| video.scrollIntoView(); | ||
|
|
||
| t.step_timeout(() => { | ||
| t.step(() => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove |
||
| const finalWidth = video.offsetWidth; | ||
| const finalHeight = video.offsetHeight; | ||
| assert_not_equals( | ||
| finalWidth, | ||
| initialWidth, | ||
| "Video width should change after video loads" | ||
| ); | ||
| assert_not_equals( | ||
| finalHeight, | ||
| initialHeight, | ||
| "Video height should change after video loads" | ||
| ); | ||
| }); | ||
| t.done(); | ||
| }, 2000); | ||
| }); | ||
| }, 2000); | ||
| </script> | ||
| </body> | ||
| </html> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| <!DOCTYPE html> | ||
| <link rel="author" title="Squarespace" href="https://www.squarespace.com/"> | ||
| <script src="/resources/testharness.js"></script> | ||
| <script src="/resources/testharnessreport.js"></script> | ||
|
|
||
| <style> | ||
| #target { | ||
| position: absolute; | ||
| top: 1000vh; | ||
| } | ||
| </style> | ||
|
|
||
| <video id="target" poster="/media/2048x1360-random.jpg" loading="lazy"></video> | ||
|
|
||
| <script> | ||
| const video = document.getElementById("target"); | ||
|
|
||
| const t = async_test( | ||
| "Video with loading=lazy does not fetch poster while not visible, then fetches poster once scrolled into view" | ||
| ); | ||
|
|
||
| // Step 1: Not visible => check initial dimensions. | ||
| t.step_timeout(() => { | ||
| t.step(() => { | ||
| const initialWidth = video.offsetWidth; | ||
| const initialHeight = video.offsetHeight; | ||
|
|
||
| // Step 2: Scroll into view => poster should load and dimensions should change. | ||
| video.scrollIntoView(); | ||
|
|
||
| t.step_timeout(() => { | ||
| t.step(() => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove |
||
| const finalWidth = video.offsetWidth; | ||
| const finalHeight = video.offsetHeight; | ||
| assert_not_equals( | ||
| finalWidth, | ||
| initialWidth, | ||
| "Video width should change after poster loads" | ||
| ); | ||
| assert_not_equals( | ||
| finalHeight, | ||
| initialHeight, | ||
| "Video height should change after poster loads" | ||
| ); | ||
| }); | ||
| t.done(); | ||
| }, 2000); | ||
| }); | ||
| }, 2000); | ||
| </script> | ||
| </body> | ||
| </html> | ||
Uh oh!
There was an error while loading. Please reload this page.