Skip to content

Added initial duckplayer page without refactor #333

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
"$USER_UNPROTECTED_DOMAINS$": "readonly",
"$CONTENT_SCOPE$": "readonly",
"$TRACKER_LOOKUP$": "readonly",
"$BUNDLED_CONFIG$": "readonly"
"$BUNDLED_CONFIG$": "readonly",
"windowsInteropPostMessage": "readonly",
"windowsInteropAddEventListener": "readonly",
"windowsInteropRemoveEventListener": "readonly"
},
"rules": {
"indent": ["error", 4]
Expand Down
3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ let package = Package(
name: "ContentScopeScripts",
dependencies: [],
resources: [
.process("dist")
.process("dist/contentScope.js"),
.copy("dist/pages"),
]
),
]
Expand Down
127 changes: 127 additions & 0 deletions integration-test/playwright/duckplayer.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { test, expect } from '@playwright/test'
import { readFileSync } from 'fs'
import { mockResponse, mockWebkit, mockWindows, removeChromeWebView } from '@duckduckgo/messaging/lib/test-utils.mjs'

test.describe('duckplayer overlays', () => {
test('loads overlays when page is www.youtube.com', async ({ page }, workerInfo) => {
await setup({
page,
configPath: './integration-test/test-pages/duckplayer/config/overlays.json',
// @ts-expect-error
platform: workerInfo.project.use.platform
})
await routeAs({
page,
url: 'https://www.youtube.com',
path: 'integration-test/test-pages/duckplayer/pages/overlays.html'
})
// await page.pause()
await page.locator('.ddg-overlay.ddg-overlay-hover').waitFor({ timeout: 500, state: 'hidden' })
})
test('skips overlay code on none-youtube', async ({ page }, workerInfo) => {
await setup({
page,
configPath: './integration-test/test-pages/duckplayer/config/overlays.json',
// @ts-expect-error
platform: workerInfo.project.use.platform
})
await routeAs({
page,
url: 'https://example.com',
path: 'integration-test/test-pages/duckplayer/pages/overlays.html'
})
expect(await page.locator('.ddg-overlay.ddg-overlay-hover').count()).toEqual(0)
})
})

/**
* @param {object} params
* @param {import("@playwright/test").Page} params.page
* @param {string} params.configPath
* @param {"windows" | "macos"} params.platform
* @return {Promise<void>}
*/
async function setup (params) {
const {
page,
configPath,
platform
} = params

// read remote config from disk
const config = JSON.parse(readFileSync(configPath, 'utf8'))

// choose a JS bundle
const bundle = {
windows: './build/windows/contentScope.js',
apple: './Sources/ContentScopeScripts/dist/contentScope.js'
}[platform]

// read the build file from disk
const build = readFileSync(bundle, 'utf8')

// setup windows messaging mocks
const messagingMocks = {
windows: mockWindows,
apple: mockWebkit
}[platform]

await page.addInitScript(messagingMocks, {
messagingContext: {
env: 'development',
context: 'contentScopeScripts',
featureName: 'duckPlayer'
}
})

// any additional mock setup
if (platform === 'windows') {
await page.addInitScript(removeChromeWebView)
}

// setup global injected vars
await page.addInitScript((params) => Object.assign(globalThis, params), {
$CONTENT_SCOPE$: config,
$USER_UNPROTECTED_DOMAINS$: [],
$USER_PREFERENCES$: {
platform: { name: platform }
}
})

// add the default mock responses - just enough to get the page working
await page.addInitScript(mockResponse, {
responses: {
getUserValues: {
privatePlayerMode: { alwaysAsk: {} },
overlayInteracted: false
}
}
})

// attach the JS
await page.addInitScript(build)
}

/**
* @param {object} params
* @param {import("@playwright/test").Page} params.page
* @param {string} params.url
* @param {string} params.path
* @return {Promise<void>}
*/
async function routeAs (params) {
const {
page,
url,
path
} = params

// fake a url load
await page.route(url, (route, request) => {
console.log(request.url())
return route.fulfill({ path })
})

// navigate to the url
await page.goto(url)
}
23 changes: 23 additions & 0 deletions integration-test/test-pages/duckplayer/config/overlays.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"unprotectedTemporary": [],
"features": {
"duckPlayer": {
"state": "enabled",
"exceptions": [],
"settings": {
"overlays": [
{
"domain": "www.youtube.com",
"state": "enabled"
}
],
"proxy": [
{
"domain": "duckduckgo.com",
"state": "enabled"
}
]
}
}
}
}
20 changes: 20 additions & 0 deletions integration-test/test-pages/duckplayer/config/proxy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"features": {
"duckPlayer": {
"state": "enabled",
"exceptions": [],
"settings": {
"overlays": "disabled",
"proxy": "disabled",
"domains": [
{
"domain": "localhost",
"patchSettings": [
{ "op": "replace", "path": "/proxy", "value": "enabled" }
]
}
]
}
}
}
}
20 changes: 20 additions & 0 deletions integration-test/test-pages/duckplayer/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Runtime checks</title>
</head>
<body>
<p><a href="../../index.html">[Home]</a></p>

<p>Duck Player</p>
<ul>
<li><a href="./pages/basic-run.html">Basic Run</a> - <a href="./config/basic-run.json">Config</a></li>
<li><a href="./pages/filter-props.html">Filter props</a> - <a href="./config/filter-props.json">Config</a></li>
<li><a href="./pages/script-overload.html">Script overloading</a> - <a href="./config/script-overload.json">Config</a></li>
<li><a href="./pages/shadow-dom.html">Shadow dom support</a> - <a href="./config/shadow-dom.json">Config</a></li>
</ul>

</body>
</html>
84 changes: 84 additions & 0 deletions integration-test/test-pages/duckplayer/pages/overlays.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Runtime checks</title>
<link rel="stylesheet" href="../../shared/style.css">
<style>
#thumbnail {
height: 100px;
width: 200px;
margin: 5px;
background: lightblue;
border: 1px solid black;
float: left;
}

#thumbnail img {
width: 100%;
height: 100%;
}

#playlist {
clear: both;
width: 100px;

}

#playlist #items {
height: 150px;
overflow: auto;
}

#playlist #thumbnail {
width: 90px;
height: 50px;
}

#loaded {
clear: both;
float: none;
width: 300px;
}

h2 {
padding-top: 2em;
}
</style>
</head>
<body>
<script src="../../shared/utils.js"></script>
<p><a href="../index.html">[Duck Player]</a></p>

<div id="initial"></div>
<div id="loaded"></div>

<script>
const thumbnail = id => `<a id="thumbnail" href="/watch?v=${id}"><img src="//:0"></a>`;
const thumbnails = title => (title ? '<h2>'+title+'</h2>' : '') + '<div class="thumbnails" data-testid="'+title+'">' + ([1,2,3,4,5]).map(thumbnail).join('') + '</div>';
const playlist = title => `<div id="playlist"><h2>${title}</h2><div id="items" class="playlist-items" data-testid="${title}">${thumbnails()}</div></div>`;
document.querySelector('#initial').innerHTML = thumbnails('THUMBNAILS') + playlist('PLAYLIST') + thumbnails('MORE THUMBNAILS');
</script>

<script>
// eslint-disable-next-line no-undef
test('should thing', async () => {
console.log('haha');

await new Promise(res => setTimeout(res, 20000));

return [
{
name: 'enabled',
result: false,
expected: true
},
]
})

// eslint-disable-next-line no-undef
renderResults()
</script>
</body>
</html>
Loading