mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1863277 - Make Web Locks tests deal with promise argument conversion as defined in the WebIDL spec. r=saschanaz
Some Web Locks wpt tests release locks from a cleanup task, but they don't wait until the lock is actually released. The tests currently pass, because in most browser engine implementations the promise that's returned from the callback for these locks is incorrectly converted by just keeping the original promise. The WebIDL spec actually requires the conversion to create a new promise around the returned promise, which means the release will require another microtask. If we fix implementations to follow the WebIDL spec then we'll start the next test before the locks from the previous test are released, causing havoc. Differential Revision: https://phabricator.services.mozilla.com/D192819
This commit is contained in:
parent
f34ff74915
commit
312850d94e
@ -41,18 +41,17 @@ async function third_party_test(t) {
|
||||
HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname);
|
||||
|
||||
// Step 1.
|
||||
navigator.locks.request('testLock', {mode: 'exclusive', ifAvailable: true},
|
||||
let lock_id = next_lock_id++;
|
||||
let [ promise, release ] = makePromiseAndResolveFunc();
|
||||
let released = navigator.locks.request('testLock', {mode: 'exclusive', ifAvailable: true},
|
||||
lock => {
|
||||
if (lock === null) {
|
||||
assert_true(false)
|
||||
return;
|
||||
}
|
||||
let lock_id = next_lock_id++;
|
||||
let release;
|
||||
const promise = new Promise(r => { release = r; });
|
||||
held.set(lock_id, release);
|
||||
return promise;
|
||||
});
|
||||
held.set(lock_id, { release, released });
|
||||
|
||||
// Step 2.
|
||||
const w = window.open(target_url);
|
||||
@ -60,10 +59,14 @@ async function third_party_test(t) {
|
||||
|
||||
// Step 7.
|
||||
t.add_cleanup(() => {
|
||||
w.close()
|
||||
w.close();
|
||||
let released = [];
|
||||
for(let i = 1; i < next_lock_id; i++){
|
||||
held.get(i)();
|
||||
let h = held.get(i);
|
||||
h.release();
|
||||
released.push(h.released);
|
||||
}
|
||||
return Promise.allSettled(released);
|
||||
});
|
||||
|
||||
// Step 8.
|
||||
@ -124,19 +127,17 @@ async function nested_iframe_test(t) {
|
||||
|
||||
// Nested Step 1.
|
||||
// Request the weblock for the top-level site.
|
||||
navigator.locks.request('testLock', {mode: 'exclusive', ifAvailable: true},
|
||||
let lock_id = next_lock_id_2++;
|
||||
let [ promise, release ] = makePromiseAndResolveFunc();
|
||||
let released = navigator.locks.request('testLock', {mode: 'exclusive', ifAvailable: true},
|
||||
lock => {
|
||||
if (lock === null) {
|
||||
assert_true(false)
|
||||
return;
|
||||
}
|
||||
// Obtain and store the release functions for clean-up.
|
||||
let lock_id = next_lock_id_2++;
|
||||
let release;
|
||||
const promise = new Promise(r => { release = r; });
|
||||
held_2.set(lock_id, release);
|
||||
return promise;
|
||||
}).catch(error => alert(error.message));
|
||||
held_2.set(lock_id, { release, released });
|
||||
|
||||
// Nested Step 2.
|
||||
// Open the nested iframes. The script in the innermost child iframe
|
||||
@ -146,10 +147,14 @@ async function nested_iframe_test(t) {
|
||||
|
||||
// Nested Step 10.
|
||||
t.add_cleanup(() => {
|
||||
w.close()
|
||||
for(let i = 1; i < next_lock_id_2; i++){
|
||||
held_2.get(i)();
|
||||
w.close();
|
||||
let released = [];
|
||||
for(let i = 1; i < next_lock_id; i++){
|
||||
let h = held_2.get(i);
|
||||
h.release();
|
||||
released.push(h.released);
|
||||
}
|
||||
return Promise.allSettled(released);
|
||||
});
|
||||
|
||||
// Nested Step 11.
|
||||
|
@ -69,9 +69,17 @@
|
||||
* @returns
|
||||
*/
|
||||
self.requestLockAndHold = (t, name, options = {}) => {
|
||||
return navigator.locks.request(name, options, () => {
|
||||
return new Promise(resolve => t.add_cleanup(resolve));
|
||||
let [promise, resolve] = self.makePromiseAndResolveFunc();
|
||||
const released = navigator.locks.request(name, options, () => promise);
|
||||
// Add a cleanup function that releases the lock by resolving the promise,
|
||||
// and then waits until the lock is really released, to avoid contaminating
|
||||
// following tests with temporarily held locks.
|
||||
t.add_cleanup(() => {
|
||||
resolve();
|
||||
// Cleanup shouldn't fail if the request is aborted.
|
||||
return released.catch(() => undefined);
|
||||
});
|
||||
return released;
|
||||
};
|
||||
|
||||
self.makePromiseAndResolveFunc = () => {
|
||||
|
Loading…
Reference in New Issue
Block a user