fix: live preview device position when using zoom (#6667)

This commit is contained in:
Jacob Fletcher
2024-06-07 09:47:35 -04:00
committed by GitHub
parent 1e834e58a4
commit 9525511e8b
8 changed files with 234 additions and 28 deletions

View File

@@ -101,6 +101,13 @@ export const selectTableRow = async (page: Page, title: string): Promise<void> =
expect(await page.locator(selector).isChecked()).toBe(true)
}
export async function navigateToListCellLink(page: Page, selector = '.cell-id') {
const cellLink = page.locator(`${selector} a`).first()
const linkURL = await cellLink.getAttribute('href')
await cellLink.click()
await page.waitForURL(`**${linkURL}`)
}
export const findTableCell = async (
page: Page,
fieldName: string,

View File

@@ -10,7 +10,7 @@ import { Users } from './collections/Users'
import { Footer } from './globals/Footer'
import { Header } from './globals/Header'
import { seed } from './seed'
import { mobileBreakpoint } from './shared'
import { desktopBreakpoint, mobileBreakpoint } from './shared'
import { formatLivePreviewURL } from './utilities/formatLivePreviewURL'
const mockModulePath = path.resolve(__dirname, './mocks/mockFSModule.js')
@@ -21,7 +21,7 @@ export default buildConfigWithDefaults({
// You can define any of these properties on a per collection or global basis
// The Live Preview config cascades from the top down, properties are inherited from here
url: formatLivePreviewURL,
breakpoints: [mobileBreakpoint],
breakpoints: [mobileBreakpoint, desktopBreakpoint],
collections: ['pages', 'posts'],
globals: ['header', 'footer'],
},

View File

@@ -5,7 +5,14 @@ import { expect, test } from '@playwright/test'
import { exactText, initPageConsoleErrorCatch, saveDocAndAssert } from '../helpers'
import { AdminUrlUtil } from '../helpers/adminUrlUtil'
import { initPayloadE2E } from '../helpers/configHelpers'
import { mobileBreakpoint } from './shared'
import {
ensureDeviceIsCentered,
ensureDeviceIsLeftAligned,
goToCollectionLivePreview,
selectLivePreviewBreakpoint,
selectLivePreviewZoom,
} from './helpers'
import { desktopBreakpoint, mobileBreakpoint } from './shared'
import { startLivePreviewDemo } from './startLivePreviewDemo'
const { beforeAll, describe } = test
@@ -216,4 +223,34 @@ describe('Live Preview', () => {
const height = parseInt(heightInputValue)
expect(height).toBe(mobileBreakpoint.height)
})
test('device — centers device when smaller than frame despite zoom', async () => {
await goToCollectionLivePreview(page, url)
await selectLivePreviewBreakpoint(page, mobileBreakpoint.label)
await ensureDeviceIsCentered(page)
await selectLivePreviewZoom(page, '75%')
await ensureDeviceIsCentered(page)
await selectLivePreviewZoom(page, '50%')
await ensureDeviceIsCentered(page)
await selectLivePreviewZoom(page, '125%')
await ensureDeviceIsCentered(page)
await selectLivePreviewZoom(page, '200%')
await ensureDeviceIsCentered(page)
expect(true).toBeTruthy()
})
test('device — left-aligns device when larger than frame despite zoom', async () => {
await goToCollectionLivePreview(page, url)
await selectLivePreviewBreakpoint(page, desktopBreakpoint.label)
await ensureDeviceIsLeftAligned(page)
await selectLivePreviewZoom(page, '75%')
await ensureDeviceIsLeftAligned(page)
await selectLivePreviewZoom(page, '50%')
await ensureDeviceIsLeftAligned(page)
await selectLivePreviewZoom(page, '125%')
await ensureDeviceIsLeftAligned(page)
await selectLivePreviewZoom(page, '200%')
await ensureDeviceIsLeftAligned(page)
expect(true).toBeTruthy()
})
})

View File

