/* @vitest-environment jsdom */ import { describe, expect, it } from 'vitest'; import { calculateMobileKeyboardFocusShift, isEditableKeyboardTarget, } from './mobileViewportKeyboardFocus'; describe('isEditableKeyboardTarget', () => { it('matches controls that open the mobile keyboard', () => { const input = document.createElement('input'); input.type = 'text'; const textarea = document.createElement('textarea'); const buttonInput = document.createElement('input'); buttonInput.type = 'file'; expect(isEditableKeyboardTarget(input)).toBe(true); expect(isEditableKeyboardTarget(textarea)).toBe(true); expect(isEditableKeyboardTarget(buttonInput)).toBe(false); }); it('ignores disabled and readonly controls', () => { const disabledInput = document.createElement('input'); disabledInput.disabled = true; const readonlyInput = document.createElement('input'); readonlyInput.readOnly = true; expect(isEditableKeyboardTarget(disabledInput)).toBe(false); expect(isEditableKeyboardTarget(readonlyInput)).toBe(false); }); }); describe('calculateMobileKeyboardFocusShift', () => { it('moves a bottom input above the visible keyboard area', () => { expect( calculateMobileKeyboardFocusShift({ layoutHeight: 800, visualTop: 0, visualHeight: 500, targetTop: 720, targetBottom: 770, currentShift: 0, margin: 20, }), ).toBe(290); }); it('does not move when the focused input is already visible', () => { expect( calculateMobileKeyboardFocusShift({ layoutHeight: 800, visualTop: 0, visualHeight: 500, targetTop: 250, targetBottom: 300, currentShift: 0, margin: 20, }), ).toBe(0); }); it('caps movement to keyboard inset plus safety margin', () => { expect( calculateMobileKeyboardFocusShift({ layoutHeight: 800, visualTop: 0, visualHeight: 500, targetTop: 790, targetBottom: 860, currentShift: 0, margin: 20, maxExtraShift: 20, }), ).toBe(320); }); });