Skip to content

Commit 63f7732

Browse files
shakyShanegithub-actions[bot]
authored andcommitted
Release build 4.22.3 [ci release]
1 parent 1b55488 commit 63f7732

File tree

29 files changed

+3133
-800
lines changed

29 files changed

+3133
-800
lines changed

Sources/ContentScopeScripts/dist/contentScopeIsolated.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3654,7 +3654,15 @@
36543654
*/
36553655
bindEvents: (video) => {
36563656
if (video) {
3657+
const before = video.href;
36573658
addTrustedEventListener(video, 'mouseover', () => {
3659+
// don't allow the hover overlay to be shown if the video has changed
3660+
// this can occur with 'shorts'
3661+
if (video.href !== before) {
3662+
if (!VideoThumbnail.isSingleVideoURL(video.href)) {
3663+
return console.log('bailing because the video has changed')
3664+
}
3665+
}
36583666
IconOverlay.moveHoverOverlayToVideoElement(video);
36593667
});
36603668

@@ -4031,7 +4039,7 @@
40314039
* For example, to enable the Duck Player Overlay on YouTube, the following config is used:
40324040
*
40334041
* ```json
4034-
* [[include:integration-test/test-pages/duckplayer/config/overlays.json]]```
4042+
* [[include:integration-test/test-pages/duckplayer/config/overlays-live.json]]```
40354043
*
40364044
*/
40374045

build/android/contentScope.js

Lines changed: 360 additions & 68 deletions
Large diffs are not rendered by default.

build/chrome-mv3/inject.js

Lines changed: 360 additions & 68 deletions
Large diffs are not rendered by default.

build/chrome/inject.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/contentScope.js

Lines changed: 369 additions & 69 deletions
Large diffs are not rendered by default.

build/firefox/inject.js

Lines changed: 360 additions & 68 deletions
Large diffs are not rendered by default.

build/integration/contentScope.js

Lines changed: 369 additions & 69 deletions
Large diffs are not rendered by default.

build/windows/contentScope.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8827,7 +8827,15 @@
88278827
*/
88288828
bindEvents: (video) => {
88298829
if (video) {
8830+
const before = video.href;
88308831
addTrustedEventListener(video, 'mouseover', () => {
8832+
// don't allow the hover overlay to be shown if the video has changed
8833+
// this can occur with 'shorts'
8834+
if (video.href !== before) {
8835+
if (!VideoThumbnail.isSingleVideoURL(video.href)) {
8836+
return console.log('bailing because the video has changed')
8837+
}
8838+
}
88318839
IconOverlay.moveHoverOverlayToVideoElement(video);
88328840
});
88338841

@@ -9204,7 +9212,7 @@
92049212
* For example, to enable the Duck Player Overlay on YouTube, the following config is used:
92059213
*
92069214
* ```json
9207-
* [[include:integration-test/test-pages/duckplayer/config/overlays.json]]```
9215+
* [[include:integration-test/test-pages/duckplayer/config/overlays-live.json]]```
92089216
*
92099217
*/
92109218

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { test } from '@playwright/test'
2+
import { DuckplayerOverlays } from './page-objects/duckplayer-overlays.js'
3+
4+
test.describe('e2e: Duck Player Thumbnail Overlays on YouTube.com', () => {
5+
test('e2e: Overlays never appear on "shorts"', async ({ page }, workerInfo) => {
6+
// @ts-expect-error - TS doesn't know about the "use.e2e" property
7+
workerInfo.skip(!workerInfo.project.use?.e2e)
8+
9+
const overlays = DuckplayerOverlays.create(page, workerInfo)
10+
11+
await overlays.overlaysEnabled({ json: 'overlays-live' })
12+
await overlays.gotoYoutubeHomepage()
13+
14+
// Ensure the hover works normally to prevent false positives
15+
await overlays.hoverAYouTubeThumbnail()
16+
await overlays.isVisible()
17+
18+
// now ensure the hover doesn't work on shorts
19+
await overlays.hoverShort()
20+
await overlays.overlaysDontShow()
21+
})
22+
})

integration-test/playwright/duckplayer.spec.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ test.describe('Duck Player Thumbnail Overlays on YouTube.com', () => {
1515
// Then our overlay shows
1616
await overlays.isVisible()
1717
})
18+
test('Overlays never appear on "shorts"', async ({ page }, workerInfo) => {
19+
const overlays = DuckplayerOverlays.create(page, workerInfo)
20+
await overlays.overlaysEnabled()
21+
await overlays.gotoThumbsPage()
22+
23+
// Ensure the hover works normally to prevent false positives
24+
await overlays.hoverAThumbnail()
25+
await overlays.isVisible()
26+
27+
// now ensure the hover doesn't work on shorts
28+
await overlays.hoverShort()
29+
await overlays.overlaysDontShow()
30+
})
1831
test('Overlays don\'t show on thumbnails when disabled', async ({ page }, workerInfo) => {
1932
const overlays = DuckplayerOverlays.create(page, workerInfo)
2033

integration-test/playwright/page-objects/duckplayer-overlays.js

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ export class DuckplayerOverlays {
5454
await this.page.goto(this.overlaysPage)
5555
}
5656

57+
async gotoYoutubeHomepage () {
58+
await this.page.goto('https://www.youtube.com')
59+
// cookie banner
60+
await this.page.getByRole('button', { name: 'Reject the use of cookies and other data for the purposes described' }).click()
61+
}
62+
5763
/**
5864
* @param {object} [params]
5965
* @param {"default" | "incremental-dom"} [params.variant]
@@ -100,9 +106,14 @@ export class DuckplayerOverlays {
100106
await this.page.getByRole('link', { name: 'Duck Player', exact: true }).waitFor({ state: 'attached' })
101107
}
102108

103-
// Given the "overlays" feature is enabled
104-
async overlaysEnabled () {
105-
await this.setup({ config: loadConfig('overlays') })
109+
/**
110+
* @param {object} [params]
111+
* @param {'overlays' | 'overlays-live'} [params.json="overlays"] - default is settings for localhost
112+
*/
113+
async overlaysEnabled (params = {}) {
114+
const { json = 'overlays' } = params
115+
116+
await this.setup({ config: loadConfig(json) })
106117
}
107118

108119
async serpProxyEnabled () {
@@ -156,6 +167,16 @@ export class DuckplayerOverlays {
156167
await this.page.locator('.thumbnail[href="/watch?v=1"]').first().hover()
157168
}
158169

170+
async hoverAYouTubeThumbnail () {
171+
await this.page.locator('a.ytd-thumbnail[href^="/watch"]').first().hover({ force: true })
172+
}
173+
174+
async hoverShort () {
175+
// this should auto-wait for our test code to modify the DOM like YouTube does
176+
await this.page.getByRole('heading', { name: 'Shorts', exact: true }).scrollIntoViewIfNeeded()
177+
await this.page.locator('a[href*="/shorts"]').first().hover({ force: true })
178+
}
179+
159180
async clickDDGOverlay () {
160181
await this.hoverAThumbnail()
161182
await this.page.locator('.ddg-play-privately').click({ force: true })
@@ -166,7 +187,21 @@ export class DuckplayerOverlays {
166187
}
167188

168189
async overlaysDontShow () {
169-
expect(await this.page.locator('.ddg-overlay.ddg-overlay-hover').count()).toEqual(0)
190+
const elements = await this.page.locator('.ddg-overlay.ddg-overlay-hover').count()
191+
192+
// if the element exists, assert that it is hidden
193+
if (elements > 0) {
194+
const style = await this.page.evaluate(() => {
195+
const div = /** @type {HTMLDivElement|null} */(document.querySelector('.ddg-overlay.ddg-overlay-hover'))
196+
if (div) {
197+
return div.style.display
198+
}
199+
return ''
200+
})
201+
expect(style).toEqual('none')
202+
}
203+
204+
// if we get here, the element was absent
170205
}
171206

172207
async watchInDuckPlayer () {
@@ -316,7 +351,7 @@ export class DuckplayerOverlays {
316351
}
317352

318353
/**
319-
* @param {"overlays"} name
354+
* @param {"overlays" | "overlays-live"} name
320355
* @return {Record<string, any>}
321356
*/
322357
function loadConfig (name) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"unprotectedTemporary": [],
3+
"features": {
4+
"duckPlayer": {
5+
"state": "enabled",
6+
"exceptions": [],
7+
"settings": {
8+
"overlays": {
9+
"youtube": {
10+
"state": "disabled"
11+
},
12+
"serpProxy": {
13+
"state": "disabled"
14+
}
15+
},
16+
"domains": [
17+
{
18+
"domain": "youtube.com",
19+
"patchSettings": [
20+
{
21+
"op": "replace",
22+
"path": "/overlays/youtube/state",
23+
"value": "enabled"
24+
}
25+
]
26+
},
27+
{
28+
"domain": "duckduckgo.com",
29+
"patchSettings": [
30+
{
31+
"op": "replace",
32+
"path": "/overlays/serpProxy/state",
33+
"value": "enabled"
34+
}
35+
]
36+
}
37+
]
38+
}
39+
}
40+
}
41+
}

integration-test/test-pages/duckplayer/pages/overlays.html

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,34 @@
66
<title>Runtime checks</title>
77
<link rel="stylesheet" href="../../shared/style.css">
88
<style>
9+
.thumbnails {
10+
display: grid;
11+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
12+
}
913
.thumbnail {
10-
height: 100px;
11-
width: 200px;
1214
margin: 5px;
1315
background: lightblue;
1416
border: 1px solid black;
15-
float: left;
17+
aspect-ratio: 16/9;
18+
display: block;
1619
}
1720

18-
.thumbnail img {
21+
.thumbnail img, .short img {
1922
width: 100%;
2023
height: 100%;
24+
object-fit: cover;
25+
display: block;
26+
}
27+
28+
.short {
29+
margin: 5px;
30+
background: lightblue;
31+
border: 1px solid black;
32+
aspect-ratio: 9/16;
33+
display: block;
2134
}
2235

2336
.playlist {
24-
clear: both;
2537
width: 100px;
2638

2739
}
@@ -37,8 +49,6 @@
3749
}
3850

3951
#loaded {
40-
clear: both;
41-
float: none;
4252
width: 300px;
4353
}
4454

@@ -81,7 +91,44 @@ <h2>MORE THUMBNAILS</h2>
8191
</div>
8292
</div>
8393

94+
<h2>Shorts</h2>
95+
<div class="thumbnails">
96+
<a class="ytd-thumbnail short" href="/watch?v=1"><img src="thumbnail-dark.jpg"></a>
97+
<a class="ytd-thumbnail short" href="/watch?v=2"><img src="thumbnail-light.jpg"></a>
98+
<a class="ytd-thumbnail short" href="/watch?v=3"><img src="thumbnail-dark.jpg"></a>
99+
<a class="ytd-thumbnail short" href="/watch?v=4"><img src="thumbnail-light.jpg"></a>
100+
<a class="ytd-thumbnail short" href="/watch?v=5"><img src="thumbnail-dark.jpg"></a>
101+
</div>
102+
84103
<div id="loaded"></div>
85104

105+
<script type="module">
106+
const variant = new URLSearchParams(window.location.search).get('variant') || 'default';
107+
108+
const knownVariants = {
109+
"default": () => {
110+
setTimeout(() => {
111+
/**
112+
* This will change '/watch?v=3' links to '/shorts/3'
113+
* It roughly mimics the behaviour of the YouTube Homepage
114+
*/
115+
const shorts = document.querySelectorAll('.short');
116+
shorts.forEach((short) => {
117+
const params = new URLSearchParams(short.search);
118+
short.pathname = "/shorts/" + params.get('v');
119+
short.search = ''
120+
})
121+
}, 200);
122+
},
123+
}
124+
125+
if (variant in knownVariants) {
126+
console.log('executing page variant', variant)
127+
knownVariants[variant]();
128+
} else {
129+
console.warn('variant not found', variant)
130+
}
131+
132+
</script>
86133
</body>
87134
</html>

0 commit comments

Comments
 (0)