Skip to content

Commit

Permalink
Resync web-platform-tests/mediacapture-streams from upstream
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=274091
rdar://128005548

Reviewed by Youenn Fablet.

Upstream commit: web-platform-tests/wpt@b5d5522

* LayoutTests/TestExpectations:
* LayoutTests/imported/w3c/resources/resource-files.json:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/BrowserCaptureMediaStreamTrack-cropTo.https-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/BrowserCaptureMediaStreamTrack-cropTo.https.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/BrowserCaptureMediaStreamTrack-restrictTo.https-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/BrowserCaptureMediaStreamTrack-restrictTo.https.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/GUM-non-applicable-constraint.https.html:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaDevices-enumerateDevices-returned-objects.https-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaDevices-enumerateDevices-returned-objects.https.html:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaDevices-enumerateDevices.https-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaDevices-enumerateDevices.https.html:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaDevices-getSupportedConstraints.https-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaDevices-getSupportedConstraints.https.html:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaDevices-getUserMedia.https-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaDevices-getUserMedia.https.html:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https.html: Removed.
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-getCapabilities.https-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-getCapabilities.https.html:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-getSettings.https-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-getSettings.https.html:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/historical-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/historical.https-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/historical.https.html:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/idlharness.https.window.js:
* LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/w3c-import.log:
* LayoutTests/platform/ios/TestExpectations:

Canonical link: https://commits.webkit.org/278723@main
  • Loading branch information
szewai committed May 14, 2024
1 parent 900e2fc commit 2dad7c4
Show file tree
Hide file tree
Showing 29 changed files with 497 additions and 246 deletions.
3 changes: 3 additions & 0 deletions LayoutTests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -6460,6 +6460,9 @@ webkit.org/b/256976 [ Debug ] imported/w3c/web-platform-tests/html/browsers/brow
# Test has been timing out since its import.
imported/w3c/web-platform-tests/dom/events/scrolling/scrollend-event-handler-content-attributes.html [ Skip ]

# New faliure after re-importing mediacapture-streams.
webkit.org/b/274091 imported/w3c/web-platform-tests/mediacapture-streams/idlharness.https.window.html

# Recent WPT update
webkit.org/b/255101 imported/w3c/web-platform-tests/css/css-backgrounds/background-attachment-fixed-inside-transform-1.html [ ImageOnlyFailure ]
webkit.org/b/255101 imported/w3c/web-platform-tests/css/css-backgrounds/background-attachment-local-hidden.html [ ImageOnlyFailure ]
Expand Down
1 change: 0 additions & 1 deletion LayoutTests/imported/w3c/resources/resource-files.json
Original file line number Diff line number Diff line change
Expand Up @@ -7939,7 +7939,6 @@
"web-platform-tests/mathml/relations/text-and-math/use-typo-metrics-1-ref.html",
"web-platform-tests/mathml/tools/operator-dictionary.xsl",
"web-platform-tests/mediacapture-record/support/MediaRecorder-iframe.html",
"web-platform-tests/mediacapture-streams/crashtests/enumerateDevices-after-discard-1.https.html",
"web-platform-tests/mediacapture-streams/iframe-enumerate-cleared.html",
"web-platform-tests/mediacapture-streams/iframe-enumerate-nogum.html",
"web-platform-tests/mediacapture-streams/iframe-enumerate.html",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
When prompted, accept to give permission to use your audio, video devices.

Description
This test checks that BrowserCaptureMediaStreamTrack cropping works as expected.

Start test

FAIL Tests that cropping MediaStreamTrack objects works as expected promise_test: Unhandled rejection with value: object "InvalidStateError: getDisplayMedia must be called from a user gesture handler."

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!doctype html>
<html>

<head>
<title>BrowserCaptureMediaStreamTrack cropTo()</title>
<link rel="help" href="https://github.com/w3c/mediacapture-region/">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>

<body>
<p class="instructions">
When prompted, accept to give permission to use your audio, video devices.
</p>
<h1 class="instructions">Description</h1>
<p class="instructions">
This test checks that BrowserCaptureMediaStreamTrack cropping works as
expected.
</p>

<button id="button">Start test</button>
<div id='test-div' width="500px" height="600px"></div>

<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=permission-helper.js></script>

<script>
"use strict";

async function getDisplayMedia() {
const p = new Promise(r => button.onclick = r);
await test_driver.click(button);
await p;
return navigator.mediaDevices.getDisplayMedia(
{video:{displaySurface:"browser"}, selfBrowserSurface:"include"});
}

