diff --git a/special-pages/messages/duckplayer/telemetryEvent.notify.json b/special-pages/messages/duckplayer/telemetryEvent.notify.json new file mode 100644 index 0000000000..1fb72b362f --- /dev/null +++ b/special-pages/messages/duckplayer/telemetryEvent.notify.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "TelemetryEvent", + "type": "object", + "required": ["attributes"], + "properties": { + "attributes": { + "oneOf": [ + { + "type": "object", + "title": "Impression", + "required": ["name", "value"], + "properties": { + "name": { + "const": "impression" + }, + "value": { + "type": "string", + "enum": ["landscape-layout"] + } + } + } + ] + } + } +} diff --git a/special-pages/pages/duckplayer/app/components/Button.module.css b/special-pages/pages/duckplayer/app/components/Button.module.css index ee6357cea2..e33abfddec 100644 --- a/special-pages/pages/duckplayer/app/components/Button.module.css +++ b/special-pages/pages/duckplayer/app/components/Button.module.css @@ -4,13 +4,13 @@ display: flex; height: 44px; line-height: 44px; - font-size: 16px; + font-size: 15px; + font-weight: bold; padding: 0 20px; flex-shrink: 0; box-shadow: none; background: rgba(255, 255, 255, 0.12); border-radius: var(--inner-radius); - font-weight: bold; color: rgba(255, 255, 255, 1); text-decoration: none; } diff --git a/special-pages/pages/duckplayer/app/components/MobileApp.jsx b/special-pages/pages/duckplayer/app/components/MobileApp.jsx index 3282d3091f..fa6e2bbea2 100644 --- a/special-pages/pages/duckplayer/app/components/MobileApp.jsx +++ b/special-pages/pages/duckplayer/app/components/MobileApp.jsx @@ -14,6 +14,7 @@ import { createAppFeaturesFrom } from "../features/app.js"; import { MobileButtons } from "./MobileButtons.jsx"; import { OrientationProvider } from "../providers/OrientationProvider.jsx"; import { FocusMode } from "./FocusMode.jsx"; +import { useTelemetry } from "../types.js"; const DISABLED_HEIGHT = 450; @@ -23,6 +24,7 @@ const DISABLED_HEIGHT = 450; */ export function MobileApp({ embed }) { const settings = useSettings(); + const telemetry = useTelemetry(); const features = createAppFeaturesFrom(settings) return ( <> @@ -35,7 +37,9 @@ export function MobileApp({ embed }) { // landscape // if the height is too low, just disable it if (window.innerHeight < DISABLED_HEIGHT) { - return FocusMode.disable() + FocusMode.disable() + telemetry.landscapeImpression() + return; } return FocusMode.enable() }} /> diff --git a/special-pages/pages/duckplayer/app/components/MobileApp.module.css b/special-pages/pages/duckplayer/app/components/MobileApp.module.css index 8549c20cae..7df1a36ac2 100644 --- a/special-pages/pages/duckplayer/app/components/MobileApp.module.css +++ b/special-pages/pages/duckplayer/app/components/MobileApp.module.css @@ -1,3 +1,6 @@ +body[data-display="app"] { + padding: 8px; +} html[data-focus-mode="on"]:root .main { --bg-color: transparent; } @@ -31,9 +34,9 @@ html[data-focus-mode="on"] .hideInFocus { --gutter-width: 8px; --gutter-combined: calc(var(--gutter-width) * 2); --outer-radius: 16px; - --inner-radius: 8px; + --inner-radius: 12px; --logo-width: 157px; - --inner-padding: 12px; + --inner-padding: 8px; position: relative; max-width: 100vh; margin: 0 auto; @@ -44,7 +47,7 @@ html[data-focus-mode="on"] .hideInFocus { --row-2: auto; --row-3: max-content; --row-4: max-content; - --row-5: 12px; + --row-5: 16px; --row-6: max-content; --row-7: auto; grid-template-rows: @@ -83,7 +86,7 @@ body:has([data-state="completed"] [aria-checked="true"]) .switch { .embed { background: var(--bg-color); grid-area: embed; - padding: var(--inner-padding); + padding: calc(var(--inner-padding) / 2); padding-bottom: 0; border-top-left-radius: var(--outer-radius); border-top-right-radius: var(--outer-radius); @@ -104,9 +107,7 @@ body:has([data-state="completed"] [aria-checked="true"]) .switch { .switch { grid-area: switch; - height: 50px; - background: rgba(255, 255, 255, 0.03); - border-radius: 16px; + height: 44px; } @media screen and (min-width: 425px) and (max-height: 600px) { @@ -159,8 +160,8 @@ body:has([data-state="completed"] [aria-checked="true"]) .switch { background: var(--bg-color); border-radius: unset; display: grid; - padding-top: 12px; - padding-bottom: 12px; + padding-top: 8px; + padding-bottom: 8px; height: 100%; } .buttons { @@ -180,75 +181,41 @@ body:has([data-state="completed"] [aria-checked="true"]) .switch { } } @media screen and (min-width: 600px) and (max-height: 450px) { - .main { - grid-template-columns: 1fr 1fr; - grid-template-rows: calc(44px + 24px) 44px auto calc(44px + 24px); - grid-template-areas: - 'embed logo' - 'embed buttons' - 'embed filler' - 'embed switch'; - align-content: center; - max-width: 100%; - max-height: 90vh; - } - body:has([data-state="completed"] [aria-checked="true"]) .main { - grid-template-rows: max-content max-content 0 0; + :root { + --body-padding: 4px; + --max-width: calc(100vw - var(--body-padding) * 2); } - body:has([data-state="completed"] [aria-checked="true"]) .logo { - padding-top: 0; - align-items: end; + body[data-display="app"] { + padding: var(--body-padding); } - body:has([data-state="completed"] [aria-checked="true"]) .buttons { - border-bottom-right-radius: var(--outer-radius); - padding-bottom: 12px; + .main { + grid-template-columns: 100%; + grid-template-rows: 100%; + grid-template-areas: 'embed'; + max-width: none; } - body:has([data-state="completed"] [aria-checked="true"]) .switch { - display: none; + .embed { + padding: 0; + border-radius: 0; + width: 100%; + max-width: var(--max-width); + background-color: transparent; } .filler { - display: block; - height: 100%; - grid-area: filler; - background: var(--bg-color) - } - .embed { - padding: var(--inner-padding); - border-bottom-left-radius: var(--outer-radius); - border-top-right-radius: 0; + display: none; } .logo { - display: grid; - width: 100%; - background: var(--bg-color); - justify-content: center; - border-top-right-radius: var(--outer-radius); - padding: var(--inner-padding); - padding-left: 0; + display: none; } .buttons { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; - padding: 0; - padding-right: var(--inner-padding); + display: none; } .switch { - background: var(--bg-color); - border-top-right-radius: 0; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - border-bottom-right-radius: var(--outer-radius); - align-self: end; - padding: var(--inner-padding); - padding-left: 0; - height: 100%; + display: none; } } @media screen and (min-width: 1100px) { .switch { justify-content: end; } - .switch > * { - min-width: 400px - } } diff --git a/special-pages/pages/duckplayer/app/components/Player.module.css b/special-pages/pages/duckplayer/app/components/Player.module.css index bfd7670e8c..dc8a276481 100644 --- a/special-pages/pages/duckplayer/app/components/Player.module.css +++ b/special-pages/pages/duckplayer/app/components/Player.module.css @@ -8,6 +8,7 @@ .root.mobile { aspect-ratio: 16/9; border-radius: var(--inner-radius); + overflow: hidden; height: auto; } @@ -45,3 +46,22 @@ justify-items: center; background: #2f2f2f; } + +@media screen and (min-width: 600px) and (max-height: 450px) { + .root.mobile { + max-height: 100%; + margin: 0 auto; + border-radius: var(--outer-radius); + overflow: hidden; + padding: 4px; + background: rgba(0, 0, 0, 0.3) + } + .iframe.mobile { + overflow: hidden; + border-radius: var(--inner-radius); + } + .error { + overflow: hidden; + border-radius: var(--inner-radius); + } +} diff --git a/special-pages/pages/duckplayer/app/components/SwitchBarMobile.module.css b/special-pages/pages/duckplayer/app/components/SwitchBarMobile.module.css index 41636cfc5a..9158c5065d 100644 --- a/special-pages/pages/duckplayer/app/components/SwitchBarMobile.module.css +++ b/special-pages/pages/duckplayer/app/components/SwitchBarMobile.module.css @@ -1,23 +1,12 @@ .switchBar { display: grid; - border-radius: 16px; + border-radius: 8px; background: rgba(255, 255, 255, 0.03); padding-inline: 16px; height: 100%; line-height: 1.1; } -@media screen and (min-width: 900px) { - .switchBar { - border-radius: 8px; - } -} -@media screen and (min-width: 667px) and (max-height: 450px) { - .switchBar { - border-radius: 8px; - } -} - .stateExiting { transition: all .3s ease-in-out; transition-delay: 2s; diff --git a/special-pages/pages/duckplayer/app/components/Wordmark-mobile.module.css b/special-pages/pages/duckplayer/app/components/Wordmark-mobile.module.css index a4848af924..7204c77f3b 100644 --- a/special-pages/pages/duckplayer/app/components/Wordmark-mobile.module.css +++ b/special-pages/pages/duckplayer/app/components/Wordmark-mobile.module.css @@ -6,7 +6,8 @@ grid-column-gap: 8px; grid-template-columns: max-content max-content; } -@media screen and (max-width: 500px) { + +@media screen and (max-width: 767px) { .logo { height: 100px; } diff --git a/special-pages/pages/duckplayer/app/index.css b/special-pages/pages/duckplayer/app/index.css index 8ef3db03bc..f1c55304d6 100644 --- a/special-pages/pages/duckplayer/app/index.css +++ b/special-pages/pages/duckplayer/app/index.css @@ -15,3 +15,9 @@ body[data-display="app"] { padding: 16px; } +@media screen and (min-width: 600px) and (max-height: 450px) { + body[data-display="app"] { + padding: 8px; + } +} + diff --git a/special-pages/pages/duckplayer/app/index.js b/special-pages/pages/duckplayer/app/index.js index f4ff62d3c5..0325b36a78 100644 --- a/special-pages/pages/duckplayer/app/index.js +++ b/special-pages/pages/duckplayer/app/index.js @@ -8,7 +8,7 @@ import { EmbedSettings } from './embed-settings.js' import enStrings from '../src/locales/en/duckplayer.json' import { Settings } from './settings.js' import { SettingsProvider } from './providers/SettingsProvider.jsx' -import { MessagingContext } from './types.js' +import { MessagingContext, TelemetryContext } from './types.js' import { UserValuesProvider } from './providers/UserValuesProvider.jsx' import { Fallback } from '../../../shared/components/Fallback/Fallback.jsx' import { Components } from './components/Components.jsx' @@ -17,10 +17,11 @@ import { DesktopApp } from './components/DesktopApp.jsx' /** * @param {import("../src/js/index.js").DuckplayerPage} messaging + * @param {import("../src/js/index.js").Telemetry} telemetry * @param {import("../../../shared/environment").Environment} baseEnvironment * @return {Promise} */ -export async function init (messaging, baseEnvironment) { +export async function init (messaging, telemetry, baseEnvironment) { const result = await callWithRetry(() => messaging.initialSetup()) if ('error' in result) { throw new Error(result.error) @@ -77,23 +78,25 @@ export async function init (messaging, baseEnvironment) { willThrow={environment.willThrow}> }> - - - - {settings.layout === 'desktop' && ( - - - - )} - {settings.layout === 'mobile' && ( - - - - )} - - - - + + + + + {settings.layout === 'desktop' && ( + + + + )} + {settings.layout === 'mobile' && ( + + + + )} + + + + + , root) diff --git a/special-pages/pages/duckplayer/app/providers/OrientationProvider.jsx b/special-pages/pages/duckplayer/app/providers/OrientationProvider.jsx index 4a063e2d6d..dd18d2406d 100644 --- a/special-pages/pages/duckplayer/app/providers/OrientationProvider.jsx +++ b/special-pages/pages/duckplayer/app/providers/OrientationProvider.jsx @@ -7,7 +7,10 @@ import { useEffect } from "preact/hooks"; */ export function OrientationProvider ({ onChange }) { useEffect(() => { - if (!screen.orientation?.type) return; + if (!screen.orientation?.type) { + onChange(getOrientationFromWidth()); + return + } onChange(getOrientationFromScreen()) const handleOrientationChange = () => { onChange(getOrientationFromScreen()); diff --git a/special-pages/pages/duckplayer/app/types.js b/special-pages/pages/duckplayer/app/types.js index 9a71a0243c..30ad73d718 100644 --- a/special-pages/pages/duckplayer/app/types.js +++ b/special-pages/pages/duckplayer/app/types.js @@ -16,3 +16,5 @@ export function useTypedTranslation () { export const MessagingContext = createContext(/** @type {import("../src/js/index.js").DuckplayerPage} */({})) export const useMessaging = () => useContext(MessagingContext) +export const TelemetryContext = createContext(/** @type {import("../src/js/index.js").Telemetry} */({})) +export const useTelemetry = () => useContext(TelemetryContext) diff --git a/special-pages/pages/duckplayer/src/js/index.js b/special-pages/pages/duckplayer/src/js/index.js index 368881e813..a267e41b22 100644 --- a/special-pages/pages/duckplayer/src/js/index.js +++ b/special-pages/pages/duckplayer/src/js/index.js @@ -108,6 +108,55 @@ export class DuckplayerPage { } } +/** + * Events that occur in the client-side application + */ +export class Telemetry { + /** + * @internal + */ + oneTimeEvents = new Set() + /** + * @param {import("@duckduckgo/messaging").Messaging} messaging + * @internal + */ + constructor (messaging) { + /** + * @internal + */ + this.messaging = messaging + } + + /** + * @param {import('../../../../types/duckplayer').TelemetryEvent} event + * @internal + */ + _event (event) { + this.messaging.notify('telemetryEvent', event) + } + + /** + * A landscape impression should only be sent once + * + * - Sends {@link "Duckplayer Messages".TelemetryEvent} + * - With attributes: {@link "Duckplayer Messages".Impression} + * + * ```json + * { + * "attributes": { + * "name": "impression", + * "value": "landscape-layout" + * } + * } + * ``` + */ + landscapeImpression () { + if (this.oneTimeEvents.has('landscapeImpression')) return + this.oneTimeEvents.add('landscapeImpression') + this._event({ attributes: { name: 'impression', value: 'landscape-layout' } }) + } +} + const baseEnvironment = new Environment() .withInjectName(document.documentElement.dataset.platform) .withEnv(import.meta.env) @@ -118,13 +167,14 @@ const messaging = createSpecialPageMessaging({ pageName: 'duckPlayerPage' }) -const example = new DuckplayerPage(messaging, import.meta.injectName) +const duckplayerPage = new DuckplayerPage(messaging, import.meta.injectName) +const telemetry = new Telemetry(messaging) -init(example, baseEnvironment).catch(e => { +init(duckplayerPage, telemetry, baseEnvironment).catch(e => { // messages. console.error(e) const msg = typeof e?.message === 'string' ? e.message : 'unknown init error' - example.reportInitException({ message: msg }) + duckplayerPage.reportInitException({ message: msg }) }) initStorage() diff --git a/special-pages/playwright.config.js b/special-pages/playwright.config.js index 2ce0b63ac1..e14e741956 100644 --- a/special-pages/playwright.config.js +++ b/special-pages/playwright.config.js @@ -59,7 +59,8 @@ export default defineConfig({ { name: 'android-landscape', testMatch: [ - 'duckplayer-screenshots.spec.js' + 'duckplayer-screenshots.spec.js', + 'duckplayer-telemetry.spec.js' ], use: { ...devices['Galaxy S III landscape'], diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-android-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-android-darwin.png index 8cf8c702bc..8e68f9f1df 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-android-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-android-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-android-landscape-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-android-landscape-darwin.png index 22055ffc24..4f64073c02 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-android-landscape-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-android-landscape-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-ios-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-ios-darwin.png index 4f6b5aeb48..1e19b10c6a 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-ios-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-ios-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-macos-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-macos-darwin.png index d96bffb686..f8880ab999 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-macos-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-macos-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-windows-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-windows-darwin.png index c5908691b2..12add2a753 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-windows-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/enabled-layout-windows-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-android-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-android-darwin.png index b677d48812..27c786f358 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-android-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-android-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-android-landscape-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-android-landscape-darwin.png index 2fe9d44f1a..a734621627 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-android-landscape-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-android-landscape-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-ios-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-ios-darwin.png index 03bed73dde..c00bedf088 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-ios-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-ios-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-macos-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-macos-darwin.png index 0a356c65c6..2715e14e69 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-macos-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-macos-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-windows-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-windows-darwin.png index 62f140af52..c50eb9d4d1 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-windows-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/error-layout-windows-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-android-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-android-darwin.png index 1fb0d5f404..ec5792c059 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-android-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-android-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-android-landscape-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-android-landscape-darwin.png index 999ea58329..4f64073c02 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-android-landscape-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-android-landscape-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-ios-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-ios-darwin.png index 7e5e92894c..a328d5e6e3 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-ios-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-ios-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-macos-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-macos-darwin.png index c0754b4fa1..0d8c5e9220 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-macos-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-macos-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-windows-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-windows-darwin.png index 79d25b5aa6..318cf8f1a9 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-windows-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/regular-layout-windows-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/tooltip-macos-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/tooltip-macos-darwin.png index 9defc83b22..1427668599 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/tooltip-macos-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/tooltip-macos-darwin.png differ diff --git a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/tooltip-windows-darwin.png b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/tooltip-windows-darwin.png index 1c1e1555df..4cde868e10 100644 Binary files a/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/tooltip-windows-darwin.png and b/special-pages/tests/duckplayer-screenshots.spec.js-snapshots/tooltip-windows-darwin.png differ diff --git a/special-pages/tests/duckplayer-telemetry.spec.js b/special-pages/tests/duckplayer-telemetry.spec.js new file mode 100644 index 0000000000..8708edf9e0 --- /dev/null +++ b/special-pages/tests/duckplayer-telemetry.spec.js @@ -0,0 +1,26 @@ +import { test } from '@playwright/test' +import { DuckPlayerPage } from './page-objects/duck-player.js' + +test.describe('duckplayer telemetry', () => { + test('sends a landscape impression', async ({ page }, workerInfo) => { + test.skip(isDesktop(workerInfo)) + const duckplayer = DuckPlayerPage.create(page, workerInfo) + await duckplayer.openWithVideoID() + await duckplayer.hasLoadedIframe() + await duckplayer.didSendTelemetry({ attributes: { name: 'impression', value: 'landscape-layout' } }) + }) +}) + +/** + * @param {import("@playwright/test").TestInfo} testInfo + */ +function isMobile (testInfo) { + const u = /** @type {any} */(testInfo.project.use) + return u?.platform === 'android' || u?.platform === 'ios' +} +/** + * @param {import("@playwright/test").TestInfo} testInfo + */ +function isDesktop (testInfo) { + return !isMobile(testInfo) +} diff --git a/special-pages/tests/page-objects/duck-player.js b/special-pages/tests/page-objects/duck-player.js index 39539d15e2..bdc27af086 100644 --- a/special-pages/tests/page-objects/duck-player.js +++ b/special-pages/tests/page-objects/duck-player.js @@ -446,6 +446,23 @@ export class DuckPlayerPage { }) } + /** + * @param {import('../../types/duckplayer.js').TelemetryEvent} evt + */ + async didSendTelemetry (evt) { + const events = await this.mocks.waitForCallCount({ method: 'telemetryEvent', count: 1 }) + expect(events).toStrictEqual([ + { + payload: { + context: 'specialPages', + featureName: 'duckPlayerPage', + method: 'telemetryEvent', + params: evt + } + } + ]) + } + async withStorageValues () { await this.page.evaluate(() => { localStorage.setItem('foo', 'bar') diff --git a/special-pages/types/duckplayer.ts b/special-pages/types/duckplayer.ts index 987d3a7513..a42041272d 100644 --- a/special-pages/types/duckplayer.ts +++ b/special-pages/types/duckplayer.ts @@ -25,7 +25,8 @@ export interface DuckplayerMessages { | OpenInfoNotification | OpenSettingsNotification | ReportInitExceptionNotification - | ReportPageExceptionNotification; + | ReportPageExceptionNotification + | TelemetryEventNotification; requests: GetUserValuesRequest | InitialSetupRequest | SetUserValuesRequest; subscriptions: OnUserValuesChangedSubscription; } @@ -61,6 +62,20 @@ export interface ReportPageExceptionNotification { export interface ReportPageExceptionNotify { message: string; } +/** + * Generated from @see "../messages/duckplayer/telemetryEvent.notify.json" + */ +export interface TelemetryEventNotification { + method: "telemetryEvent"; + params: TelemetryEvent; +} +export interface TelemetryEvent { + attributes: Impression; +} +export interface Impression { + name: "impression"; + value: "landscape-layout"; +} /** * Generated from @see "../messages/duckplayer/getUserValues.request.json" */