Skip to content

Commit f010454

Browse files
mgurgelgithub-actions[bot]
authored andcommitted
Release build 8.9.0 [ci release]
1 parent 313a212 commit f010454

File tree

45 files changed

+3133
-159
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3133
-159
lines changed

CHANGELOG.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
- Try catch notify messaging (#1592)
2-
- Revert "Revert "Add support for non isolated messaging (#1586)" (#1591)" (#1593)
1+
- New Duck Player entry point (#1559)
2+
- history screenshots (#1511)

Sources/ContentScopeScripts/dist/contentScopeIsolated.js

Lines changed: 452 additions & 29 deletions
Large diffs are not rendered by default.

build/android/contentScope.js

Lines changed: 452 additions & 29 deletions
Large diffs are not rendered by default.

build/integration/contentScope.js

Lines changed: 454 additions & 30 deletions
Large diffs are not rendered by default.

build/windows/contentScope.js

Lines changed: 452 additions & 29 deletions
Large diffs are not rendered by default.

injected/entry-points/integration.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ function generateConfig() {
3333
'cookie',
3434
'webCompat',
3535
'apiManipulation',
36+
'duckPlayer',
3637
],
3738
},
3839
};
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import { expect, test } from '@playwright/test';
2+
import { DuckplayerOverlays } from './page-objects/duckplayer-overlays.js';
3+
4+
test.describe('Duck Player - Drawer UI variant', () => {
5+
test.describe('Video Player overlays', () => {
6+
test("Selecting 'watch here' on mobile", async ({ page }, workerInfo) => {
7+
const overlays = DuckplayerOverlays.create(page, workerInfo);
8+
await overlays.reducedMotion();
9+
10+
// Given drawer overlay variant is set
11+
await overlays.withRemoteConfig({ json: 'overlays-drawer.json' });
12+
13+
// And my setting is 'always ask'
14+
await overlays.userSettingIs('always ask');
15+
await overlays.gotoPlayerPage();
16+
17+
// watch here = overlays removed
18+
await overlays.mobile.choosesWatchHere();
19+
await overlays.mobile.overlayIsRemoved();
20+
await overlays.pixels.sendsPixels([
21+
{ pixelName: 'overlay', params: {} },
22+
{ pixelName: 'play.do_not_use', params: { remember: '0' } },
23+
]);
24+
});
25+
test("Selecting 'watch here' on mobile + remember", async ({ page }, workerInfo) => {
26+
const overlays = DuckplayerOverlays.create(page, workerInfo);
27+
await overlays.reducedMotion();
28+
29+
// Given drawer overlay variant is set
30+
await overlays.withRemoteConfig({ json: 'overlays-drawer.json' });
31+
32+
// And my setting is 'always ask'
33+
await overlays.userSettingIs('always ask');
34+
await overlays.gotoPlayerPage();
35+
36+
// watch here = overlays removed
37+
await overlays.mobile.selectsRemember();
38+
await overlays.mobile.choosesWatchHere();
39+
await overlays.mobile.overlayIsRemoved();
40+
await overlays.pixels.sendsPixels([
41+
{ pixelName: 'overlay', params: {} },
42+
{ pixelName: 'play.do_not_use', params: { remember: '1' } },
43+
]);
44+
await overlays.userSettingWasUpdatedTo('disabled');
45+
});
46+
test("Selecting 'watch in duckplayer' on mobile", async ({ page }, workerInfo) => {
47+
const overlays = DuckplayerOverlays.create(page, workerInfo);
48+
await overlays.reducedMotion();
49+
50+
// Given drawer overlay variant is set
51+
await overlays.withRemoteConfig({ json: 'overlays-drawer.json' });
52+
53+
// And my setting is 'always ask'
54+
await overlays.userSettingIs('always ask');
55+
await overlays.gotoPlayerPage();
56+
57+
await overlays.mobile.choosesDuckPlayer();
58+
await overlays.pixels.sendsPixels([
59+
{ pixelName: 'overlay', params: {} },
60+
{ pixelName: 'play.use', params: { remember: '0' } },
61+
]);
62+
await overlays.userSettingWasUpdatedTo('always ask');
63+
});
64+
test("Selecting 'watch in duckplayer' on mobile + remember", async ({ page }, workerInfo) => {
65+
const overlays = DuckplayerOverlays.create(page, workerInfo);
66+
await overlays.reducedMotion();
67+
68+
// Given drawer overlay variant is set
69+
await overlays.withRemoteConfig({ json: 'overlays-drawer.json' });
70+
71+
// And my setting is 'always ask'
72+
await overlays.userSettingIs('always ask');
73+
await overlays.gotoPlayerPage();
74+
75+
await overlays.mobile.selectsRemember();
76+
await overlays.mobile.choosesDuckPlayer();
77+
await overlays.pixels.sendsPixels([
78+
{ pixelName: 'overlay', params: {} },
79+
{ pixelName: 'play.use', params: { remember: '1' } },
80+
]);
81+
await overlays.userSettingWasUpdatedTo('enabled');
82+
});
83+
test('Clicking on video thumbnail dismisses overlay', async ({ page }, workerInfo) => {
84+
const overlays = DuckplayerOverlays.create(page, workerInfo);
85+
await overlays.reducedMotion();
86+
87+
// Given drawer overlay variant is set
88+
await overlays.withRemoteConfig({ json: 'overlays-drawer.json' });
89+
90+
// And my setting is 'always ask'
91+
await overlays.userSettingIs('always ask');
92+
await overlays.gotoPlayerPage();
93+
94+
await overlays.mobile.clicksOnVideoThumbnail();
95+
await overlays.pixels.sendsPixels([
96+
{ pixelName: 'overlay', params: {} },
97+
{ pixelName: 'play.do_not_use.thumbnail', params: {} },
98+
]);
99+
await overlays.userSettingWasNotUpdated();
100+
});
101+
test('Clicking on drawer backdrop dismisses overlay', async ({ page }, workerInfo) => {
102+
const overlays = DuckplayerOverlays.create(page, workerInfo);
103+
await overlays.reducedMotion();
104+
105+
// Given drawer overlay variant is set
106+
await overlays.withRemoteConfig({ json: 'overlays-drawer.json' });
107+
108+
// And my setting is 'always ask'
109+
await overlays.userSettingIs('always ask');
110+
await overlays.gotoPlayerPage();
111+
112+
await overlays.mobile.clicksOnDrawerBackdrop();
113+
await overlays.pixels.sendsPixels([
114+
{ pixelName: 'overlay', params: {} },
115+
{ pixelName: 'play.do_not_use', params: {} },
116+
]);
117+
await overlays.userSettingWasNotUpdated();
118+
});
119+
test('opens info', async ({ page }, workerInfo) => {
120+
const overlays = DuckplayerOverlays.create(page, workerInfo);
121+
await overlays.reducedMotion();
122+
123+
// Given drawer overlay variant is set
124+
await overlays.withRemoteConfig({ json: 'overlays-drawer.json' });
125+
126+
// And my setting is 'always ask'
127+
await overlays.userSettingIs('always ask');
128+
await overlays.gotoPlayerPage();
129+
await overlays.mobile.opensInfo();
130+
});
131+
});
132+
133+
/**
134+
* Use this test in `--headed` mode to cycle through every language
135+
*/
136+
test.describe.skip('Translated Overlays', () => {
137+
const items = [
138+
'bg',
139+
'cs',
140+
'da',
141+
'de',
142+
'el',
143+
'en',
144+
'es',
145+
'et',
146+
'fi',
147+
'fr',
148+
'hr',
149+
'hu',
150+
'it',
151+
'lt',
152+
'lv',
153+
'nb',
154+
'nl',
155+
'pl',
156+
'pt',
157+
'ro',
158+
'ru',
159+
'sk',
160+
'sl',
161+
'sv',
162+
'tr',
163+
];
164+
// const items = ['en']
165+
for (const locale of items) {
166+
test(`testing UI ${locale}`, async ({ page }, workerInfo) => {
167+
// console.log(workerInfo.project.use.viewport.height)
168+
// console.log(workerInfo.project.use.viewport.width)
169+
const overlays = DuckplayerOverlays.create(page, workerInfo);
170+
await overlays.withRemoteConfig({ json: 'overlays-drawer.json', locale });
171+
await overlays.userSettingIs('always ask');
172+
await overlays.gotoPlayerPage();
173+
await page.locator('ddg-video-drawer-mobile').nth(0).waitFor();
174+
await page.locator('.html5-video-player').screenshot({ path: `screens/se-2/${locale}.png` });
175+
});
176+
}
177+
});
178+
179+
/**
180+
* Use `npm run playwright-screenshots` to run this test only.
181+
*/
182+
test.describe('Overlay screenshot @screenshots', () => {
183+
test("testing Overlay UI 'en'", async ({ page }, workerInfo) => {
184+
const overlays = DuckplayerOverlays.create(page, workerInfo);
185+
await overlays.withRemoteConfig({ json: 'overlays-drawer.json', locale: 'en' });
186+
await overlays.userSettingIs('always ask');
187+
await overlays.gotoPlayerPage();
188+
await page.locator('ddg-video-drawer-mobile').nth(0).waitFor();
189+
await expect(page.locator('ddg-video-drawer-mobile')).toHaveScreenshot('drawer.png', { maxDiffPixels: 20 });
190+
});
191+
});
192+
});
Loading

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const uiSettings = {
3838
const configFiles = /** @type {const} */ ([
3939
'overlays.json',
4040
'overlays-live.json',
41+
'overlays-drawer.json',
4142
'disabled.json',
4243
'thumbnail-overlays-disabled.json',
4344
'click-interceptions-disabled.json',
@@ -90,6 +91,10 @@ export class DuckplayerOverlays {
9091
});
9192
}
9293

94+
async reducedMotion() {
95+
await this.page.emulateMedia({ reducedMotion: 'reduce' });
96+
}
97+
9398
/**
9499
* @param {object} params
95100
* @param {'default' | 'cookie_banner'} [params.variant]
@@ -472,6 +477,17 @@ export class DuckplayerOverlays {
472477
]);
473478
}
474479

480+
/**
481+
* @return {Promise<void>}
482+
*/
483+
async userSettingWasNotUpdated() {
484+
const messages = await this.collector.outgoingMessages();
485+
// @ts-expect-error - Subscription is missing method property
486+
const setUserValuesMessages = messages.filter((message) => message.payload?.method === 'setUserValues');
487+
488+
expect(setUserValuesMessages.length).toBe(0);
489+
}
490+
475491
/**
476492
* Helper for creating an instance per platform
477493
* @param {import("@playwright/test").Page} page
@@ -536,6 +552,16 @@ class DuckplayerOverlaysMobile {
536552
await page.getByRole('link', { name: 'Turn On Duck Player' }).click();
537553
}
538554

555+
async clicksOnVideoThumbnail() {
556+
const { page } = this.overlays;
557+
await page.locator('ddg-video-thumbnail-overlay-mobile .bg').click({ force: true });
558+
}
559+
560+
async clicksOnDrawerBackdrop() {
561+
const { page } = this.overlays;
562+
await page.locator('ddg-video-drawer-mobile .ddg-mobile-drawer-background').click({ position: { x: 10, y: 10 } });
563+
}
564+
539565
async selectsRemember() {
540566
const { page } = this.overlays;
541567
await page.getByRole('switch').click();
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"unprotectedTemporary": [],
3+
"features": {
4+
"duckPlayer": {
5+
"state": "enabled",
6+
"exceptions": [],
7+
"settings": {
8+
"overlays": {
9+
"youtube": {
10+
"state": "disabled",
11+
"selectors": {
12+
"thumbLink": "a[href^='/watch']",
13+
"excludedRegions": [
14+
"#playlist",
15+
"ytd-movie-renderer",
16+
"ytd-grid-movie-renderer"
17+
],
18+
"videoElement": "#player video",
19+
"videoElementContainer": "#player .html5-video-player",
20+
"hoverExcluded": [".an-overlay-causing-breakage"],
21+
"clickExcluded": [".an-overlay-causing-breakage"],
22+
"allowedEventTargets": [],
23+
"drawerContainer": "body"
24+
},
25+
"thumbnailOverlays": {
26+
"state": "enabled"
27+
},
28+
"clickInterception": {
29+
"state": "enabled"
30+
},
31+
"videoOverlays": {
32+
"state": "enabled"
33+
},
34+
"videoDrawer": {
35+
"state": "enabled"
36+
}
37+
},
38+
"serpProxy": {
39+
"state": "disabled"
40+
}
41+
},
42+
"domains": [
43+
{
44+
"domain": "localhost",
45+
"patchSettings": [
46+
{
47+
"op": "replace",
48+
"path": "/overlays/youtube/state",
49+
"value": "enabled"
50+
},
51+
{
52+
"op": "replace",
53+
"path": "/overlays/serpProxy/state",
54+
"value": "enabled"
55+
}
56+
]
57+
}
58+
]
59+
}
60+
}
61+
}
62+
}

injected/integration-test/test-pages/duckplayer/pages/player.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,23 @@
154154
</template>
155155
<script>
156156
(async () => {
157+
settingsFiles = {
158+
default: '/duckplayer/config/overlays.json',
159+
drawer: '/duckplayer/config/overlays-drawer.json',
160+
}
161+
157162
if (!new URLSearchParams(location.search).has('preview')) {
158163
return;
159164
}
160165
const platformName = new URLSearchParams(window.location.search).get('platform') || 'macos';
161166
const locale = new URLSearchParams(window.location.search).get('locale') || 'en';
167+
const settingsId = new URLSearchParams(window.location.search).get('config') || 'default';
168+
162169
await import("/build/contentScope.js").catch(console.error)
163-
const overlays = await fetch('/duckplayer/config/overlays.json').then(x => x.json())
170+
171+
const settingsFile = settingsFiles[settingsId] || settingsFiles.default;
172+
const overlays = await fetch(settingsFile).then(x => x.json())
173+
164174
document.dispatchEvent(new CustomEvent('content-scope-init-args', {
165175
detail: {
166176
debug: true,

injected/playwright.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@ export default defineConfig({
3737
},
3838
{
3939
name: 'ios',
40-
testMatch: ['integration-test/duckplayer-mobile.spec.js'],
40+
testMatch: ['integration-test/duckplayer-mobile.spec.js', 'integration-test/duckplayer-mobile-drawer.spec.js'],
4141
use: { injectName: 'apple-isolated', platform: 'ios', ...devices['iPhone 13'] },
4242
},
4343
{
4444
name: 'android',
4545
testMatch: [
4646
'integration-test/duckplayer-mobile.spec.js',
47+
'integration-test/duckplayer-mobile-drawer.spec.js',
4748
'integration-test/web-compat-android.spec.js',
4849
'integration-test/message-bridge-android.spec.js',
4950
],
Lines changed: 10 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)