promise_test(async t => {
const stream = await getDisplayMedia();
assert_true(stream.active, "stream should be active.");

assert_equals(stream.getVideoTracks().length, 1);
const [videoTrack] = stream.getVideoTracks();
assert_true(videoTrack instanceof MediaStreamTrack,
"track should be either MediaStreamTrack or a subclass thereof.");
assert_equals(videoTrack.readyState, "live");

const div = document.getElementById('test-div');
const cropTarget = await CropTarget.fromElement(div);
assert_true(!!videoTrack.cropTo, "cropTo exposed.");
assert_true(typeof videoTrack.cropTo === 'function',
"cropTo is a function.");
await videoTrack.cropTo(cropTarget);

assert_true(stream.active, "stream should be active.");
assert_false(videoTrack.muted, "track should not be muted.");
}, "Tests that cropping MediaStreamTrack objects works as expected");

</script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
When prompted, accept to give permission to use your audio, video devices.

Description
This test checks that restricting BrowserCaptureMediaStreamTrack works as expected.



FAIL Tests that restricting MediaStreamTrack objects works as expected (StackingContext). promise_test: Unhandled rejection with value: object "InvalidStateError: getDisplayMedia must be called from a user gesture handler."
FAIL Tests that restricting MediaStreamTrack objects works as expected (OnlyOneBoxFragment). promise_test: Unhandled rejection with value: object "InvalidStateError: getDisplayMedia must be called from a user gesture handler."
FAIL Tests that restricting MediaStreamTrack objects works as expected (FlattenedIn3D). promise_test: Unhandled rejection with value: object "InvalidStateError: getDisplayMedia must be called from a user gesture handler."

Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
<!doctype html>
<html>

<head>
<title>BrowserCaptureMediaStreamTrack restrictTo()</title>
<link rel="help" href="https://screen-share.github.io/element-capture/">
</head>

<body>
<p class="instructions">
When prompted, accept to give permission to use your audio, video devices.
</p>
<h1 class="instructions">Description</h1>
<p class="instructions">
This test checks that restricting BrowserCaptureMediaStreamTrack works as
expected.
</p>

<style>
div {
height: 100px;
}
.stacking {
opacity: 0.9;
}
#container {
columns:4;
column-fill:auto;
}
.fragmentize {
height: 50px;
}
#target {
background: linear-gradient(red, blue);
}
</style>


<div id='container'>
<div id='target'></div>
</div>
<video id="video"
style="border: 2px blue dotted; width: 250px; height: 250px;"
autoplay playsinline muted></video>

<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>

<script>
"use strict";

// For more information, see:
// https://screen-share.github.io/element-capture/#elements-eligible-for-restriction
const EligibilityRequirement = {
StackingContext: "StackingContext",
OnlyOneBoxFragment: "OnlyOneBoxFragment",
FlattenedIn3D: "FlattenedIn3D",
};

// The target div.
const div = document.getElementById('target');

// Returns a promise that, if successful, will resolve to a media stream.
async function getDisplayMedia() {
return test_driver.bless('getDisplayMedia', () =>
navigator.mediaDevices.getDisplayMedia({
video: { displaySurface: "browser" },
selfBrowserSurface: "include",
}));
}

// Returns a promise that will resolve successfully if at least one frame is
// read before the timeout.
function assertFrameRead(t, state, message) {
const last_frame_count = state.frame_count;
return t.step_wait(() => state.frame_count > last_frame_count,
message, 5000, 10);
}

// Returns a promise that will resolve successfully if there are no frames
// produced for an entire second after being called.
function assertStopsProducingFrames(t, state, message) {
let last_frame_count = state.frame_count;

return t.step_timeout(() => {
assert_equals(state.frame_count, last_frame_count);
}, 1000);
}

function makeDivEligible() {
// Must always have a stacking context to be eligible.
div.classList.add("stacking");
div.parentElement.classList.remove("fragmented");
div.style.transform = "";
}

function makeDivIneligible(state) {
switch(state.eligibilityParam) {
case EligibilityRequirement.StackingContext:
div.classList.remove("stacking");
break;

case EligibilityRequirement.OnlyOneBoxFragment:
div.parentElement.classList.add("fragmented");
break;

case EligibilityRequirement.FlattenedIn3D:
div.style.transform = "rotateY(90deg)";
break;
}
}

// Restore element state after each test.
function cleanupDiv() {
div.classList.remove("stacking");
div.parentElement.classList.remove("fragmented");
div.style.transform = "";
}

function startAnimation(t, state) {
let count = 0;
function animate() {
if (!state.running) {
return;
}
count += 1;
div.innerText = count;
window.requestAnimationFrame(animate);
}
window.requestAnimationFrame(animate);

// Stop animation as part of cleanup.
t.add_cleanup(() => { state.running = false; });
}

// Updates the state.frame_count value whenever a new frame is received on
// the passed in media stream track.
async function readFromTrack(state, track) {
while (state.running) {
const reader = new MediaStreamTrackProcessor(track).readable.getReader();
while (true) {
const frameOrDone = await reader.read();
if (frameOrDone.done) {
break;
}
frameOrDone.value.close();
state.frame_count += 1;
}
}
}

