import { expect, fixture, html } from '@open-wc/testing';
import '@lion/checkbox-group/define';
/**
* @typedef {import('../src/LionCheckboxIndeterminate').LionCheckboxIndeterminate} LionCheckboxIndeterminate
* @typedef {import('../src/LionCheckboxGroup').LionCheckboxGroup} LionCheckboxGroup
*/
/**
* @param {LionCheckboxIndeterminate} el
*/
function getProtectedMembers(el) {
return {
// @ts-ignore
subCheckboxes: el._subCheckboxes,
};
}
describe('', () => {
it('should have type = checkbox', async () => {
// Arrange
const el = await fixture(html`
`);
// Assert
expect(el.getAttribute('type')).to.equal('checkbox');
});
it('should not be indeterminate by default if all children are unchecked', async () => {
// Arrange
const el = await fixture(html`
`);
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'lion-checkbox-indeterminate',
));
// Assert
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
});
it('should be indeterminate if one child is checked', async () => {
// Arrange
const el = /** @type {LionCheckboxGroup} */ await fixture(html`
`);
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'lion-checkbox-indeterminate',
));
// Assert
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.true;
});
it('should be checked if all children are checked', async () => {
// Arrange
const el = /** @type {LionCheckboxGroup} */ (await fixture(html`
`));
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'lion-checkbox-indeterminate',
));
// Assert
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
expect(elIndeterminate?.checked).to.be.true;
});
it('should become indeterminate if one child is checked', async () => {
// Arrange
const el = /** @type {LionCheckboxGroup} */ (await fixture(html`
`));
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'lion-checkbox-indeterminate',
));
const { subCheckboxes } = getProtectedMembers(elIndeterminate);
// Act
subCheckboxes[0].checked = true;
await el.updateComplete;
// Assert
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.true;
});
it('should become checked if all children are checked', async () => {
// Arrange
const el = /** @type {LionCheckboxGroup} */ (await fixture(html`
`));
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'lion-checkbox-indeterminate',
));
const { subCheckboxes } = getProtectedMembers(elIndeterminate);
// Act
subCheckboxes[0].checked = true;
subCheckboxes[1].checked = true;
subCheckboxes[2].checked = true;
await el.updateComplete;
// Assert
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
expect(elIndeterminate?.checked).to.be.true;
});
it('should sync all children when parent is checked (from indeterminate to checked)', async () => {
// Arrange
const el = /** @type {LionCheckboxGroup} */ (await fixture(html`
`));
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'lion-checkbox-indeterminate',
));
// Act
elIndeterminate._inputNode.click();
await elIndeterminate.updateComplete;
const { subCheckboxes } = getProtectedMembers(elIndeterminate);
// Assert
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.false;
expect(subCheckboxes[0].hasAttribute('checked')).to.be.true;
expect(subCheckboxes[1].hasAttribute('checked')).to.be.true;
expect(subCheckboxes[2].hasAttribute('checked')).to.be.true;
});
it('should sync all children when parent is checked (from unchecked to checked)', async () => {
// Arrange
const el = /** @type {LionCheckboxGroup} */ (await fixture(html`
`));
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'lion-checkbox-indeterminate',
));
// Act
elIndeterminate._inputNode.click();
await elIndeterminate.updateComplete;
const { subCheckboxes } = getProtectedMembers(elIndeterminate);
// Assert
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.false;
expect(subCheckboxes[0].hasAttribute('checked')).to.be.true;
expect(subCheckboxes[1].hasAttribute('checked')).to.be.true;
expect(subCheckboxes[2].hasAttribute('checked')).to.be.true;
});
it('should sync all children when parent is checked (from checked to unchecked)', async () => {
// Arrange
const el = /** @type {LionCheckboxGroup} */ (await fixture(html`
`));
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'lion-checkbox-indeterminate',
));
// Act
elIndeterminate._inputNode.click();
await elIndeterminate.updateComplete;
const elProts = getProtectedMembers(elIndeterminate);
// Assert
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
expect(elProts.subCheckboxes[0].hasAttribute('checked')).to.be.false;
expect(elProts.subCheckboxes[1].hasAttribute('checked')).to.be.false;
expect(elProts.subCheckboxes[2].hasAttribute('checked')).to.be.false;
});
it('should work as expected with siblings checkbox-indeterminate', async () => {
// Arrange
const el = /** @type {LionCheckboxGroup} */ (await fixture(html`
`));
const elFirstIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'#first-checkbox-indeterminate',
));
const elSecondIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'#second-checkbox-indeterminate',
));
// Act - check the first sibling
elFirstIndeterminate._inputNode.click();
await elFirstIndeterminate.updateComplete;
await elSecondIndeterminate.updateComplete;
const elFirstSubCheckboxes = getProtectedMembers(elFirstIndeterminate);
const elSecondSubCheckboxes = getProtectedMembers(elSecondIndeterminate);
// Assert - the second sibling should not be affected
expect(elFirstIndeterminate.hasAttribute('indeterminate')).to.be.false;
expect(elFirstSubCheckboxes.subCheckboxes[0].hasAttribute('checked')).to.be.true;
expect(elFirstSubCheckboxes.subCheckboxes[1].hasAttribute('checked')).to.be.true;
expect(elFirstSubCheckboxes.subCheckboxes[2].hasAttribute('checked')).to.be.true;
expect(elSecondSubCheckboxes.subCheckboxes[0].hasAttribute('checked')).to.be.false;
expect(elSecondSubCheckboxes.subCheckboxes[1].hasAttribute('checked')).to.be.false;
});
it('should work as expected with nested indeterminate checkboxes', async () => {
// Arrange
const el = /** @type {LionCheckboxGroup} */ (await fixture(html`
`));
const elNestedIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'#nested-checkbox-indeterminate',
));
const elParentIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'#parent-checkbox-indeterminate',
));
const elNestedSubCheckboxes = getProtectedMembers(elNestedIndeterminate);
const elParentSubCheckboxes = getProtectedMembers(elParentIndeterminate);
// Act - check a nested checkbox
if (elNestedIndeterminate) {
elNestedSubCheckboxes.subCheckboxes[0]._inputNode.click();
}
await el.updateComplete;
// Assert
expect(elNestedIndeterminate?.hasAttribute('indeterminate')).to.be.true;
expect(elParentIndeterminate?.hasAttribute('indeterminate')).to.be.true;
// Act - check all nested checkbox
if (elNestedIndeterminate) elNestedSubCheckboxes.subCheckboxes[1]._inputNode.click();
if (elNestedIndeterminate) elNestedSubCheckboxes.subCheckboxes[2]._inputNode.click();
await el.updateComplete;
// Assert
expect(elNestedIndeterminate?.hasAttribute('checked')).to.be.true;
expect(elNestedIndeterminate?.hasAttribute('indeterminate')).to.be.false;
expect(elParentIndeterminate?.hasAttribute('checked')).to.be.false;
expect(elParentIndeterminate?.hasAttribute('indeterminate')).to.be.true;
// Act - finally check all remaining checkbox
if (elParentIndeterminate) {
elParentSubCheckboxes.subCheckboxes[0]._inputNode.click();
}
if (elParentIndeterminate) {
elParentSubCheckboxes.subCheckboxes[1]._inputNode.click();
}
await el.updateComplete;
// Assert
expect(elNestedIndeterminate?.hasAttribute('checked')).to.be.true;
expect(elNestedIndeterminate?.hasAttribute('indeterminate')).to.be.false;
expect(elParentIndeterminate?.hasAttribute('checked')).to.be.true;
expect(elParentIndeterminate?.hasAttribute('indeterminate')).to.be.false;
});
it('should work as expected if extra html', async () => {
// Arrange
const el = /** @type {LionCheckboxGroup} */ (await fixture(html`
Let's have some fun
Hello I'm a div
useless div
absolutely useless
Too much fun, stop it !
`));
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (el.querySelector(
'lion-checkbox-indeterminate',
));
const { subCheckboxes } = getProtectedMembers(elIndeterminate);
// Act
subCheckboxes[0].checked = true;
subCheckboxes[1].checked = true;
subCheckboxes[2].checked = true;
await el.updateComplete;
// Assert
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
expect(elIndeterminate?.checked).to.be.true;
});
});