Skip to content
Open
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
76 changes: 46 additions & 30 deletions bun.lock

Large diffs are not rendered by default.

71 changes: 41 additions & 30 deletions e2e/screenshots.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,46 @@ import {
} from '@screenly/edge-apps/test/screenshots'
import path from 'path'

const { screenlyJsContent } = createMockScreenlyForScreenshots(
{ coordinates: [40.7128, -74.006], location: 'New York, NY' },
{
enable_analytics: 'false',
override_locale: 'en',
override_timezone: 'America/New_York',
welcome_heading: 'Welcome',
welcome_message: 'to the team, Sam!',
},
)

for (const { width, height } of RESOLUTIONS) {
test(`screenshot ${width}x${height}`, async ({ browser }) => {
const screenshotsDir = getScreenshotsDir()

const context = await browser.newContext({ viewport: { width, height } })
const page = await context.newPage()

await setupClockMock(page)
await setupScreenlyJsMock(page, screenlyJsContent)

await page.goto('/')
await page.waitForLoadState('networkidle')

await page.screenshot({
path: path.join(screenshotsDir, `${width}x${height}.png`),
fullPage: false,
})
const VARIANTS = [
{ prefix: '', mode: 'lobby' },
{ prefix: 'poster-', mode: 'poster' },
]

for (const { prefix, mode } of VARIANTS) {
const { screenlyJsContent } = createMockScreenlyForScreenshots(
{ coordinates: [40.7128, -74.006], location: 'New York, NY' },
{
enable_analytics: 'false',
mode,
override_locale: 'en',
override_timezone: 'America/New_York',
welcome_heading: 'Welcome',
welcome_message: 'to the team, Sam!',
},
)

for (const { width, height } of RESOLUTIONS) {
test(`screenshot ${prefix}${width}x${height}`, async ({ browser }) => {
const screenshotsDir = getScreenshotsDir()

const context = await browser.newContext({
viewport: { width, height },
reducedMotion: 'reduce',
})
const page = await context.newPage()

await context.close()
})
await setupClockMock(page)
await setupScreenlyJsMock(page, screenlyJsContent)

await page.goto('/')
await page.waitForLoadState('networkidle')

await page.screenshot({
path: path.join(screenshotsDir, `${prefix}${width}x${height}.png`),
fullPage: false,
})

await context.close()
})
}
}
14 changes: 9 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@
orientation="auto"
padding="0"
>
<div id="app">
<app-header class="header" show-date></app-header>
<main class="content">
<main class="welcome">
<header class="welcome-header">
<img class="welcome-logo is-hidden" data-logo alt="" />
<p class="welcome-time" data-time></p>
</header>
<section class="welcome-body">
<p class="welcome-eyebrow" data-eyebrow></p>
<p id="welcome-heading" class="welcome-heading"></p>
<p id="welcome-message" class="welcome-message"></p>
</main>
</div>
</section>
</main>
</auto-scaler>
<script type="module" src="/src/main.ts"></script>
</body>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"prettier": "./.prettierrc.json",
"devDependencies": {
"@playwright/test": "^1.60.0",
"@screenly/edge-apps": "^1.2.1",
"@screenly/edge-apps": "^1.5.0",
"@types/bun": "^1.3.14",
"@types/jsdom": "^28.0.3",
"bun-types": "^1.3.14",
Expand Down
15 changes: 15 additions & 0 deletions screenly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ settings:
optional: true
help_text: Enable or disable Sentry and Google Analytics integrations.
is_global: true
mode:
type: string
default_value: lobby
title: Mode
optional: true
help_text:
properties:
help_text: Choose the layout for where the screen is placed.
options:
- label: Lobby (logo and date header)
value: lobby
- label: Poster (message only)
value: poster
type: select
schema_version: 1
override_locale:
type: string
default_value: en
Expand Down
15 changes: 15 additions & 0 deletions screenly_qc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ settings:
optional: true
help_text: Enable or disable Sentry and Google Analytics integrations.
is_global: true
mode:
type: string
default_value: lobby
title: Mode
optional: true
help_text:
properties:
help_text: Choose the layout for where the screen is placed.
options:
- label: Lobby (logo and date header)
value: lobby
- label: Poster (message only)
value: poster
type: select
schema_version: 1
override_locale:
type: string
default_value: en
Expand Down
Binary file modified screenshots/1080x1920.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/1280x720.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/1920x1080.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/2160x3840.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/2160x4096.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/3840x2160.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/4096x2160.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/480x800.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/720x1280.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/800x480.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/poster-1080x1920.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/poster-1280x720.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/poster-1920x1080.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/poster-2160x3840.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/poster-2160x4096.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/poster-3840x2160.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/poster-4096x2160.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/poster-480x800.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/poster-720x1280.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/poster-800x480.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 28 additions & 1 deletion src/app.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, test, expect, beforeEach, afterEach } from 'bun:test'
import { setupScreenlyMock, resetScreenlyMock } from '@screenly/edge-apps/test'

import init from './app'
import init, { getHeadingSizeClass } from './app'

describe('Welcome App', () => {
beforeEach(() => {
Expand Down Expand Up @@ -57,4 +57,31 @@ describe('Welcome App', () => {
'to the team',
)
})

test('steps a long heading down in size', () => {
setupScreenlyMock({}, { welcome_heading: 'Welcome to our headquarters' })
init()

const headingEl = document.querySelector('#welcome-heading')
expect(headingEl?.classList.contains('is-long')).toBe(true)
})
})

describe('getHeadingSizeClass', () => {
test('returns no class for a short heading', () => {
expect(getHeadingSizeClass('Welcome')).toBe('')
})

test('returns is-long past 16 characters', () => {
expect(getHeadingSizeClass('a'.repeat(17))).toBe('is-long')
})

test('returns is-very-long past 34 characters', () => {
expect(getHeadingSizeClass('a'.repeat(35))).toBe('is-very-long')
})

test('treats the thresholds as exclusive', () => {
expect(getHeadingSizeClass('a'.repeat(16))).toBe('')
expect(getHeadingSizeClass('a'.repeat(34))).toBe('is-long')
})
})
14 changes: 14 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import { getSettingWithDefault, signalReady } from '@screenly/edge-apps'

const LONG_HEADING_CHARS = 16
const VERY_LONG_HEADING_CHARS = 34

// The greeting is customer free text; a long one steps down in size instead
// of wrapping off the canvas
export function getHeadingSizeClass(text: string): string {
if (text.length > VERY_LONG_HEADING_CHARS) return 'is-very-long'
if (text.length > LONG_HEADING_CHARS) return 'is-long'
return ''
}

export default function init() {
const welcomeHeading = getSettingWithDefault<string>(
'welcome_heading',
Expand All @@ -12,6 +23,9 @@ export default function init() {

const headingEl =
document.querySelector<HTMLParagraphElement>('#welcome-heading')!
headingEl.className = ['welcome-heading', getHeadingSizeClass(welcomeHeading)]
.filter(Boolean)
.join(' ')
headingEl.textContent = welcomeHeading

const messageEl =
Expand Down
Loading