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('