diff --git a/src/material/datepicker/aria-accessible-name.spec.ts b/src/material/datepicker/aria-accessible-name.spec.ts new file mode 100644 index 000000000000..260164b2cddc --- /dev/null +++ b/src/material/datepicker/aria-accessible-name.spec.ts @@ -0,0 +1,159 @@ +import {_computeAriaAccessibleName} from './aria-accessible-name'; + +describe('_computeAriaAccessibleName', () => { + let rootElement: HTMLSpanElement; + + beforeEach(() => { + rootElement = document.createElement('span'); + document.body.appendChild(rootElement); + }); + + afterEach(() => { + rootElement.remove(); + }); + + it('uses aria-labelledby over aria-label', () => { + rootElement.innerHTML = ` + + + `; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe('Aria Labelledby'); + }); + + it('uses aria-label over for/id', () => { + rootElement.innerHTML = ` + + + `; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe('Aria Label'); + }); + + it('uses a label with for/id over a title attribute', () => { + rootElement.innerHTML = ` + + + `; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe('For'); + }); + + it('returns title when argument has a specified title', () => { + rootElement.innerHTML = ``; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe('Title'); + }); + + // match browser behavior of giving placeholder attribute preference over title attribute + it('uses placeholder over title', () => { + rootElement.innerHTML = ``; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe('Placeholder'); + }); + + it('uses aria-label over title and placeholder', () => { + rootElement.innerHTML = ``; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe('Aria Label'); + }); + + it('includes both textnode and element children of label with for/id', () => { + rootElement.innerHTML = ` + + + `; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe('Hello Wo r ld !'); + }); + + it('return computed name of hidden label which has for/id', () => { + rootElement.innerHTML = ` + + + `; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe('For'); + }); + + it('returns computed names of existing elements when 2 of 3 targets of aria-labelledby exist', () => { + rootElement.innerHTML = ` + + + + `; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe('Label1 Label2'); + }); + + it('returns repeated label when there are duplicate ids in aria-labelledby', () => { + rootElement.innerHTML = ` + + + `; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe('Label1 Label1'); + }); + + it('returns empty string when passed ``', () => { + rootElement.innerHTML = ``; + + const input = rootElement.querySelector('#test-el')!; + expect(_computeAriaAccessibleName(input as HTMLInputElement)).toBe(''); + }); + + it('ignores the aria-labelledby of an aria-labelledby', () => { + rootElement.innerHTML = ` + +