[MM-61571]: Add label to form field in channel header (#29553)

* [MA-12]: Add label to form field in channel header

* [MA-12]: Update aria attributes and tests

* [MA-12]: Update snapshots, fix e2e test

* [MA-12]: Fix E2E tests

* [MA-12]: Fix type in test
Этот коммит содержится в:
Saurabh Sharma
2025-01-09 03:34:42 +05:30
коммит произвёл GitHub
родитель 3a13dc2d5d
Коммит a3b2ecec19
12 изменённых файлов: 59 добавлений и 64 удалений

Просмотреть файл

@@ -36,13 +36,13 @@ describe('Channel Settings - Channel Header', () => {
cy.findByText('Edit Channel Header').click(); cy.findByText('Edit Channel Header').click();
// # Type something in the header edit box // # Type something in the header edit box
cy.get('[aria-label="edit the channel header..."]').clear().type('This is the new header content'); cy.get('textarea[placeholder="Edit the Channel Header..."]').clear().type('This is the new header content');
// * Verify the "Preview" button exists // * Verify the "Preview" button exists
cy.findByText('Preview').should('be.visible'); cy.findByText('Preview').should('be.visible');
// * Verify that before hitting the preview button, the style on the textbox is `display: block` // * Verify that before hitting the preview button, the style on the textbox is `display: block`
cy.get('[aria-label="edit the channel header..."]').should('have.css', 'display', 'block'); cy.get('textarea[placeholder="Edit the Channel Header..."]').should('have.css', 'display', 'block');
// # Click the "Preview" button // # Click the "Preview" button
cy.findByText('Preview').click(); cy.findByText('Preview').click();
@@ -51,7 +51,7 @@ describe('Channel Settings - Channel Header', () => {
cy.findByText('Edit').should('be.visible'); cy.findByText('Edit').should('be.visible');
// * Verify that the display is now none on the textbox element // * Verify that the display is now none on the textbox element
cy.get('[aria-label="edit the channel header..."]').should('have.css', 'display', 'none'); cy.get('textarea[placeholder="Edit the Channel Header..."]').should('have.css', 'display', 'none');
}); });
}); });
}); });

Просмотреть файл

