fix(inspect): reset a released preview video in the next task
On WebKit (GStreamer) a video replaced while its pipeline was still starting blocked the page: pause, src removal and load() in one task never returned, so the next chooser selection hung (CI page workflows webkit shard 2/2, "URLs and media end with their owning session"). The src is still dropped before the URL is revoked; only the load() reset moves to the next task. A fresh-page regression replaces the first video as soon as it shows, fifteen times.
This commit is contained in:
+4
-2
@@ -1296,8 +1296,10 @@ mapped differences"):
|
|||||||
`image/png,image/jpeg,image/webp` plus `video/*,.mp4,.mov,.m4v,.webm,.mkv,.avi,.wmv`. A
|
`image/png,image/jpeg,image/webp` plus `video/*,.mp4,.mov,.m4v,.webm,.mkv,.avi,.wmv`. A
|
||||||
video previews in the same `#local-preview` slot as `video.local-file-preview` with
|
video previews in the same `#local-preview` slot as `video.local-file-preview` with
|
||||||
native `controls`, `playsInline`, `preload="metadata"` and `muted`, never autoplays
|
native `controls`, `playsInline`, `preload="metadata"` and `muted`, never autoplays
|
||||||
inline, and is paused, unloaded (`removeAttribute('src')`, `load()`) and removed on
|
inline, and is paused, has its `src` removed and is removed from the page on replacement
|
||||||
replacement or dispose.
|
or dispose, before its URL is revoked; its `load()` reset runs in the next task, because
|
||||||
|
WebKit (GStreamer) blocked the page when a still-starting video was reset in the same
|
||||||
|
task (`replacing a video that just started loading never blocks the page`).
|
||||||
- **D63** (status line): one `p.small.spaced-16` in `#local-preview`, for states the
|
- **D63** (status line): one `p.small.spaced-16` in `#local-preview`, for states the
|
||||||
concept never shows: "Drop one file at a time.", "Folders cannot be inspected. Choose
|
concept never shows: "Drop one file at a time.", "Folders cannot be inspected. Choose
|
||||||
one image or video file.", "This file type cannot be previewed or inspected here.
|
one image or video file.", "This file type cannot be previewed or inspected here.
|
||||||
|
|||||||
@@ -391,6 +391,28 @@ test('URLs and media end with their owning session', async ({ page }) => {
|
|||||||
expect(state.revoked.filter(url => url === state.created[7])).toHaveLength(1);
|
expect(state.revoked.filter(url => url === state.created[7])).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('replacing a video that just started loading never blocks the page', async ({ context, browserName }) => {
|
||||||
|
test.setTimeout(120000);
|
||||||
|
// WebKit (GStreamer) blocked the page when a video's pipeline was reset with load() in the same task that
|
||||||
|
// removed its src, while it was still starting: the next chooser selection never completed. Each fresh page
|
||||||
|
// replaces its first video as soon as it shows.
|
||||||
|
for (let attempt = 0; attempt < 15; attempt++) {
|
||||||
|
const page = await context.newPage();
|
||||||
|
try {
|
||||||
|
if (attempt === 0) await startCoverage(page, browserName);
|
||||||
|
await openInspect(page);
|
||||||
|
await choose(page, localFixture('core-tags.webm', 'video/webm'));
|
||||||
|
await expect(preview(page).locator('video.local-file-preview')).toBeVisible();
|
||||||
|
await chooser(page).setInputFiles(parityPng('f02.png'), { timeout: 8000 });
|
||||||
|
await expect(preview(page).locator('img.local-file-preview')).toBeVisible();
|
||||||
|
await expect(preview(page).locator('video')).toHaveCount(0);
|
||||||
|
if (attempt === 0) await saveCoverage(page, browserName);
|
||||||
|
} finally {
|
||||||
|
await page.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('replacing a file mid-read never shows or sends the old record', async ({ page, context }) => {
|
test('replacing a file mid-read never shows or sends the old record', async ({ page, context }) => {
|
||||||
const host = await bridgeHost(context);
|
const host = await bridgeHost(context);
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -37,10 +37,14 @@ function element(tag, className, text) {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Stops a preview from holding its blob: URL: media is paused and unloaded before the session revokes the URL. */
|
/**
|
||||||
|
* Stops a preview from holding its blob: URL: media is paused and its src dropped before the session revokes the URL.
|
||||||
|
* The media resets with load() in the next task: WebKit (GStreamer) blocked the page when a starting video was reset in
|
||||||
|
* the same task that removed its src.
|
||||||
|
*/
|
||||||
function releaseMedia(node) {
|
function releaseMedia(node) {
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
if (node instanceof HTMLMediaElement) { node.pause(); node.removeAttribute('src'); node.load(); }
|
if (node instanceof HTMLMediaElement) { node.pause(); node.removeAttribute('src'); setTimeout(() => node.load(), 0); }
|
||||||
else node.removeAttribute('src');
|
else node.removeAttribute('src');
|
||||||
node.remove();
|
node.remove();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user