import { expect, fixture, html, elementUpdated } from '@open-wc/testing'; import './nile-badge'; import NileBadge from './nile-badge'; describe('NileBadge', () => { // === RENDERING === it('1. should render without errors', async () => { const el = await fixture(html``); expect(el).to.exist; }); it('2. should have a shadow root', async () => { const el = await fixture(html``); expect(el.shadowRoot).to.not.be.null; }); it('3. should render a span as base element', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span).to.exist; }); it('4. should render slot content', async () => { const el = await fixture(html`Badge Text`); expect(el.textContent!.trim()).to.equal('Badge Text'); }); it('5. should render default slot', async () => { const el = await fixture(html``); const slot = el.shadowRoot!.querySelector('slot'); expect(slot).to.exist; }); // === DEFAULT PROPERTIES === it('6. should have variant default to normal', async () => { const el = await fixture(html``); expect(el.variant).to.equal('normal'); }); it('7. should have rounded default to false', async () => { const el = await fixture(html``); expect(el.rounded).to.be.false; }); it('8. should have pilltype default to badge-color', async () => { const el = await fixture(html``); expect(el.pilltype).to.equal('badge-color'); }); // === VARIANT TESTS === it('9. should apply primary variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--primary')).to.be.true; }); it('10. should apply success variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--success')).to.be.true; }); it('11. should apply normal variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--normal')).to.be.true; }); it('12. should apply warning variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--warning')).to.be.true; }); it('13. should apply error variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--error')).to.be.true; }); it('14. should apply info variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--info')).to.be.true; }); it('15. should apply gray variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--gray')).to.be.true; }); it('16. should apply brand variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--brand')).to.be.true; }); it('17. should apply blue-light variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--blue-light')).to.be.true; }); it('18. should apply blue variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--blue')).to.be.true; }); it('19. should apply indigo variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--indigo')).to.be.true; }); it('20. should apply purple variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--purple')).to.be.true; }); it('21. should apply pink variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--pink')).to.be.true; }); it('22. should apply orange variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--orange')).to.be.true; }); it('23. should apply gray-blue variant class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--gray-blue')).to.be.true; }); it('24. should reflect variant attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('success'); }); // === ROUNDED === it('25. should apply rounded class when rounded is true', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('26. should not apply rounded class when rounded is false', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--rounded')).to.be.false; }); it('27. should reflect rounded attribute', async () => { const el = await fixture(html``); expect(el.hasAttribute('rounded')).to.be.true; }); // === PILLTYPE === it('28. should apply badge-color pilltype class by default', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--badge-color')).to.be.true; }); it('29. should apply pill-outline pilltype class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--pill-outline')).to.be.true; }); it('30. should apply pill-color pilltype class', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('31. should auto-round when pilltype is pill-outline', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('32. should auto-round when pilltype is pill-color', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('33. should reflect pilltype attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('pilltype')).to.equal('pill-outline'); }); // === CSS PARTS === it('34. should have base part', async () => { const el = await fixture(html``); const base = el.shadowRoot!.querySelector('[part~="base"]'); expect(base).to.exist; }); it('35. should have content part', async () => { const el = await fixture(html``); const content = el.shadowRoot!.querySelector('[part~="content"]'); expect(content).to.exist; }); // === DYNAMIC PROPERTY CHANGES === it('36. should update variant dynamically', async () => { const el = await fixture(html``); el.variant = 'success'; await el.updateComplete; const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--success')).to.be.true; }); it('37. should update rounded dynamically', async () => { const el = await fixture(html``); el.rounded = true; await el.updateComplete; const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('38. should update pilltype dynamically', async () => { const el = await fixture(html``); el.pilltype = 'pill-outline'; await el.updateComplete; const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--pill-outline')).to.be.true; }); // === CLASS COMBINATIONS === it('39. should have badge class always', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge')).to.be.true; }); it('40. should handle variant + rounded', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--error')).to.be.true; expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('41. should handle variant + pilltype', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--success')).to.be.true; expect(span!.classList.contains('badge--pill-outline')).to.be.true; }); it('42. should handle all properties together', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--warning')).to.be.true; expect(span!.classList.contains('badge--rounded')).to.be.true; expect(span!.classList.contains('badge--pill-outline')).to.be.true; }); // === ALL VARIANTS CLASS VERIFICATION === it('43. should not have other variant classes when primary', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--primary')).to.be.true; expect(span!.classList.contains('badge--success')).to.be.false; expect(span!.classList.contains('badge--error')).to.be.false; }); it('44. should switch variant classes on change', async () => { const el = await fixture(html``); el.variant = 'error'; await el.updateComplete; const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--error')).to.be.true; expect(span!.classList.contains('badge--primary')).to.be.false; }); // === CONTENT RENDERING === it('45. should render HTML content in slot', async () => { const el = await fixture(html`Bold`); const strong = el.querySelector('strong'); expect(strong).to.exist; expect(strong!.textContent).to.equal('Bold'); }); it('46. should render multiple elements in slot', async () => { const el = await fixture(html`AB`); const spans = el.querySelectorAll('span'); expect(spans.length).to.equal(2); }); it('47. should handle empty content', async () => { const el = await fixture(html``); expect(el.textContent!.trim()).to.equal(''); }); // === BADGE CLASS === it('48. should have badge__content class on slot', async () => { const el = await fixture(html``); const contentSlot = el.shadowRoot!.querySelector('.badge__content'); expect(contentSlot).to.exist; }); // === REPEATED UPDATES === it('49. should handle multiple variant changes', async () => { const el = await fixture(html``); const variants: Array<'primary' | 'success' | 'error' | 'warning' | 'info'> = ['primary', 'success', 'error', 'warning', 'info']; for (const v of variants) { el.variant = v; await el.updateComplete; const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains(`badge--${v}`)).to.be.true; } }); it('50. should handle toggling rounded', async () => { const el = await fixture(html``); el.rounded = true; await el.updateComplete; let span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--rounded')).to.be.true; el.rounded = false; await el.updateComplete; span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--rounded')).to.be.false; }); // === ADDITIONAL VARIANT COMBINATIONS === it('51. primary variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('primary'); }); it('52. success variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('success'); }); it('53. normal variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('normal'); }); it('54. warning variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('warning'); }); it('55. error variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('error'); }); it('56. info variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('info'); }); it('57. gray variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('gray'); }); it('58. brand variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('brand'); }); it('59. blue-light variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('blue-light'); }); it('60. blue variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('blue'); }); it('61. indigo variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('indigo'); }); it('62. purple variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('purple'); }); it('63. pink variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('pink'); }); it('64. orange variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('orange'); }); it('65. gray-blue variant reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('variant')).to.equal('gray-blue'); }); // === PILLTYPE VARIATIONS === it('66. badge-color pilltype reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('pilltype')).to.equal('badge-color'); }); it('67. pill-outline pilltype reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('pilltype')).to.equal('pill-outline'); }); it('68. pill-color pilltype reflects attribute', async () => { const el = await fixture(html``); expect(el.getAttribute('pilltype')).to.equal('pill-color'); }); // === DYNAMIC PILLTYPE UPDATES === it('69. should switch from badge-color to pill-outline', async () => { const el = await fixture(html``); el.pilltype = 'pill-outline'; await el.updateComplete; const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--pill-outline')).to.be.true; expect(span!.classList.contains('badge--badge-color')).to.be.false; }); it('70. should switch from pill-outline to pill-color', async () => { const el = await fixture(html``); el.pilltype = 'pill-color'; await el.updateComplete; const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--pill-outline')).to.be.false; }); // === EACH VARIANT WITH ROUNDED === it('71. primary variant with rounded', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--primary')).to.be.true; expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('72. success variant with rounded', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--success')).to.be.true; expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('73. error variant with rounded', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--error')).to.be.true; expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('74. warning variant with rounded', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--warning')).to.be.true; expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('75. info variant with rounded', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--info')).to.be.true; expect(span!.classList.contains('badge--rounded')).to.be.true; }); // === EACH VARIANT WITH PILL-OUTLINE === it('76. primary with pill-outline', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--primary')).to.be.true; expect(span!.classList.contains('badge--pill-outline')).to.be.true; expect(span!.classList.contains('badge--rounded')).to.be.true; }); it('77. success with pill-outline', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--success')).to.be.true; expect(span!.classList.contains('badge--pill-outline')).to.be.true; }); it('78. error with pill-outline', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--error')).to.be.true; expect(span!.classList.contains('badge--pill-outline')).to.be.true; }); it('79. warning with pill-outline', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--warning')).to.be.true; expect(span!.classList.contains('badge--pill-outline')).to.be.true; }); it('80. info with pill-outline', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--info')).to.be.true; expect(span!.classList.contains('badge--pill-outline')).to.be.true; }); // === EACH VARIANT WITH BADGE-COLOR === it('81. primary with badge-color', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--primary')).to.be.true; expect(span!.classList.contains('badge--badge-color')).to.be.true; }); it('82. success with badge-color', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--success')).to.be.true; expect(span!.classList.contains('badge--badge-color')).to.be.true; }); it('83. blue with badge-color', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--blue')).to.be.true; expect(span!.classList.contains('badge--badge-color')).to.be.true; }); it('84. indigo with badge-color', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--indigo')).to.be.true; expect(span!.classList.contains('badge--badge-color')).to.be.true; }); it('85. purple with badge-color', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--purple')).to.be.true; expect(span!.classList.contains('badge--badge-color')).to.be.true; }); // === MULTIPLE DYNAMIC UPDATES === it('86. should cycle through all pilltypes', async () => { const el = await fixture(html``); const pilltypes: Array<'badge-color' | 'pill-outline' | 'pill-color'> = ['badge-color', 'pill-outline', 'pill-color']; for (const pt of pilltypes) { el.pilltype = pt; await el.updateComplete; expect(el.pilltype).to.equal(pt); } }); it('87. should handle setting variant to each value', async () => { const el = await fixture(html``); const variants: Array<'primary' | 'success' | 'normal' | 'warning' | 'error' | 'info' | 'gray' | 'brand'> = ['primary', 'success', 'normal', 'warning', 'error', 'info', 'gray', 'brand']; for (const v of variants) { el.variant = v; await el.updateComplete; const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains(`badge--${v}`)).to.be.true; } }); // === SLOT STRUCTURE === it('88. slot should be inside span', async () => { const el = await fixture(html``); const span = el.shadowRoot!.querySelector('span'); const slot = span!.querySelector('slot'); expect(slot).to.exist; }); // === ELEMENT INSTANCE === it('89. should be instance of NileBadge', async () => { const el = await fixture(html``); expect(el).to.be.instanceOf(NileBadge); }); it('90. should have correct tag name', async () => { const el = await fixture(html``); expect(el.tagName.toLowerCase()).to.equal('nile-badge'); }); // === ATTRIBUTE SETTING === it('91. should set variant via setAttribute', async () => { const el = await fixture(html``); el.setAttribute('variant', 'error'); await el.updateComplete; expect(el.variant).to.equal('error'); }); it('92. should set rounded via setAttribute', async () => { const el = await fixture(html``); el.setAttribute('rounded', ''); await el.updateComplete; expect(el.rounded).to.be.true; }); it('93. should remove rounded attribute', async () => { const el = await fixture(html``); el.removeAttribute('rounded'); await el.updateComplete; expect(el.rounded).to.be.false; }); it('94. should set pilltype via setAttribute', async () => { const el = await fixture(html``); el.setAttribute('pilltype', 'pill-outline'); await el.updateComplete; expect(el.pilltype).to.equal('pill-outline'); }); // === STYLES === it('95. should have static styles', async () => { expect(NileBadge.styles).to.exist; }); // === RENDERING STRESS === it('96. should render consistently after multiple rapid updates', async () => { const el = await fixture(html``); el.variant = 'primary'; el.variant = 'success'; el.variant = 'error'; await el.updateComplete; const span = el.shadowRoot!.querySelector('span'); expect(span!.classList.contains('badge--error')).to.be.true; }); it('97. should render long text content', async () => { const longText = 'A'.repeat(1000); const el = await fixture(html`${longText}`); expect(el.textContent!.trim()).to.equal(longText); }); it('98. should render special characters', async () => { const el = await fixture(html`<script>`); expect(el.textContent).to.contain('