@@ -122,7 +122,7 @@ describe('Verify Accessibility Support in different input fields', () => {
cy.apiAddUserToTeam(testTeam.id, user.id).then(() => { cy.apiAddUserToTeam(testTeam.id, user.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, user.id).then(() => { cy.apiAddUserToChannel(testChannel.id, user.id).then(() => {
// * Verify Accessibility support in post input field // * Verify Accessibility support in post input field
cy.uiGetPostTextBox().should('have.attr', 'aria-label', `write to ${testChannel.display_name}`).clear().focus(); cy.uiGetPostTextBox().should('have.attr', 'placeholder', `Write to ${testChannel.display_name}`).clear().focus();
// # Ensure User list is cached once in UI // # Ensure User list is cached once in UI
cy.uiGetPostTextBox().type('@').wait(TIMEOUTS.FIVE_SEC); cy.uiGetPostTextBox().type('@').wait(TIMEOUTS.FIVE_SEC);
@@ -168,7 +168,7 @@ describe('Verify Accessibility Support in different input fields', () => {
it('MM-T1458 Verify Accessibility Support in Main Post Input', () => { it('MM-T1458 Verify Accessibility Support in Main Post Input', () => {
cy.get('#advancedTextEditorCell').within(() => { cy.get('#advancedTextEditorCell').within(() => {
// * Verify Accessibility Support in Main Post input // * Verify Accessibility Support in Main Post input
cy.uiGetPostTextBox().should('have.attr', 'aria-label', `write to ${testChannel.display_name}`).and('have.attr', 'role', 'textbox').clear().focus().type('test'); cy.uiGetPostTextBox().should('have.attr', 'placeholder', `Write to ${testChannel.display_name}`).and('have.attr', 'role', 'textbox').clear().focus().type('test');
// # Set a11y focus on the textbox // # Set a11y focus on the textbox
cy.get('#FormattingControl_bold').focus().tab({shift: true}); cy.get('#FormattingControl_bold').focus().tab({shift: true});
@@ -231,7 +231,7 @@ describe('Verify Accessibility Support in different input fields', () => {
cy.get('#rhsContainer').within(() => { cy.get('#rhsContainer').within(() => {
// * Verify Accessibility Support in RHS input // * Verify Accessibility Support in RHS input
cy.uiGetReplyTextBox().should('have.attr', 'aria-label', 'reply to this thread...').and('have.attr', 'role', 'textbox').focus().type('test').tab({shift: true}).tab().tab(); cy.uiGetReplyTextBox().should('have.attr', 'placeholder', 'Reply to this thread...').and('have.attr', 'role', 'textbox').focus().type('test').tab({shift: true}).tab().tab();
// * Verify if the focus is on the preview button // * Verify if the focus is on the preview button
cy.get('#PreviewInputTextButton').should('be.focused').and('have.attr', 'aria-label', 'preview').tab(); cy.get('#PreviewInputTextButton').should('be.focused').and('have.attr', 'aria-label', 'preview').tab();

Просмотреть файл

@@ -61,7 +61,7 @@ describe('MM-23102 - Channel Moderation - Create Posts', () => {
// # Check Guest user should not have the permission to create a post on a channel when the option is removed // # Check Guest user should not have the permission to create a post on a channel when the option is removed
// * Guest user should see a message stating that this channel is read-only and the textbox area should be disabled // * Guest user should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox_placeholder').should('have.text', 'This channel is read-only. Only members with permission can post here.'); cy.findByTestId('post_textbox').should('have.attr', 'placeholder', 'This channel is read-only. Only members with permission can post here.');
cy.findByTestId('post_textbox').should('be.disabled'); cy.findByTestId('post_textbox').should('be.disabled');
// # As a system admin, check the option to allow Create Posts for Guests and save // # As a system admin, check the option to allow Create Posts for Guests and save
@@ -75,7 +75,7 @@ describe('MM-23102 - Channel Moderation - Create Posts', () => {
// # Check Guest user should have the permission to create a post on a channel when the option is allowed // # Check Guest user should have the permission to create a post on a channel when the option is allowed
// * Guest user should see a message stating that this channel is read-only and the textbox area should be disabled // * Guest user should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox').clear(); cy.findByTestId('post_textbox').clear();
cy.findByTestId('post_textbox_placeholder').should('have.text', `Write to ${testChannel.display_name}`); cy.findByTestId('post_textbox').should('have.attr', 'placeholder', `Write to ${testChannel.display_name}`);
cy.findByTestId('post_textbox').should('not.be.disabled'); cy.findByTestId('post_textbox').should('not.be.disabled');
}); });
@@ -92,7 +92,7 @@ describe('MM-23102 - Channel Moderation - Create Posts', () => {
// # Check Member should not have the permission to create a post on a channel when the option is removed. // # Check Member should not have the permission to create a post on a channel when the option is removed.
// * User should see a message stating that this channel is read-only and the textbox area should be disabled // * User should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox_placeholder').should('have.text', 'This channel is read-only. Only members with permission can post here.'); cy.findByTestId('post_textbox').should('have.attr', 'placeholder', 'This channel is read-only. Only members with permission can post here.');
cy.findByTestId('post_textbox').should('be.disabled'); cy.findByTestId('post_textbox').should('be.disabled');
// # As a system admin, check the option to allow Create Posts for Members and save // # As a system admin, check the option to allow Create Posts for Members and save
@@ -106,7 +106,7 @@ describe('MM-23102 - Channel Moderation - Create Posts', () => {
// # Check Member should have the permission to create a post on a channel when the option is allowed // # Check Member should have the permission to create a post on a channel when the option is allowed
// * Member user should see a message stating that this channel is read-only and the textbox area should be disabled // * Member user should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox').clear(); cy.findByTestId('post_textbox').clear();
cy.findByTestId('post_textbox_placeholder').should('have.text', `Write to ${testChannel.display_name}`); cy.findByTestId('post_textbox').should('have.attr', 'placeholder', `Write to ${testChannel.display_name}`);
cy.findByTestId('post_textbox').should('not.be.disabled'); cy.findByTestId('post_textbox').should('not.be.disabled');
}); });
}); });

Просмотреть файл

@@ -31,7 +31,7 @@ describe('Keyboard Shortcuts', () => {
// * Verify modal is open // * Verify modal is open
cy.findByRole('dialog', {name: 'Edit Header for Off-Topic'}).within(() => { cy.findByRole('dialog', {name: 'Edit Header for Off-Topic'}).within(() => {
// # Enter new header and save // # Enter new header and save
cy.findByRole('textbox', {name: 'edit the channel header...'}).type(newHeader); cy.findByRole('textbox', {name: 'Edit the text appearing next to the channel name in the header.'}).type(newHeader);
cy.uiSave(); cy.uiSave();
}); });

Просмотреть файл

@@ -2,24 +2,7 @@
exports[`components/AutosizeTextarea should match snapshot, init 1`] = ` exports[`components/AutosizeTextarea should match snapshot, init 1`] = `
<div> <div>
<div
data-testid="autosize_textarea_placeholder"
id="autosize_textarea_placeholder"
style={
Object {
"background": "none",
"borderColor": "transparent",
"opacity": 0.75,
"overflow": "hidden",
"pointerEvents": "none",
"position": "absolute",
"textOverflow": "ellipsis",
"whiteSpace": "nowrap",
}
}
/>
<textarea <textarea
aria-label=""
data-testid="autosize_textarea" data-testid="autosize_textarea"
dir="auto" dir="auto"
height={0} height={0}

Просмотреть файл

@@ -227,7 +227,7 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
}), }),
); );
expect(screen.getByLabelText('write to test channel')).toHaveValue('original draft'); expect(screen.getByPlaceholderText('Write to Test Channel')).toHaveValue('original draft');
rerender( rerender(
<AdvancedTextEditor <AdvancedTextEditor
@@ -235,7 +235,7 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
channelId={otherChannelId} channelId={otherChannelId}
/>, />,
); );
expect(screen.getByLabelText('write to other channel')).toHaveValue('a different draft'); expect(screen.getByPlaceholderText('Write to Other Channel')).toHaveValue('a different draft');
}); });
it('should save a new draft when changing channels', () => { it('should save a new draft when changing channels', () => {
@@ -246,7 +246,7 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
initialState, initialState,
); );
userEvent.type(screen.getByLabelText('write to test channel'), 'some text'); userEvent.type(screen.getByPlaceholderText('Write to Test Channel'), 'some text');
expect(mockedUpdateDraft).not.toHaveBeenCalled(); expect(mockedUpdateDraft).not.toHaveBeenCalled();
@@ -312,7 +312,7 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
}), }),
); );
userEvent.type(screen.getByLabelText('write to test channel'), ' plus some new text'); userEvent.type(screen.getByPlaceholderText('Write to Test Channel'), ' plus some new text');
expect(mockedUpdateDraft).not.toHaveBeenCalled(); expect(mockedUpdateDraft).not.toHaveBeenCalled();
@@ -348,7 +348,7 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
}), }),
); );
userEvent.clear(screen.getByLabelText('write to test channel')); userEvent.clear(screen.getByPlaceholderText('Write to Test Channel'));
expect(mockedRemoveDraft).not.toHaveBeenCalled(); expect(mockedRemoveDraft).not.toHaveBeenCalled();
expect(mockedUpdateDraft).not.toHaveBeenCalled(); expect(mockedUpdateDraft).not.toHaveBeenCalled();

Просмотреть файл

@@ -130,21 +130,6 @@ const AutosizeTextarea = React.forwardRef<HTMLTextAreaElement, Props>(({
heightProps.height = height.current; heightProps.height = height.current;
} }
let textareaPlaceholder = null;
const placeholderAriaLabel = placeholder ? placeholder.toLowerCase() : '';
if (!value && !defaultValue) {
textareaPlaceholder = (
<div
{...otherProps}
id={`${id}_placeholder`}
data-testid={`${id}_placeholder`}
style={styles.placeholder}
>
{placeholder}
</div>
);
}
let referenceValue = value || defaultValue; let referenceValue = value || defaultValue;
if (referenceValue?.endsWith('\n')) { if (referenceValue?.endsWith('\n')) {
// In a div, the browser doesn't always count characters at the end of a line when measuring the dimensions // In a div, the browser doesn't always count characters at the end of a line when measuring the dimensions
@@ -158,16 +143,15 @@ const AutosizeTextarea = React.forwardRef<HTMLTextAreaElement, Props>(({
} }
return ( return (
<div> <div >
{textareaPlaceholder}
<textarea <textarea
ref={setTextareaRef} ref={setTextareaRef}
data-testid={id} data-testid={id}
id={id} id={id}
{...heightProps} {...heightProps}
{...otherProps} {...otherProps}
placeholder={placeholder}
role='textbox' role='textbox'
aria-label={placeholderAriaLabel}
dir='auto' dir='auto'
disabled={disabled} disabled={disabled}
onChange={onChange} onChange={onChange}

Просмотреть файл

@@ -53,12 +53,15 @@ exports[`components/EditChannelHeaderModal edit direct message channel 1`] = `
componentClass="div" componentClass="div"
> >
<div> <div>
<p> <label
className="textarea-label"
htmlFor="edit_textbox"
>
<MemoizedFormattedMessage <MemoizedFormattedMessage
defaultMessage="Edit the text appearing next to the channel name in the header." defaultMessage="Edit the text appearing next to the channel name in the header."
id="edit_channel_header_modal.description" id="edit_channel_header_modal.description"
/> />
</p> </label>
<div <div
className="textarea-wrapper" className="textarea-wrapper"
> >
@@ -183,12 +186,15 @@ exports[`components/EditChannelHeaderModal error with intl message 1`] = `
componentClass="div" componentClass="div"
> >
<div> <div>
<p> <label
className="textarea-label"
htmlFor="edit_textbox"
>
<MemoizedFormattedMessage <MemoizedFormattedMessage
defaultMessage="Edit the text appearing next to the channel name in the header." defaultMessage="Edit the text appearing next to the channel name in the header."
id="edit_channel_header_modal.description" id="edit_channel_header_modal.description"
/> />
</p> </label>
<div <div
className="textarea-wrapper" className="textarea-wrapper"
> >
@@ -331,12 +337,15 @@ exports[`components/EditChannelHeaderModal error without intl message 1`] = `
componentClass="div" componentClass="div"
> >
<div> <div>
<p> <label
className="textarea-label"
htmlFor="edit_textbox"
>
<MemoizedFormattedMessage <MemoizedFormattedMessage
defaultMessage="Edit the text appearing next to the channel name in the header." defaultMessage="Edit the text appearing next to the channel name in the header."
id="edit_channel_header_modal.description" id="edit_channel_header_modal.description"
/> />
</p> </label>
<div <div
className="textarea-wrapper" className="textarea-wrapper"
> >
@@ -471,12 +480,15 @@ exports[`components/EditChannelHeaderModal should match snapshot, init 1`] = `
componentClass="div" componentClass="div"
> >
<div> <div>
<p> <label
className="textarea-label"
htmlFor="edit_textbox"
>
<MemoizedFormattedMessage <MemoizedFormattedMessage
defaultMessage="Edit the text appearing next to the channel name in the header." defaultMessage="Edit the text appearing next to the channel name in the header."
id="edit_channel_header_modal.description" id="edit_channel_header_modal.description"
/> />
</p> </label>
<div <div
className="textarea-wrapper" className="textarea-wrapper"
> >
@@ -601,12 +613,15 @@ exports[`components/EditChannelHeaderModal submitted 1`] = `
componentClass="div" componentClass="div"
> >
<div> <div>
<p> <label
className="textarea-label"
htmlFor="edit_textbox"
>
<MemoizedFormattedMessage <MemoizedFormattedMessage
defaultMessage="Edit the text appearing next to the channel name in the header." defaultMessage="Edit the text appearing next to the channel name in the header."
id="edit_channel_header_modal.description" id="edit_channel_header_modal.description"
/> />
</p> </label>
<div <div
className="textarea-wrapper" className="textarea-wrapper"
> >

Просмотреть файл

@@ -227,12 +227,15 @@ export class EditChannelHeaderModal extends React.PureComponent<Props, State> {
</Modal.Header> </Modal.Header>
<Modal.Body bsClass='modal-body edit-modal-body'> <Modal.Body bsClass='modal-body edit-modal-body'>
<div> <div>
<p> <label
htmlFor='edit_textbox'
className='textarea-label'
>
<FormattedMessage <FormattedMessage
id='edit_channel_header_modal.description' id='edit_channel_header_modal.description'
defaultMessage='Edit the text appearing next to the channel name in the header.' defaultMessage='Edit the text appearing next to the channel name in the header.'
/> />
</p> </label>
<div className='textarea-wrapper'> <div className='textarea-wrapper'>
<Textbox <Textbox
value={this.state.header!} value={this.state.header!}

Просмотреть файл

@@ -57,6 +57,11 @@
.edit-modal-body { .edit-modal-body {
overflow: visible; overflow: visible;
.textarea-label {
margin-bottom: 10px;
font-weight: 400;
}
.custom-textarea { .custom-textarea {
height: auto; height: auto;
min-height: 8em; min-height: 8em;

Просмотреть файл

@@ -26,6 +26,11 @@
background: #ffffac !important; background: #ffffac !important;
color: #d04444 !important; color: #d04444 !important;
} }
&::placeholder {
text-overflow: ellipsis;
white-space: pre;
}
} }
} }

Просмотреть файл

@@ -148,6 +148,6 @@ describe('identifyElementRegion', () => {
expect(identifyElementRegion(screen.getByText(post.message))).toEqual('post'); expect(identifyElementRegion(screen.getByText(post.message))).toEqual('post');
}); });
expect(identifyElementRegion(screen.getByText('Write to ' + channel.display_name))).toEqual('post_textbox'); expect(identifyElementRegion(screen.getByPlaceholderText('Write to ' + channel.display_name))).toEqual('post_textbox');
}); });
}); });