From a4ffd32abb7684df4bc1e96dce56d4901d1226e5 Mon Sep 17 00:00:00 2001 From: IvanCCO Date: Sat, 4 Jul 2026 20:23:11 -0300 Subject: [PATCH] test: update grid overlay rendering behavior based on enabled state - Modified tests to ensure the grid overlay does not render when disabled by default. - Updated the behavior to render the overlay when the enabled state is set to true. - Introduced a new function to merge session settings, improving the handling of grid settings based on site state. - Adjusted default settings to set 'enabled' to false, aligning with the new behavior. These changes enhance the clarity of the grid's visibility logic and ensure consistent behavior across different states. --- src/content.resize.test.ts | 2 +- src/content.test.ts | 42 ++++++++++--------- src/site-patterns.ts | 83 ++++++++++++++++++++++++-------------- src/utils.ts | 2 +- 4 files changed, 78 insertions(+), 51 deletions(-) diff --git a/src/content.resize.test.ts b/src/content.resize.test.ts index 1aca53e..f02f73a 100644 --- a/src/content.resize.test.ts +++ b/src/content.resize.test.ts @@ -17,7 +17,7 @@ describe('resize handling', () => { }); it('re-renders the grid when the window is resized', async () => { - const stored = normalizeSettings(DEFAULT_SETTINGS); + const stored = normalizeSettings({ ...DEFAULT_SETTINGS, enabled: true }); vi.stubGlobal('chrome', { runtime: { getURL: (path: string) => `chrome-extension://test-id/${path}`, diff --git a/src/content.test.ts b/src/content.test.ts index 75bdc06..490d0b2 100644 --- a/src/content.test.ts +++ b/src/content.test.ts @@ -95,9 +95,15 @@ afterEach(() => { }); describe('initial render', () => { - it('renders the overlay with the default stretch column grid', async () => { + it('does not render the overlay while disabled by default', async () => { await loadContentScript(); + expect(document.getElementById(GRID_OVERLAY_ID)).toBeNull(); + }); + + it('renders the overlay with the default stretch column grid when enabled', async () => { + await loadContentScript({ enabled: true }); + const overlay = getOverlay(); const gridLayer = overlay.querySelector('.grid-ui__layer') as HTMLElement; const frame = gridLayer.firstElementChild as HTMLElement; @@ -106,10 +112,10 @@ describe('initial render', () => { expect(frame.style.gridTemplateColumns).toBe(`repeat(${DEFAULT_SETTINGS.count}, minmax(0, 1fr))`); }); - it('reads the site identity from the page metadata for the popover header', async () => { + it('reads the site identity from the page metadata for the popover header when enabled', async () => { document.head.innerHTML = ''; - await loadContentScript(); + await loadContentScript({ enabled: true }); const title = document.querySelector('.grid-ui__popover-title'); expect(title?.textContent).toBe('Acme Corp'); @@ -118,7 +124,7 @@ describe('initial render', () => { describe('visibility toggle', () => { it('hides the grid layer and flips the trigger icon state', async () => { - await loadContentScript(); + await loadContentScript({ enabled: true }); const overlay = getOverlay(); const axisTrigger = overlay.querySelector('.grid-ui__anchor--start') as HTMLButtonElement; const gridLayer = overlay.querySelector('.grid-ui__layer') as HTMLElement; @@ -131,7 +137,7 @@ describe('visibility toggle', () => { }); it('persists the change to chrome.storage.sync after the debounce delay', async () => { - const { chromeMock, getStoredSettings } = await loadContentScript(); + const { chromeMock, getStoredSettings } = await loadContentScript({ enabled: true }); vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout'] }); const overlay = getOverlay(); @@ -149,7 +155,7 @@ describe('visibility toggle', () => { describe('adjust popover', () => { it('opens on trigger click and closes when clicked again', async () => { - await loadContentScript(); + await loadContentScript({ enabled: true }); const overlay = getOverlay(); const adjustTrigger = overlay.querySelector('.grid-ui__anchor--center') as HTMLButtonElement; const popover = overlay.querySelector('[data-popover="adjust"]') as HTMLElement; @@ -166,7 +172,7 @@ describe('adjust popover', () => { describe('pattern picker', () => { it('lists all variations and defaults regardless of the active axis', async () => { - await loadContentScript(); + await loadContentScript({ enabled: true }); const overlay = getOverlay(); const adjustTrigger = overlay.querySelector('.grid-ui__anchor--center') as HTMLButtonElement; const patternTrigger = overlay.querySelector('.grid-ui__pattern-trigger') as HTMLButtonElement; @@ -202,7 +208,7 @@ describe('pattern picker', () => { }); it('applies defaults onto the active variation and can snapshot a new version', async () => { - const { getStoredSettings } = await loadContentScript(); + const { getStoredSettings } = await loadContentScript({ enabled: true }); const overlay = getOverlay(); const adjustTrigger = overlay.querySelector('.grid-ui__anchor--center') as HTMLButtonElement; const patternTrigger = overlay.querySelector('.grid-ui__pattern-trigger') as HTMLButtonElement; @@ -241,7 +247,7 @@ describe('pattern picker', () => { describe('measurement controls', () => { it('updates the count and the rendered grid when the count slider changes', async () => { - await loadContentScript(); + await loadContentScript({ enabled: true }); const overlay = getOverlay(); const countRange = overlay.querySelector('.grid-ui__field--slider input[min="1"][max="24"]') as HTMLInputElement; @@ -253,7 +259,7 @@ describe('measurement controls', () => { }); it('hides the size field for stretch and shows it for a fixed distribution', async () => { - await loadContentScript(); + await loadContentScript({ enabled: true }); const overlay = getOverlay(); const sizeField = overlay.querySelector('.grid-ui__field--slider--color') ?.parentElement?.querySelectorAll('label')[1] as HTMLLabelElement | undefined; @@ -272,7 +278,7 @@ describe('measurement controls', () => { describe('axis switching', () => { it('resets the distribution and re-renders the grid for the new axis', async () => { - const { getStoredSettings } = await loadContentScript(); + const { getStoredSettings } = await loadContentScript({ enabled: true }); const overlay = getOverlay(); const rowsOption = overlay.querySelector('[data-axis="rows"]') as HTMLButtonElement; @@ -298,7 +304,7 @@ describe('axis switching', () => { describe('disabling', () => { it('removes the overlay from the DOM and persists enabled:false immediately when closed', async () => { - const { chromeMock, getStoredSettings } = await loadContentScript(); + const { chromeMock, getStoredSettings } = await loadContentScript({ enabled: true }); const overlay = getOverlay(); const closeTrigger = overlay.querySelector('.grid-ui__close') as HTMLButtonElement; @@ -313,12 +319,12 @@ describe('disabling', () => { describe('background/popup messaging', () => { it('re-renders when a GRID_SETTINGS_UPDATED message arrives', async () => { - const { emitMessage } = await loadContentScript(); + const { emitMessage } = await loadContentScript({ enabled: true }); const overlay = getOverlay(); emitMessage({ type: GRID_MESSAGE_TYPE, - settings: { ...DEFAULT_SETTINGS, axis: 'grid', size: 70 }, + settings: { ...DEFAULT_SETTINGS, enabled: true, axis: 'grid', size: 70 }, }); const frame = (overlay.querySelector('.grid-ui__layer') as HTMLElement).firstElementChild as HTMLElement; @@ -326,12 +332,12 @@ describe('background/popup messaging', () => { }); it('shows only size and color controls in grid mode', async () => { - const { emitMessage } = await loadContentScript(); + const { emitMessage } = await loadContentScript({ enabled: true }); const overlay = getOverlay(); emitMessage({ type: GRID_MESSAGE_TYPE, - settings: { ...DEFAULT_SETTINGS, axis: 'grid', size: 70 }, + settings: { ...DEFAULT_SETTINGS, enabled: true, axis: 'grid', size: 70 }, }); const adjustTrigger = overlay.querySelector('.grid-ui__anchor--center') as HTMLButtonElement; @@ -359,7 +365,7 @@ describe('background/popup messaging', () => { }); it('ignores messages with an unrelated type', async () => { - const { emitMessage } = await loadContentScript(); + const { emitMessage } = await loadContentScript({ enabled: true }); const overlay = getOverlay(); const frameBefore = (overlay.querySelector('.grid-ui__layer') as HTMLElement).firstElementChild as HTMLElement; const childCountBefore = frameBefore.children.length; @@ -373,7 +379,7 @@ describe('background/popup messaging', () => { describe('controller drag', () => { it('adds and removes dragging class during pointer interaction', async () => { - await loadContentScript(); + await loadContentScript({ enabled: true }); const overlay = getOverlay(); const controller = overlay.querySelector('.grid-ui__controller') as HTMLElement; diff --git a/src/site-patterns.ts b/src/site-patterns.ts index 639a91c..cd88e35 100644 --- a/src/site-patterns.ts +++ b/src/site-patterns.ts @@ -219,6 +219,19 @@ function normalizeSession( }; } +function mergeSessionSettings( + settings: GridSettings, + siteState: SiteGridState, +): GridSettings { + return normalizeSettings({ + ...settings, + enabled: siteState.session?.enabled ?? settings.enabled, + visible: siteState.session?.visible ?? settings.visible, + toolbarX: siteState.session?.toolbarX ?? settings.toolbarX, + toolbarY: siteState.session?.toolbarY ?? settings.toolbarY, + }); +} + function mergePresetPattern( pattern: GridPattern, siteState: SiteGridState, @@ -227,19 +240,13 @@ function mergePresetPattern( color: DEFAULT_SETTINGS.color, opacity: DEFAULT_SETTINGS.opacity, }; - const session: Partial> = - siteState.session ?? {}; return { ...pattern, - settings: normalizeSettings({ - ...pattern.settings, - ...appearance, - enabled: session.enabled ?? DEFAULT_SETTINGS.enabled, - visible: session.visible ?? DEFAULT_SETTINGS.visible, - toolbarX: session.toolbarX ?? DEFAULT_SETTINGS.toolbarX, - toolbarY: session.toolbarY ?? DEFAULT_SETTINGS.toolbarY, - }), + settings: mergeSessionSettings( + normalizeSettings({ ...pattern.settings, ...appearance }), + siteState, + ), }; } @@ -400,7 +407,10 @@ export function getActivePattern(siteState: SiteGridState): GridPattern { return mergePresetPattern(pattern, siteState); } - return pattern; + return { + ...pattern, + settings: mergeSessionSettings(pattern.settings, siteState), + }; } export function getPatternsForAxis( @@ -448,7 +458,6 @@ export function selectPattern(siteState: SiteGridState, patternId: string): Site ...siteState, activePatternId: patternId, appearance: undefined, - session: undefined, }; } @@ -458,13 +467,20 @@ export function ensureAxisPattern(siteState: SiteGridState, axis: GridAxis): Sit return selectPattern(siteState, existingVariation.id); } + const currentSettings = getActivePattern(siteState).settings; const template = getFirstPresetForAxis(siteState, axis)?.settings ?? { ...DEFAULT_SETTINGS, axis }; - const nextPattern = createVariationPattern(siteState.patterns, template); + const nextPattern = createVariationPattern(siteState.patterns, { + ...template, + enabled: currentSettings.enabled, + visible: currentSettings.visible, + toolbarX: currentSettings.toolbarX, + toolbarY: currentSettings.toolbarY, + }); return { activePatternId: nextPattern.id, patterns: [nextPattern, ...siteState.patterns], appearance: undefined, - session: undefined, + session: siteState.session, }; } @@ -473,30 +489,30 @@ export function updateActivePatternSettings( settings: GridSettings, ): SiteGridState { const normalized = normalizeSettings(settings); + const currentSettings = getActivePattern(siteState).settings; + + if (!patternSettingsChanged(currentSettings, normalized)) { + return { + ...siteState, + session: { + enabled: normalized.enabled, + visible: normalized.visible, + toolbarX: normalized.toolbarX, + toolbarY: normalized.toolbarY, + }, + }; + } + const rawActive = siteState.patterns.find((pattern) => pattern.id === siteState.activePatternId); if (rawActive?.kind === 'preset') { - const currentSettings = getActivePattern(siteState).settings; - - if (!patternSettingsChanged(currentSettings, normalized)) { - return { - ...siteState, - session: { - enabled: normalized.enabled, - visible: normalized.visible, - toolbarX: normalized.toolbarX, - toolbarY: normalized.toolbarY, - }, - }; - } - const nextPattern = createVariationPattern(siteState.patterns, normalized); return { ...siteState, activePatternId: nextPattern.id, patterns: [nextPattern, ...siteState.patterns], appearance: undefined, - session: undefined, + session: siteState.session, }; } @@ -505,7 +521,7 @@ export function updateActivePatternSettings( ...ensuredState, activePatternId: getActivePattern(ensuredState).id, appearance: undefined, - session: undefined, + session: siteState.session, patterns: ensuredState.patterns.map((pattern) => pattern.id === ensuredState.activePatternId ? { @@ -537,7 +553,12 @@ export function applyPatternSelection(siteState: SiteGridState, patternId: strin color: currentSettings.color, opacity: currentSettings.opacity, }, - session: siteState.session, + session: siteState.session ?? { + enabled: currentSettings.enabled, + visible: currentSettings.visible, + toolbarX: currentSettings.toolbarX, + toolbarY: currentSettings.toolbarY, + }, }; } diff --git a/src/utils.ts b/src/utils.ts index 94605b7..7d64bdb 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -36,7 +36,7 @@ const MIN_SPACING = 0; const MAX_SPACING = 240; export const DEFAULT_SETTINGS: GridSettings = { - enabled: true, + enabled: false, visible: true, toolbarX: null, toolbarY: null,