UNPKG

@zeix/ui-element

Version:

UIElement - a HTML-first library for reactive Web Components

367 lines (290 loc) 10.2 kB
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Input Checkbox Component Tests</title> </head> <body> <!-- Test fixtures --> <form-checkbox id="test1"> <label> <input type="checkbox" /> <span class="label">Default Checkbox</span> </label> </form-checkbox> <form-checkbox id="test2" checked> <label> <input type="checkbox" checked /> <span class="label">Pre-checked</span> </label> </form-checkbox> <form-checkbox id="test3" class="todo"> <label> <input type="checkbox" class="visually-hidden" /> <span class="label">Task Item</span> </label> </form-checkbox> <form-checkbox id="test4"> <label> <input type="checkbox" /> <span class="label">Required Task</span> </label> </form-checkbox> <script type="module"> import { runTests } from '@web/test-runner-mocha' import { assert } from '@esm-bundle/chai' import '../../../docs/assets/main.js' // Built components bundle const wait = ms => new Promise(resolve => setTimeout(resolve, ms)) const animationFrame = () => new Promise(requestAnimationFrame) const microtask = () => new Promise(queueMicrotask) const tick = async () => { await animationFrame() // Wait for effects to execute await microtask() // Wait for DOM to reflect changes } // Helper to simulate checkbox click const clickCheckbox = async checkbox => { checkbox.click() await tick() } // Helper to reset checkbox component state const resetCheckbox = async el => { el.label = '' const input = el.querySelector('input') if (el.checked && input) { input.click() } await tick() } runTests(() => { describe('Input Checkbox Component', () => { beforeEach(async () => { // Reset all test components before each test const testIds = ['test1', 'test2', 'test3', 'test4'] for (const id of testIds) { const el = document.getElementById(id) if (el) await resetCheckbox(el) } }) it('should verify component exists and has expected structure', () => { const el = document.getElementById('test1') assert.isNotNull(el) assert.equal(el.tagName.toLowerCase(), 'form-checkbox') // Check for required elements const input = el.querySelector('input') const label = el.querySelector('.label') assert.isNotNull(input) assert.equal(input.type, 'checkbox') assert.isNotNull(label) // Check initial properties exist assert.isDefined(el.checked) assert.isDefined(el.label) }) it('should initialize with correct default state', async () => { const el = document.getElementById('test1') const input = el.querySelector('input') await tick() assert.equal(el.checked, false) assert.equal(el.label, '') assert.equal(input.checked, false) assert.isFalse(el.hasAttribute('checked')) }) it('should handle checked state correctly', async () => { const el = document.getElementById('test1') const input = el.querySelector('input') await tick() // Initially should not be checked assert.equal(el.checked, false) assert.equal(input.checked, false) // Setting property should sync both await clickCheckbox(input) assert.equal(el.checked, true) assert.equal(input.checked, true) assert.isTrue(el.hasAttribute('checked')) }) it('should not allow to set checked programmatically', async () => { const el = document.getElementById('test1') const input = el.querySelector('input') assert.throws(() => { el.checked = true }, TypeError) }) it('should sync label property to label element', async () => { const el = document.getElementById('test1') const labelEl = el.querySelector('.label') // Set label programmatically el.label = 'New Label Text' await tick() assert.equal(labelEl.textContent, 'New Label Text') // Clear label el.label = '' await tick() assert.equal(labelEl.textContent, '') }) it('should handle input change events', async () => { const el = document.getElementById('test1') const input = el.querySelector('input') // Initially unchecked assert.equal(el.checked, false) // Click the input await clickCheckbox(input) assert.equal(el.checked, true) assert.equal(input.checked, true) assert.isTrue(el.hasAttribute('checked')) // Click again to uncheck await clickCheckbox(input) assert.equal(el.checked, false) assert.equal(input.checked, false) assert.isFalse(el.hasAttribute('checked')) }) it('should handle string label values correctly', async () => { const el = document.getElementById('test1') const labelEl = el.querySelector('.label') // Test various string values el.label = 'Simple task' await tick() assert.equal(labelEl.textContent, 'Simple task') el.label = '123 items' await tick() assert.equal(labelEl.textContent, '123 items') el.label = 'Special chars: !@#$%' await tick() assert.equal( labelEl.textContent, 'Special chars: !@#$%', ) // Test number conversion el.label = 42 await tick() assert.equal(labelEl.textContent, '42') }) it('should work with visually hidden checkbox', async () => { const el = document.getElementById('test3') const input = el.querySelector('input') const labelEl = el.querySelector('.label') assert.isTrue( input.classList.contains('visually-hidden'), ) // Should work normally despite being visually hidden if (!el.checked) clickCheckbox(input) el.label = 'Hidden Checkbox' await tick() assert.equal(input.checked, true) assert.equal(labelEl.textContent, 'Hidden Checkbox') assert.isTrue(el.hasAttribute('checked')) }) it('should handle rapid property changes', async () => { const el = document.getElementById('test1') const input = el.querySelector('input') const labelEl = el.querySelector('.label') // Rapid changes for (let i = 0; i < 5; i++) { input.click() el.label = `Task ${i}` } await tick() // Should have final values (i=4, 4%2===0 is true) assert.equal(input.checked, true) assert.equal(labelEl.textContent, 'Task 4') assert.equal(el.checked, true) }) it('should handle keyboard interactions', async () => { const el = document.getElementById('test1') const input = el.querySelector('input') // Focus the input input.focus() // Simulate space key press const spaceEvent = new KeyboardEvent('keydown', { key: ' ', code: 'Space', bubbles: true, cancelable: true, }) input.dispatchEvent(spaceEvent) // Simulate space key release (which triggers the change) const spaceUpEvent = new KeyboardEvent('keyup', { key: ' ', code: 'Space', bubbles: true, }) input.dispatchEvent(spaceUpEvent) // The actual change depends on browser behavior // We just ensure no errors occur await tick() }) it('should handle RESET values correctly', async () => { const el = document.getElementById('test1') const labelEl = el.querySelector('.label') // Set initial value el.label = 'Initial Label' await tick() assert.equal(labelEl.textContent, 'Initial Label') // Reset to original DOM content (RESET behavior) el.label = '' await tick() // Should be empty (since our test fixture starts empty) assert.equal(labelEl.textContent, '') }) it('should handle form submission behavior', async () => { const el = document.getElementById('test1') const input = el.querySelector('input') // Set name and value for form behavior input.name = 'testCheckbox' input.value = 'testValue' // Check the checkbox await clickCheckbox(input) // Should have form data when checked assert.equal(input.checked, true) assert.equal(input.name, 'testCheckbox') assert.equal(input.value, 'testValue') // Uncheck await clickCheckbox(input) // Should not have form data when unchecked assert.equal(input.checked, false) }) it('should handle change event bubbling', async () => { const el = document.getElementById('test1') const input = el.querySelector('input') let changeEventFired = false el.addEventListener('change', () => { changeEventFired = true }) // Trigger change via input await clickCheckbox(input) assert.isTrue(changeEventFired) assert.equal(el.checked, true) }) it('should handle indeterminate state', async () => { const el = document.getElementById('test1') const input = el.querySelector('input') // Set indeterminate state input.indeterminate = true // Component should still handle checked property normally await clickCheckbox(input) assert.equal(input.checked, true) // Indeterminate state should be preserved until input changes // assert.isTrue(input.indeterminate) }) it('should handle mixed state scenarios', async () => { const el = document.getElementById('test1') const input = el.querySelector('input') const labelEl = el.querySelector('.label') // Scenario: Start unchecked with label el.label = 'Todo Item' await tick() assert.equal(el.checked, false) assert.equal(labelEl.textContent, 'Todo Item') // Check it await clickCheckbox(input) assert.equal(el.checked, true) assert.equal(labelEl.textContent, 'Todo Item') // Change label while checked el.label = 'Completed Item' await tick() assert.equal(el.checked, true) assert.equal(labelEl.textContent, 'Completed Item') }) }) }) </script> </body> </html>