Merge branch 'main' of git.k6n.net:mats/cms-onpageeditor
This commit is contained in:
commit
2d35df4c7f
15 files changed
+295
-16
No files matched your search
@@ -0,0 +1,49 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { bundleUrl, hasPreviewCookie, runLoader, type LoaderEnv } from '../src/loader-core'
|
||||
|
||||
function env(href: string, cookie = '', scriptSrc?: string) {
|
||||
const jar = { value: cookie }
|
||||
const e = {
|
||||
location: { href, protocol: new URL(href).protocol, replace: vi.fn() },
|
||||
cookie: { get: () => jar.value, set: (v: string) => void (jar.value = v) },
|
||||
scriptSrc,
|
||||
load: vi.fn(() => Promise.resolve({})),
|
||||
} satisfies LoaderEnv
|
||||
return { e, jar }
|
||||
}
|
||||
|
||||
describe('cms-client loader', () => {
|
||||
it('does nothing for visitors', () => {
|
||||
const { e } = env('https://k6n.net/')
|
||||
expect(runLoader(e)).toBe('idle')
|
||||
expect(e.load).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('loads the editor bundle next to the script when the preview cookie is set', () => {
|
||||
const { e } = env('https://k6n.net/', 'a=b; cms_preview=1', 'https://k6n.net/editor/cms-client.js')
|
||||
expect(runLoader(e)).toBe('loaded')
|
||||
expect(e.load).toHaveBeenCalledWith('https://k6n.net/editor/onpage-editor.js')
|
||||
})
|
||||
|
||||
it('?cms_preview=1 sets the cookie, strips the param and reloads', () => {
|
||||
const { e, jar } = env('https://k6n.net/a?x=1&cms_preview=1')
|
||||
expect(runLoader(e)).toBe('redirected')
|
||||
expect(jar.value).toMatch(/^cms_preview=1; path=\/; SameSite=Lax; Secure$/)
|
||||
expect(e.location.replace).toHaveBeenCalledWith('https://k6n.net/a?x=1')
|
||||
expect(e.load).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('?cms_preview=0 clears the cookie (no Secure on http)', () => {
|
||||
const { e, jar } = env('http://localhost/a?cms_preview=0', 'cms_preview=1')
|
||||
runLoader(e)
|
||||
expect(jar.value).toBe('cms_preview=; path=/; max-age=0; SameSite=Lax')
|
||||
expect(e.location.replace).toHaveBeenCalledWith('http://localhost/a')
|
||||
})
|
||||
|
||||
it('helpers', () => {
|
||||
expect(hasPreviewCookie('cms_preview=1')).toBe(true)
|
||||
expect(hasPreviewCookie('xcms_preview=1')).toBe(false)
|
||||
expect(hasPreviewCookie('cms_preview=0')).toBe(false)
|
||||
expect(bundleUrl()).toBe('/editor/onpage-editor.js')
|
||||
})
|
||||
})
|
||||
@@ -84,7 +84,6 @@ describe('Style panel (schema-driven)', () => {
|
||||
await select('l1')
|
||||
await h.press('Style')
|
||||
await act(async () => void [...h.shadow.querySelectorAll<HTMLElement>('[role=tab]')].find((t) => t.textContent === 'Tablet')!.click())
|
||||
expect(h.shadow.querySelector('[data-style-field="gap"]')).toBeNull() // spacing has no per-breakpoint form
|
||||
await act(async () => void chip('flow', 'Stack').click())
|
||||
await h.settle()
|
||||
expect(data('l1').responsive).toEqual({ tablet: { flow: 'stack' } })
|
||||
@@ -95,6 +94,33 @@ describe('Style panel (schema-driven)', () => {
|
||||
expect('responsive' in data('l1')).toBe(false)
|
||||
})
|
||||
|
||||
it('breakpoints can override gap, which renders as a k6n-<bp>-gap class', async () => {
|
||||
h = await setup()
|
||||
await h.settle()
|
||||
await select('l1')
|
||||
await h.press('Style')
|
||||
await act(async () => void [...h.shadow.querySelectorAll<HTMLElement>('[role=tab]')].find((t) => t.textContent === 'Mobile')!.click())
|
||||
await act(async () => void chip('gap', 'xs').click())
|
||||
await h.settle()
|
||||
expect(data('l1').responsive).toEqual({ mobile: { gap: 'xs' } })
|
||||
expect(data('l1').gap).not.toBe('xs')
|
||||
expect(byId('l1').className).toContain('k6n-m-gap-xs')
|
||||
})
|
||||
|
||||
it('the device preview is an iframe named so the editor does not boot inside it', async () => {
|
||||
h = await setup()
|
||||
await h.settle()
|
||||
await select('l1')
|
||||
await h.press('Style')
|
||||
await act(async () => void [...h.shadow.querySelectorAll<HTMLElement>('[role=tab]')].find((t) => t.textContent === 'Mobile')!.click())
|
||||
await act(async () => void [...h.shadow.querySelectorAll<HTMLElement>('.cms-style__preview .cms-chip')][0].click())
|
||||
const f = h.shadow.querySelector('iframe')!
|
||||
expect(f.name).toBe('cms-device-preview')
|
||||
expect(f.style.width).toBe('390px')
|
||||
await act(async () => void h.shadow.querySelector<HTMLElement>('[aria-label="Close preview"]')!.click())
|
||||
expect(h.shadow.querySelector('iframe')).toBeNull()
|
||||
})
|
||||
|
||||
it('rapid clicks on one field coalesce into a single undo step', async () => {
|
||||
h = await setup()
|
||||
await h.settle()
|
||||
|
||||
+2
-1
@@ -25,7 +25,8 @@ describe('describeStyle', () => {
|
||||
expect(byName('paddingTop')).toMatchObject({ kind: 'spacing', box: 'padding', side: 'top', overrides: 'padding', token: '--k6n-sp-{value}', inferred: false })
|
||||
expect(byName('gap')).toMatchObject({ kind: 'gap', inferred: false })
|
||||
expect(byName('flow').responsive).toEqual(['mobile', 'tablet', 'desktop'])
|
||||
expect(byName('gap').responsive).toEqual([]) // spacing is not a breakpoint override (the template has no classes for it)
|
||||
expect(byName('gap').responsive).toEqual(['mobile', 'tablet', 'desktop'])
|
||||
expect(byName('padding').responsive).toEqual([]) // only declared per-side in the breakpoint def
|
||||
expect(isWrapperSchema(layout)).toBe(true)
|
||||
})
|
||||
|
||||
|
||||
Reference in new issue
Block a user