Skip to content

Commit

Permalink
test: add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vursen committed Nov 22, 2021
1 parent b9e6427 commit 888dd9e
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 23 deletions.
1 change: 1 addition & 0 deletions packages/form-layout/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@esm-bundle/chai": "^4.3.4",
"@vaadin/testing-helpers": "^0.3.2",
"@vaadin/text-field": "23.0.0-alpha1",
"@vaadin/custom-field": "23.0.0-alpha1",
"sinon": "^9.2.1"
}
}
25 changes: 22 additions & 3 deletions packages/form-layout/src/vaadin-form-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,26 @@ class FormItem extends ThemableMixin(PolymerElement) {
}
}

/**
* @return {HTMLElement}
* @private
*/
get __labelNode() {
return this.querySelector('[slot=label]');
}

/**
* @return {HTMLElement[]}
* @private
*/
get __fieldNodes() {
return [...this.querySelectorAll(':not([slot])')];
}

/**
* @return {HTMLElement | undefined}
* @private
*/
get __fieldAriaTarget() {
const fieldNode = this.__fieldNodes[0];
if (fieldNode && fieldNode.ariaTarget) {
Expand All @@ -195,15 +207,18 @@ class FormItem extends ThemableMixin(PolymerElement) {
return fieldNode;
}

/** @private */
/**
* @param {HTMLElement} labelNode
* @private
*/
__linkLabelToField(labelNode) {
const fieldAriaTarget = this.__fieldAriaTarget;
if (!fieldAriaTarget) {
return;
}

const ariaLabelledBy = fieldAriaTarget.getAttribute('aria-labelledby');
fieldAriaTarget.setAttribute('aria-labelledby', `${ariaLabelledBy} ${labelNode.id}`);
const aria = fieldAriaTarget.getAttribute('aria-labelledby');
fieldAriaTarget.setAttribute('aria-labelledby', `${aria} ${labelNode.id}`);
}

/** @private */
Expand All @@ -222,6 +237,10 @@ class FormItem extends ThemableMixin(PolymerElement) {

/** @private */
__onContentSlotChange() {
if (this.__labelNode) {
this.__linkLabelToField(this.__labelNode);
}

if (this.__contentField) {
// Discard the old field
this.__updateRequiredState(false);
Expand Down
124 changes: 104 additions & 20 deletions packages/form-layout/test/form-item.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,27 @@ import { expect } from '@esm-bundle/chai';
import { fixtureSync, nextFrame } from '@vaadin/testing-helpers';
import sinon from 'sinon';
import '@polymer/polymer/lib/elements/custom-style.js';
import '@vaadin/text-field';
import '@vaadin/custom-field';
import '../vaadin-form-item.js';

describe('form-item', () => {
let item, label, input;

beforeEach(() => {
item = fixtureSync(`
<vaadin-form-item>
<label slot="label">Label</label>
<input>
</vaadin-form-item>
`);
label = item.querySelector('label');
input = item.querySelector('input');
});

describe('basic features', () => {
let labelSlot, inputSlot;

const ID_REGEX = /^label-vaadin-form-item-\d+$/;

beforeEach(() => {
item = fixtureSync(`
<vaadin-form-item>
<label slot="label">Label</label>
<input>
</vaadin-form-item>
`);
label = item.querySelector('label');
input = item.querySelector('input');
labelSlot = item.shadowRoot.querySelector('slot[name="label"]');
inputSlot = item.shadowRoot.querySelector('slot:not([name])');
});
Expand All @@ -38,9 +39,26 @@ describe('form-item', () => {
it('should distribute input', () => {
expect(inputSlot.assignedNodes()).to.contain(input);
});

it('should set id on the label element', () => {
const id = label.getAttribute('id');
expect(id).to.match(ID_REGEX);
expect(id.endsWith(item.constructor._uniqueLabelId)).to.be.true;
});
});

describe('label positioning', () => {
beforeEach(() => {
item = fixtureSync(`
<vaadin-form-item>
<label slot="label">Label</label>
<input>
</vaadin-form-item>
`);
label = item.querySelector('label');
input = item.querySelector('input');
});

it('should be aside by default', () => {
const labelRect = label.getBoundingClientRect();
const inputRect = input.getBoundingClientRect();
Expand Down Expand Up @@ -70,17 +88,83 @@ describe('form-item', () => {
});
});

describe('label click', () => {
it('should focus input', () => {
const spy = sinon.spy(input, 'focus');
label.click();
expect(spy.called).to.be.true;
describe.only('label', () => {
describe('input', () => {
beforeEach(() => {
item = fixtureSync(`
<vaadin-form-item>
<label slot="label">Label</label>
<input aria-labelledby="custom-id">
</vaadin-form-item>
`);
label = item.querySelector('label');
input = item.querySelector('input');
});

it('should focus input on label click', () => {
const spy = sinon.spy(input, 'focus');
label.click();
expect(spy.calledOnce).to.be.true;
});

it('should click input on label click', () => {
const spy = sinon.spy(input, 'click');
label.click();
expect(spy.calledOnce).to.be.true;
});

it('should link the label to the input via aria-labelledby', () => {
const aria = input.getAttribute('aria-labelledby');
expect(aria).to.include('custom-id');
expect(aria).to.include(label.id);
});
});

it('should click input', () => {
const spy = sinon.spy(input, 'click');
label.click();
expect(spy.called).to.be.true;
describe('field', () => {
let field, fieldInput;

beforeEach(() => {
item = fixtureSync(`
<vaadin-form-item>
<label slot="label">Label</label>
<vaadin-text-field>
<input slot="input" aria-labelledby="custom-id">
</vaadin-text-field>
</vaadin-form-item>
`);
label = item.querySelector('label');
field = item.querySelector('vaadin-text-field');
fieldInput = field.querySelector('input');
});

it('should link the label to the field input via aria-labelledby', () => {
console.log(field, fieldInput);
console.log(label.id);
const aria = fieldInput.getAttribute('aria-labelledby');
expect(aria).to.include('custom-id');
expect(aria).to.include(label.id);
});
});

describe('field group', () => {
let fieldGroup;

beforeEach(() => {
item = fixtureSync(`
<vaadin-form-item>
<label slot="label">Label</label>
<vaadin-custom-field aria-labelledby="custom-id"></vaadin-custom-field>
</vaadin-form-item>
`);
label = item.querySelector('label');
fieldGroup = item.querySelector('vaadin-custom-field');
});

it('should link the label to the field group via aria-labelledby', () => {
const aria = fieldGroup.getAttribute('aria-labelledby');
expect(aria).to.include('custom-id');
expect(aria).to.include(label.id);
});
});
});

Expand Down

0 comments on commit 888dd9e

Please sign in to comment.