Skip to content

Commit

Permalink
Merge branch 'refs/heads/main' into visual-regression-focus-next-try
Browse files Browse the repository at this point in the history
  • Loading branch information
jeripeierSBB committed May 27, 2024
2 parents be8cfeb + f3a8643 commit e746d4f
Show file tree
Hide file tree
Showing 9 changed files with 260 additions and 102 deletions.
1 change: 1 addition & 0 deletions .stylelintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"ignore": ["custom-properties"]
}
],
"no-descending-specificity": null,
"scss/comment-no-empty": null,
"scss/at-import-partial-extension": "always",
"property-no-vendor-prefix": [
Expand Down
2 changes: 2 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
comment: false
ignore:
- 'src/components/core/testing/**/*'
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
"sass": "1.77.2",
"sinon": "18.0.0",
"storybook": "8.1.3",
"stylelint": "16.5.0",
"stylelint": "16.6.0",
"stylelint-config-prettier-scss": "1.0.0",
"stylelint-config-standard-scss": "13.1.0",
"stylelint-scss": "6.3.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import '../radio-button.js';

import { SbbRadioButtonGroupElement } from './radio-button-group.js';

describe(`sbb-radio-button-group with ${fixture.name}`, () => {
describe(`sbb-radio-button-group`, () => {
let element: SbbRadioButtonGroupElement;

beforeEach(async () => {
element = await fixture(
html`
describe('events', () => {
beforeEach(async () => {
element = await fixture(html`
<sbb-radio-button-group value="Value one">
<sbb-radio-button id="sbb-radio-1" value="Value one">Value one</sbb-radio-button>
<sbb-radio-button id="sbb-radio-2" value="Value two">Value two</sbb-radio-button>
Expand All @@ -23,16 +23,13 @@ describe(`sbb-radio-button-group with ${fixture.name}`, () => {
>
<sbb-radio-button id="sbb-radio-4" value="Value four">Value four</sbb-radio-button>
</sbb-radio-button-group>
`,
{ modules: ['./radio-button-group.ts', '../radio-button.ts'] },
);
});
`);
});

it('renders', () => {
assert.instanceOf(element, SbbRadioButtonGroupElement);
});
it('renders', () => {
assert.instanceOf(element, SbbRadioButtonGroupElement);
});

describe('events', () => {
it('selects radio on click', async () => {
const firstRadio = element.querySelector('#sbb-radio-1') as SbbRadioButtonElement;
const radio = element.querySelector('#sbb-radio-2') as SbbRadioButtonElement;
Expand Down Expand Up @@ -161,4 +158,34 @@ describe(`sbb-radio-button-group with ${fixture.name}`, () => {
expect(firstRadio).to.have.attribute('checked');
});
});

describe('initialization', () => {
beforeEach(async () => {
element = await fixture(html`
<sbb-radio-button-group value="Value one">
<p>Other content</p>
</sbb-radio-button-group>
`);
});

it('should preserve value when no radios were slotted but slotchange was triggered', () => {
expect(element.value).to.equal('Value one');
});

it('should restore value when radios are slotted', async () => {
const radioOne = document.createElement('sbb-radio-button');
radioOne.value = 'Value one';

const radioTwo = document.createElement('sbb-radio-button');
radioTwo.value = 'Value two';

element.appendChild(radioTwo);
element.appendChild(radioOne);

await waitForLitRender(element);

expect(element.value).to.equal('Value one');
expect(radioOne).to.have.attribute('checked');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export class SbbRadioButtonGroupElement extends SbbDisabledMixin(LitElement) {

const radioButtons = this.radioButtons;

this.value = initValue ?? radioButtons.find((radio) => radio.checked)?.value;
this.value = initValue ?? radioButtons.find((radio) => radio.checked)?.value ?? this.value;

for (const radio of radioButtons) {
radio.checked = radio.value === this.value;
Expand Down
218 changes: 171 additions & 47 deletions src/components/radio-button/radio-button/radio-button.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,65 +6,189 @@ import { waitForCondition, waitForLitRender, EventSpy } from '../../core/testing

import { SbbRadioButtonElement } from './radio-button.js';

describe(`sbb-radio-button with ${fixture.name}`, () => {
describe(`sbb-radio-button`, () => {
let element: SbbRadioButtonElement;

beforeEach(async () => {
element = await fixture(html`<sbb-radio-button value="Value">Value label</sbb-radio-button>`, {
modules: ['./radio-button.ts'],
describe('general', () => {
beforeEach(async () => {
element = await fixture(html`<sbb-radio-button value="Value">Value label</sbb-radio-button>`);
});
});

it('renders', async () => {
assert.instanceOf(element, SbbRadioButtonElement);
});
it('renders', async () => {
assert.instanceOf(element, SbbRadioButtonElement);
});

it('should not render accessibility label about containing state', async () => {
element = element.shadowRoot!.querySelector('.sbb-screen-reader-only:not(input)')!;
expect(element).not.to.be.ok;
});
it('should have corresponding aria values set', async () => {
expect(element).to.have.attribute('aria-checked', 'false');
expect(element).to.have.attribute('aria-required', 'false');
expect(element).not.to.have.attribute('aria-disabled');
});

it('selects radio on click', async () => {
const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);
it('should update aria values', async () => {
element.checked = true;
element.required = true;
element.disabled = true;

element.click();
await waitForLitRender(element);
await waitForLitRender(element);

expect(element).to.have.attribute('checked');
await waitForCondition(() => stateChange.events.length === 1);
expect(stateChange.count).to.be.equal(1);
});
expect(element).to.have.attribute('aria-checked', 'true');
expect(element).to.have.attribute('aria-required', 'true');
expect(element).to.have.attribute('aria-disabled', 'true');
});

it('should not render accessibility label about containing state', async () => {
element = element.shadowRoot!.querySelector('.sbb-screen-reader-only:not(input)')!;
expect(element).not.to.be.ok;
});

it('selects radio on click', async () => {
const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);

element.click();
await waitForLitRender(element);

expect(element).to.have.attribute('checked');
await waitForCondition(() => stateChange.events.length === 1);
expect(stateChange.count).to.be.equal(1);
});

it('does not deselect radio if already checked', async () => {
const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);

element.click();
await waitForLitRender(element);
expect(element).to.have.attribute('checked');
await waitForCondition(() => stateChange.events.length === 1);
expect(stateChange.count).to.be.equal(1);

element.click();
await waitForLitRender(element);
expect(element).to.have.attribute('checked');
await waitForCondition(() => stateChange.events.length === 1);
expect(stateChange.count).to.be.equal(1);
});

it('allows empty selection', async () => {
const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);

element.allowEmptySelection = true;
element.click();
await waitForLitRender(element);
expect(element).to.have.attribute('checked');
await waitForCondition(() => stateChange.events.length === 1);
expect(stateChange.count).to.be.equal(1);

element.click();
await waitForLitRender(element);
expect(element).not.to.have.attribute('checked');
await waitForCondition(() => stateChange.events.length === 2);
expect(stateChange.count).to.be.equal(2);
});

it('should convert falsy checked to false', async () => {
element.checked = true;
(element.checked as any) = undefined;

await waitForLitRender(element);

expect(element.checked).to.equal(false);
expect(element).to.have.attribute('aria-checked', 'false');
});

it('should convert truthy checked to true', async () => {
element.checked = true;
(element.checked as any) = 2;

await waitForLitRender(element);

expect(element.checked).to.equal(true);
expect(element).to.have.attribute('aria-checked', 'true');
});

it('does not deselect radio if already checked', async () => {
const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);
it('should convert falsy disabled to false', async () => {
element.disabled = true;
(element.disabled as any) = undefined;

element.click();
await waitForLitRender(element);
expect(element).to.have.attribute('checked');
await waitForCondition(() => stateChange.events.length === 1);
expect(stateChange.count).to.be.equal(1);
await waitForLitRender(element);

element.click();
await waitForLitRender(element);
expect(element).to.have.attribute('checked');
await waitForCondition(() => stateChange.events.length === 1);
expect(stateChange.count).to.be.equal(1);
expect(element.disabled).to.equal(false);
expect(element).not.to.have.attribute('aria-disabled');
});

it('should convert truthy disabled to true', async () => {
element.disabled = true;
(element.disabled as any) = 2;

await waitForLitRender(element);

expect(element.disabled).to.equal(true);
expect(element).to.have.attribute('aria-disabled', 'true');
});

it('should convert falsy required to false', async () => {
element.required = true;
(element.required as any) = undefined;

await waitForLitRender(element);

expect(element.required).to.equal(false);
expect(element).to.have.attribute('aria-required', 'false');
});

it('should convert truthy required to true', async () => {
element.required = true;
(element.required as any) = 2;

await waitForLitRender(element);

expect(element.required).to.equal(true);
expect(element).to.have.attribute('aria-required', 'true');
});

it('should convert falsy allowEmptySelection to false', async () => {
element.allowEmptySelection = true;
(element.allowEmptySelection as any) = undefined;

await waitForLitRender(element);

expect(element.allowEmptySelection).to.equal(false);
});

it('should convert truthy allowEmptySelection to true', async () => {
element.allowEmptySelection = true;
(element.allowEmptySelection as any) = 2;

await waitForLitRender(element);

expect(element.allowEmptySelection).to.equal(true);
});
});

it('allows empty selection', async () => {
const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);

element.allowEmptySelection = true;
element.click();
await waitForLitRender(element);
expect(element).to.have.attribute('checked');
await waitForCondition(() => stateChange.events.length === 1);
expect(stateChange.count).to.be.equal(1);

element.click();
await waitForLitRender(element);
expect(element).not.to.have.attribute('checked');
await waitForCondition(() => stateChange.events.length === 2);
expect(stateChange.count).to.be.equal(2);
describe('with initial attributes', () => {
beforeEach(async () => {
element = await fixture(
html`<sbb-radio-button value="Value" checked disabled required>
Value label
</sbb-radio-button>`,
);
});

it('should have corresponding aria values set', async () => {
expect(element).to.have.attribute('aria-checked', 'true');
expect(element).to.have.attribute('aria-required', 'true');
expect(element).to.have.attribute('aria-disabled', 'true');
});

it('should update aria values', async () => {
element.checked = false;
element.required = false;
element.disabled = false;

await waitForLitRender(element);

expect(element).to.have.attribute('aria-checked', 'false');
expect(element).to.have.attribute('aria-required', 'false');
expect(element).not.to.have.attribute('aria-disabled');
});
});
});
Loading

0 comments on commit e746d4f

Please sign in to comment.