@@ -0,0 +1,124 @@
import type { Page } from '@playwright/test'
import { expect } from '@playwright/test'
import { exactText, navigateToListCellLink } from '../helpers.js'
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
export const EXPECT_TIMEOUT = 8000
export const POLL_TOPASS_TIMEOUT = EXPECT_TIMEOUT * 4
export const goToDoc = async (page: Page, urlUtil: AdminUrlUtil) => {
await page.goto(urlUtil.list)
await page.waitForURL(urlUtil.list)
await navigateToListCellLink(page)
}
export const goToCollectionLivePreview = async (
page: Page,
urlUtil: AdminUrlUtil,
): Promise<void> => {
await goToDoc(page, urlUtil)
await page.goto(`${page.url()}/preview`)
await page.waitForURL(`**/preview`)
}
export const goToGlobalLivePreview = async (
page: Page,
slug: string,
serverURL: string,
): Promise<void> => {
const global = new AdminUrlUtil(serverURL, slug)
const previewURL = `${global.global(slug)}/preview`
await page.goto(previewURL)
await page.waitForURL(previewURL)
}
export const selectLivePreviewBreakpoint = async (page: Page, breakpointLabel: string) => {
const breakpointSelector = page.locator(
'.live-preview-toolbar-controls__breakpoint button.popup-button',
)
await expect(() => expect(breakpointSelector).toBeTruthy()).toPass({
timeout: POLL_TOPASS_TIMEOUT,
})
await breakpointSelector.first().click()
await page
.locator(`.live-preview-toolbar-controls__breakpoint button.popup-button-list__button`)
.filter({ hasText: breakpointLabel })
.click()
await expect(breakpointSelector).toContainText(breakpointLabel)
const option = page.locator(
'.live-preview-toolbar-controls__breakpoint button.popup-button-list__button--selected',
)
await expect(option).toHaveText(breakpointLabel)
}
export const selectLivePreviewZoom = async (page: Page, zoomLabel: string) => {
const zoomSelector = page.locator('.live-preview-toolbar-controls__zoom button.popup-button')
await expect(() => expect(zoomSelector).toBeTruthy()).toPass({
timeout: POLL_TOPASS_TIMEOUT,
})
await zoomSelector.first().click()
const zoomOption = page.locator(
'.live-preview-toolbar-controls__zoom button.popup-button-list__button',
{
hasText: exactText(zoomLabel),
},
)
expect(zoomOption).toBeTruthy()
await zoomOption.click()
await expect(zoomSelector).toContainText(zoomLabel)
const option = page.locator(
'.live-preview-toolbar-controls__zoom button.popup-button-list__button--selected',
)
await expect(option).toHaveText(zoomLabel)
}
export const ensureDeviceIsCentered = async (page: Page) => {
const main = page.locator('.live-preview-window__main')
const iframe = page.locator('iframe.live-preview-iframe')
const mainBoxAfterZoom = await main.boundingBox()
const iframeBoxAfterZoom = await iframe.boundingBox()
const distanceFromIframeLeftToMainLeftAfterZoom = Math.abs(
mainBoxAfterZoom?.x - iframeBoxAfterZoom?.x,
)
const distanceFromIFrameRightToMainRightAfterZoom = Math.abs(
mainBoxAfterZoom?.x +
mainBoxAfterZoom?.width -
iframeBoxAfterZoom?.x -
iframeBoxAfterZoom?.width,
)
await expect(() =>
expect(distanceFromIframeLeftToMainLeftAfterZoom).toBe(
distanceFromIFrameRightToMainRightAfterZoom,
),
).toPass({
timeout: POLL_TOPASS_TIMEOUT,
})
}
export const ensureDeviceIsLeftAligned = async (page: Page) => {
const main = page.locator('.live-preview-window__main > div')
const iframe = page.locator('iframe.live-preview-iframe')
const mainBoxAfterZoom = await main.boundingBox()
const iframeBoxAfterZoom = await iframe.boundingBox()
const distanceFromIframeLeftToMainLeftAfterZoom = Math.abs(
mainBoxAfterZoom?.x - iframeBoxAfterZoom?.x,
)
await expect(() => expect(distanceFromIframeLeftToMainLeftAfterZoom).toBe(0)).toPass({
timeout: POLL_TOPASS_TIMEOUT,
})
}

View File

@@ -8,3 +8,10 @@ export const mobileBreakpoint = {
width: 375,
height: 667,
}
export const desktopBreakpoint = {
label: 'Desktop',
name: 'desktop',
width: 1920,
height: 1024,
}