-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve the placeholder instructions accessibility. #45801
Changes from all commits
0aa9782
9bba5f0
ed69991
f818056
d3faeb9
3c8d17b
ccb24c3
887b619
00fdbbf
22c9153
d4c5265
eea9100
4fdf14e
e4a0f6a
37bda2d
9bf6cf5
87923da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import { render, screen, within } from '@testing-library/react'; | |
*/ | ||
import { useResizeObserver } from '@wordpress/compose'; | ||
import { SVG, Path } from '@wordpress/primitives'; | ||
import { speak } from '@wordpress/a11y'; | ||
|
||
/** | ||
* Internal dependencies | ||
|
@@ -41,17 +42,21 @@ const Placeholder = ( | |
|
||
const getPlaceholder = () => screen.getByTestId( 'placeholder' ); | ||
|
||
jest.mock( '@wordpress/a11y', () => ( { speak: jest.fn() } ) ); | ||
const mockedSpeak = jest.mocked( speak ); | ||
|
||
describe( 'Placeholder', () => { | ||
beforeEach( () => { | ||
// @ts-ignore | ||
useResizeObserver.mockReturnValue( [ | ||
<div key="1" />, | ||
{ width: 320 }, | ||
] ); | ||
mockedSpeak.mockReset(); | ||
} ); | ||
|
||
describe( 'basic rendering', () => { | ||
it( 'should by default render label section and fieldset.', () => { | ||
it( 'should by default render label section and content section.', () => { | ||
render( <Placeholder /> ); | ||
const placeholder = getPlaceholder(); | ||
|
||
|
@@ -74,9 +79,12 @@ describe( 'Placeholder', () => { | |
); | ||
expect( placeholderInstructions ).not.toBeInTheDocument(); | ||
|
||
// Test for empty fieldset. | ||
const placeholderFieldset = | ||
within( placeholder ).getByRole( 'group' ); | ||
// Test for empty content. When the content is empty, | ||
// the only way to query the div is with `querySelector` | ||
// eslint-disable-next-line testing-library/no-node-access | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a better way or is it okay to ignore? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mhh, there isn't an obvious better choice. Maybe @tyxla can think of something here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the ping @ciampo! Nope, if we remove the Therefore, since I agree with removing the |
||
const placeholderFieldset = placeholder.querySelector( | ||
'.components-placeholder__fieldset' | ||
); | ||
expect( placeholderFieldset ).toBeInTheDocument(); | ||
expect( placeholderFieldset ).toBeEmptyDOMElement(); | ||
} ); | ||
|
@@ -104,27 +112,38 @@ describe( 'Placeholder', () => { | |
expect( placeholderLabel ).toBeInTheDocument(); | ||
} ); | ||
|
||
it( 'should display a fieldset from the children property', () => { | ||
const content = 'Fieldset'; | ||
it( 'should display content from the children property', () => { | ||
const content = 'Placeholder content'; | ||
render( <Placeholder>{ content }</Placeholder> ); | ||
const placeholderFieldset = screen.getByRole( 'group' ); | ||
const placeholder = screen.getByText( content ); | ||
|
||
expect( placeholderFieldset ).toBeInTheDocument(); | ||
expect( placeholderFieldset ).toHaveTextContent( content ); | ||
expect( placeholder ).toBeInTheDocument(); | ||
expect( placeholder ).toHaveTextContent( content ); | ||
} ); | ||
|
||
it( 'should display a legend if instructions are passed', () => { | ||
it( 'should display instructions when provided', () => { | ||
const instructions = 'Choose an option.'; | ||
render( | ||
<Placeholder instructions={ instructions }> | ||
<div>Fieldset</div> | ||
<div>Placeholder content</div> | ||
</Placeholder> | ||
); | ||
const placeholder = getPlaceholder(); | ||
const instructionsContainer = | ||
within( placeholder ).getByText( instructions ); | ||
|
||
expect( instructionsContainer ).toBeInTheDocument(); | ||
} ); | ||
|
||
it( 'should announce instructions to screen readers', () => { | ||
const instructions = 'Awesome block placeholder instructions.'; | ||
render( | ||
<Placeholder instructions={ instructions }> | ||
<div>Placeholder content</div> | ||
</Placeholder> | ||
); | ||
const captionedFieldset = screen.getByRole( 'group', { | ||
name: instructions, | ||
} ); | ||
|
||
expect( captionedFieldset ).toBeInTheDocument(); | ||
expect( speak ).toHaveBeenCalledWith( instructions ); | ||
} ); | ||
|
||
it( 'should add an additional className to the top container', () => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On page load, all block with placeholders with instructions are now all "speaking" at once. Is this by intention?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ellatrix No, it needs to be fixed.