// Parameterized test method. Note that this returns a Promise that will be
// resolved to represent success of the entire promise test.
async function runTest(t, eligibilityParam) {
let state = {
eligibilityParam: eligibilityParam,
frame_count: 0,
running: true,
reading: false,
};
startAnimation(t, state);

let videoTrack = undefined;
return getDisplayMedia().then(stream => {
t.add_cleanup(() => {
stream.getTracks().forEach(track => track.stop());
});
assert_true(!!stream, "should have resolved to a stream.");
assert_true(stream.active, "stream should be active.");
assert_equals(stream.getVideoTracks().length, 1);

[videoTrack] = stream.getVideoTracks();
assert_true(videoTrack instanceof MediaStreamTrack,
"track should be either MediaStreamTrack or a subclass thereof.");
assert_equals(videoTrack.readyState, "live", "track should be live.");

// Consume the stream in a video element.
const video = document.querySelector('video');
video.srcObject = stream;

// Remove the video source, so that the stream object can be released.
t.add_cleanup(() => {video.srcObject = null});

// Keep track of the number of frames used.
const readPromise = readFromTrack(state, videoTrack);
t.add_cleanup(() => readPromise);

return assertFrameRead(t, state, "Track should produce frames.");
}).then(() => {
assert_true(!!RestrictionTarget, "RestrictionTarget exposed.");
assert_true(!!RestrictionTarget.fromElement,
"RestrictionTarget.fromElement exposed.");

return RestrictionTarget.fromElement(div);
}).then(restrictionTarget => {
assert_true(!!videoTrack.restrictTo, "restrictTo exposed.");
assert_true(typeof videoTrack.restrictTo === 'function',
"restrictTo is a function.");

return videoTrack.restrictTo(restrictionTarget);
}).then(() => {
// By default, elements are not eligible for restriction due to not being
// placed in their own stacking context.
return assertStopsProducingFrames(t, state,
"No new frames after restriction.");
});

// TODO(crbug.com/333770107): once the issue with the
// --disable-threaded-compositing flag is resolved on Chrome's check in bots
// the rest of this test should be enabled.
// ).then(() => {
// // Should be unpaused now that the element is eligible.
// makeDivEligible();

// // Make sure the element state is restored to default between tests.
// t.add_cleanup(() => { cleanupDiv(); });

// // Restart the reader now that the stream is producing frames again.
// return assertFrameRead(t, state,
// "Received at least one frame after becoming eligible.");
// }).then(() => {

// // Should pause if it becomes ineligible again.
// makeDivIneligible(state);
// return assertStopsProducingFrames(t, state,
// "No new frames after becoming ineligible again.");
// });
}

// Test parameterizations.
[
EligibilityRequirement.StackingContext,
EligibilityRequirement.OnlyOneBoxFragment,
EligibilityRequirement.FlattenedIn3D,
].forEach(param =>
promise_test(t => runTest(t, param),
`Tests that restricting MediaStreamTrack objects works as expected (${param}).`
));

</script>
</body>

</html>
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
echoCancellation: {ideal: true},
autoGainControl: {ideal: true},
noiseSuppression: {ideal: true},
voiceIsolation: {ideal: true},
latency: {min: 0},
channelCount: {min: 0}
}
Expand All @@ -48,6 +49,7 @@
echoCancellation: {exact: true},
autoGainControl: {exact: true},
noiseSuppression: {exact: true},
voiceIsolation: {exact: true},
latency: {max: 0},
channelCount: {max: 0}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

PASS enumerateDevices returns expected mostly empty objects in case device-info permission is not granted
PASS enumerateDevices returns expected objects in case device-info permission is granted
PASS enumerateDevices exposes mostly empty objects ahead of successful getUserMedia call
PASS enumerateDevices exposes expected objects after successful getUserMedia call

Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
assert_equals(device1.deviceId, "", "deviceId is empty before capture");
assert_equals(device1.groupId, "", "groupId is empty before capture");
assert_equals(device1.label, "", "label is empty before capture");
assert_in_array(device1.kind, ["audioinput", "audiooutput", "videoinput", "kind is set to a valid value before capture"]);
assert_in_array(device1.kind, ["audioinput", "audiooutput", "videoinput"],
"kind is set to a valid value before capture");
}
}
/* Additionally, at most one device of each kind
Expand All @@ -52,8 +53,8 @@
}, testName);
}

doTest(false, "enumerateDevices returns expected mostly empty objects in case device-info permission is not granted");
doTest(true, "enumerateDevices returns expected objects in case device-info permission is granted");
doTest(false, "enumerateDevices exposes mostly empty objects ahead of successful getUserMedia call");
doTest(true, "enumerateDevices exposes expected objects after successful getUserMedia call");
</script>
</body>
</html>
Loading

0 comments on commit 2dad7c4

Please sign in to comment.