|
1 | 1 | /** |
2 | | - * Sub-stream ↔ main-stream swap on per-cell fullscreen (#366) |
| 2 | + * Sub-stream ↔ main-stream swap on per-cell fullscreen (#366, #578) |
3 | 3 | * |
4 | | - * When a stream is configured with sub_stream_url and rendered in a grid |
5 | | - * (>1 cell), the video cell uses the `{name}_sub` go2rtc source. Entering |
6 | | - * native fullscreen on that specific cell must swap it to the main stream |
7 | | - * so the user sees full-resolution video, not the low-res dashboard feed. |
| 4 | + * When a stream is configured with sub_stream_url and rendered on the |
| 5 | + * dashboard, the video cell uses the `{name}_sub` go2rtc source regardless |
| 6 | + * of the selected grid size. Entering native fullscreen on that specific |
| 7 | + * cell must swap it to the main stream so the user sees full-resolution |
| 8 | + * video, not the low-res dashboard feed. |
8 | 9 | * |
9 | 10 | * We assert this via the `data-sub-stream` attribute on each `.video-cell`, |
10 | 11 | * which mirrors the `useSubStream` prop resolved by LiveView / WebRTCView. |
@@ -119,13 +120,26 @@ test.describe('Sub-stream swap on per-cell fullscreen @ui @liveview', () => { |
119 | 120 | await expect(cellB).toHaveAttribute('data-sub-stream', 'true'); |
120 | 121 | }); |
121 | 122 |
|
122 | | - test('single-stream layout never uses sub-stream', async ({ page }) => { |
| 123 | + test('single-stream layout uses sub-stream until fullscreen', async ({ page }) => { |
123 | 124 | await page.goto('/index.html?cols=1&rows=1&stream=cam_a', { waitUntil: 'domcontentloaded' }); |
124 | 125 |
|
125 | 126 | const cellA = page.locator('.video-cell[data-stream-name="cam_a"]').first(); |
126 | 127 | await expect(cellA).toBeVisible({ timeout: 15000 }); |
127 | 128 |
|
128 | | - // 1×1 layout always shows the main stream (full-screen/recording quality). |
| 129 | + // Grid dimensions do not select stream quality: a 1×1 dashboard tile |
| 130 | + // still uses the configured low-resolution source. |
| 131 | + await expect(cellA).toHaveAttribute('data-sub-stream', 'true'); |
| 132 | + |
| 133 | + await page.evaluate(() => { |
| 134 | + const target = document.querySelector('.video-cell[data-stream-name="cam_a"]'); |
| 135 | + Object.defineProperty(document, 'fullscreenElement', { |
| 136 | + configurable: true, |
| 137 | + get: () => target, |
| 138 | + }); |
| 139 | + document.dispatchEvent(new Event('fullscreenchange')); |
| 140 | + }); |
| 141 | + |
| 142 | + // Only actual fullscreen upgrades the tile to the main stream. |
129 | 143 | await expect(cellA).toHaveAttribute('data-sub-stream', 'false'); |
130 | 144 | }); |
131 | 145 | }); |
0 commit comments