Accessible names for follow buttons (#14687)

* added aria-pressed value to all follow_buttons

* added check to remove aria pressed attribute and added cypress tests

* removed unfollow aria-label setting and cypress test fixes

* fixed cypress failing tests

* failing cypress test fix

* added steps to check correct states are loaded when page refreshed

* refreshed alias after page reload
This commit is contained in:
Keshav Biswa 2021-09-22 09:04:34 +05:30 committed by GitHub
parent 1746366c9b
commit 086813afd4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 172 additions and 74 deletions

View file

@ -144,7 +144,7 @@ module ApplicationHelper
}
},
class: "crayons-btn follow-action-button whitespace-nowrap #{classes} #{user_follow}",
aria: { label: "Follow #{followable_type}: #{followable_name}" },
aria: { label: "Follow #{followable_type}: #{followable_name}", pressed: "false" },
)
end

View file

@ -42,7 +42,7 @@ function addButtonFollowText(button, style) {
}
/**
* Sets the aria-label of the button
* Sets the aria-label and aria-pressed value of the button
*
* @param {HTMLElement} button The Follow button to update.
* @param {string} followType The followableType of the button.
@ -51,23 +51,31 @@ function addButtonFollowText(button, style) {
*/
function addAriaLabelToButton({ button, followType, followName, style = '' }) {
let label = '';
let pressed = '';
switch (style) {
case 'follow':
label = `Follow ${followType.toLowerCase()}: ${followName}`;
pressed = 'false';
break;
case 'follow-back':
label = `Follow ${followType.toLowerCase()} back: ${followName}`;
pressed = 'false';
break;
case 'following':
label = `Unfollow ${followType.toLowerCase()}: ${followName}`;
label = `Follow ${followType.toLowerCase()}: ${followName}`;
pressed = 'true';
break;
case 'self':
label = `Edit profile`;
break;
default:
label = `Follow ${followType.toLowerCase()}: ${followName}`;
pressed = 'false';
}
button.setAttribute('aria-label', label);
pressed.length === 0
? button.removeAttribute('aria-pressed')
: button.setAttribute('aria-pressed', pressed);
}
/**

View file

@ -22,10 +22,12 @@ describe('Follow author from article sidebar', () => {
cy.get('@followButton').click();
cy.get('@followButton').should('have.text', 'Following');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
cy.get('@followButton').click();
cy.wait('@followRequest');
cy.get('@followButton').should('have.text', 'Follow');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
});
});
});

View file

@ -31,10 +31,27 @@ describe('Follow from article liquid tag', () => {
'followUserButton',
);
cy.get('@followUserButton').should('have.text', 'Follow');
cy.get('@followUserButton').should(
'have.attr',
'aria-pressed',
'false',
);
cy.get('@followUserButton').click();
cy.get('@followUserButton').should('have.text', 'Following');
cy.get('@followUserButton').should(
'have.attr',
'aria-pressed',
'true',
);
cy.get('@followUserButton').click();
cy.get('@followUserButton').should('have.text', 'Follow');
cy.get('@followUserButton').should(
'have.attr',
'aria-pressed',
'false',
);
});
});
});

View file

@ -78,15 +78,22 @@ describe('Preview user profile from article page', () => {
cy.findByText('Edinburgh');
cy.findByText('University of Life');
cy.findByRole('button', {
name: 'Follow user: Admin McAdmin',
}).click();
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).as(
'followUserButton',
);
// Wait for Follow button to disappear and Following button to be initialized
cy.findByRole('button', {
name: 'Follow user: Admin McAdmin',
}).should('not.exist');
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
cy.get('@followUserButton').should(
'have.attr',
'aria-pressed',
'false',
);
cy.get('@followUserButton').click();
cy.get('@followUserButton').should(
'have.attr',
'aria-pressed',
'true',
);
});
// Check we can close the preview dropdown
@ -123,13 +130,14 @@ describe('Preview user profile from article page', () => {
cy.findByRole('button', {
name: 'Follow user: Admin McAdmin',
}).click();
}).as('userFollowButton');
// Wait for Follow button to disappear and Following button to be initialized
cy.findByRole('button', {
name: 'Follow user: Admin McAdmin',
}).should('not.exist');
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
cy.get('@userFollowButton').click();
cy.get('@userFollowButton').should(
'have.attr',
'aria-pressed',
'true',
);
});
});
});
@ -147,12 +155,14 @@ describe('Preview user profile from article page', () => {
.within(() => {
cy.findByRole('button', {
name: 'Follow user: Admin McAdmin',
}).click();
// Confirm the follow button has been updated
cy.findByRole('button', {
name: 'Follow user: Admin McAdmin',
}).should('not.exist');
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
}).as('userFollowButton');
cy.get('@userFollowButton').click();
cy.get('@userFollowButton').should(
'have.attr',
'aria-pressed',
'true',
);
});
// Close the preview card so the next preview button can be clicked
@ -165,7 +175,8 @@ describe('Preview user profile from article page', () => {
cy.findAllByTestId('profile-preview-card')
.last()
.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
.findByRole('button', { name: 'Follow user: Admin McAdmin' })
.should('have.attr', 'aria-pressed', 'true');
});
it('should detach listeners on preview card close', () => {

View file

@ -32,13 +32,14 @@ describe('Preview profile from series', () => {
cy.findByText('Edinburgh');
cy.findByText('University of Life');
cy.findByRole('button', { name: 'Follow user: Series User' }).click();
// Check that the follow button has updated as expected
cy.findByRole('button', { name: 'Follow user: Series User' }).should(
'not.exist',
cy.findByRole('button', { name: 'Follow user: Series User' }).as(
'userFollowButton',
);
cy.findByRole('button', { name: 'Unfollow user: Series User' });
cy.get('@userFollowButton').should('have.attr', 'aria-pressed', 'false');
cy.get('@userFollowButton').click();
cy.get('@userFollowButton').should('have.text', 'Following');
cy.get('@userFollowButton').should('have.attr', 'aria-pressed', 'true');
});
});
});

View file

@ -23,10 +23,12 @@ describe('View article discussion', () => {
// Confirm the follow button has been updated
cy.get('@userFollowButton').should('have.text', 'Following');
cy.get('@userFollowButton').should('have.attr', 'aria-pressed', 'true');
// Repeat and check the button changes back to 'Follow'
cy.get('@userFollowButton').click();
cy.get('@userFollowButton').should('have.text', 'Follow');
cy.get('@userFollowButton').should('have.attr', 'aria-pressed', 'false');
});
});

View file

@ -27,13 +27,18 @@ describe('Home feed profile preview cards', () => {
cy.findByText('Edinburgh');
cy.findByText('University of Life');
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).click();
// Check that following status has been updated
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).should(
'not.exist',
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).as(
'userFollowButton',
);
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
cy.get('@userFollowButton').should(
'have.attr',
'aria-pressed',
'false',
);
cy.get('@userFollowButton').click();
cy.get('@userFollowButton').should('have.text', 'Following');
cy.get('@userFollowButton').should('have.attr', 'aria-pressed', 'true');
});
});
});

View file

@ -24,7 +24,18 @@ describe('Logged out Home feed', () => {
cy.findByText('Edinburgh');
cy.findByText('University of Life');
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).click();
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).as(
'userFollowButton',
);
cy.get('@userFollowButton').click();
// Confirm the follow button has been updated
cy.get('@userFollowButton').should('have.text', 'Follow');
cy.get('@userFollowButton').should(
'have.attr',
'aria-pressed',
'false',
);
});
// Clicking a follow button while logged out should always trigger the log in to continue modal

View file

@ -25,7 +25,18 @@ describe('Logged out - tag index page', () => {
cy.findByText('Edinburgh');
cy.findByText('University of Life');
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).click();
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).as(
'userFollowButton',
);
cy.get('@userFollowButton').click();
// Confirm the follow button has been updated
cy.get('@userFollowButton').should('have.text', 'Follow');
cy.get('@userFollowButton').should(
'have.attr',
'aria-pressed',
'false',
);
});
// Clicking a follow button while logged out should always trigger the log in to continue modal

View file

@ -14,11 +14,14 @@ describe('Follow user from notifications', () => {
cy.findByRole('button', { name: 'Follow user back: User' }).as(
'followButton',
);
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
cy.get('@followButton').click();
cy.get('@followButton').should('have.text', 'Following');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
cy.get('@followButton').click();
cy.get('@followButton').should('have.text', 'Follow back');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
});
});

View file

@ -13,6 +13,7 @@ describe('Follow podcast', () => {
cy.findByRole('heading', {
name: 'Developer on Fire Developer on Fire Follow',
});
cy.findByRole('button', { name: 'Follow podcast: Developer on Fire' }).as(
'followButton',
);
@ -20,16 +21,19 @@ describe('Follow podcast', () => {
cy.get('@followButton').click();
// Inner text should now be following
cy.get('@followButton').should('have.text', 'Following');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
// Check that state is persisted on refresh
cy.visitAndWaitForUserSideEffects('/developeronfire');
cy.findByRole('button', { name: 'Unfollow podcast: Developer on Fire' }).as(
cy.findByRole('button', { name: 'Follow podcast: Developer on Fire' }).as(
'followButton',
);
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
// Check it reverts back to Follow on click
cy.get('@followButton').click();
cy.get('@followButton').should('have.text', 'Follow');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
// Check that state is persisted on refresh
cy.visitAndWaitForUserSideEffects('/developeronfire');

View file

@ -12,24 +12,28 @@ describe('Follow user from profile page', () => {
it('follows and unfollows an organisation', () => {
cy.intercept('/follows').as('followsRequest');
cy.findByRole('button', {
name: 'Follow organization: Bachmanity',
}).click();
cy.wait('@followsRequest');
cy.findByRole('button', { name: 'Unfollow organization: Bachmanity' });
cy.findByRole('button', { name: 'Follow organization: Bachmanity' }).as(
'followButton',
);
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
cy.get('@followButton').click();
// Inner text should now be following
cy.get('@followButton').should('have.text', 'Following');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
// Check that state is persisted on refresh
cy.visitAndWaitForUserSideEffects('/bachmanity');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
// Check it reverts back to Follow on click
cy.get('@followButton').click();
cy.get('@followButton').should('have.text', 'Follow');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
// Check that the update persists after reload
cy.visitAndWaitForUserSideEffects('/bachmanity');
cy.findByRole('button', {
name: 'Unfollow organization: Bachmanity',
}).click();
cy.wait('@followsRequest');
cy.findByRole('button', { name: 'Follow organization: Bachmanity' });
// Check that the update persists after reload
cy.visitAndWaitForUserSideEffects('/bachmanity');
cy.findByRole('button', { name: 'Follow organization: Bachmanity' });
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
});
});

View file

@ -14,22 +14,27 @@ describe('Follow user from profile page', () => {
cy.findByRole('button', {
name: 'Follow user: Article Editor v1 User',
}).click();
}).as('followButton');
cy.get('@followButton').click();
cy.wait('@followsRequest');
cy.findByRole('button', { name: 'Unfollow user: Article Editor v1 User' });
cy.get('@followButton').should('have.text', 'Following');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
// Check that the update persists after reload
cy.visitAndWaitForUserSideEffects('/article_editor_v1_user');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
cy.get('@followButton').click();
cy.findByRole('button', {
name: 'Unfollow user: Article Editor v1 User',
}).click();
cy.wait('@followsRequest');
cy.findByRole('button', { name: 'Follow user: Article Editor v1 User' });
cy.get('@followButton').should('have.text', 'Follow');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
// Check that the update persists after reload
cy.visitAndWaitForUserSideEffects('/article_editor_v1_user');
cy.findByRole('button', { name: 'Follow user: Article Editor v1 User' });
cy.get('@followButton').should('have.text', 'Follow');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
});
});

View file

@ -31,9 +31,11 @@ describe('Follow user from search results', () => {
cy.wait('@followsRequest');
cy.get('@followButton').should('have.text', 'Following');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
cy.get('@followButton').click();
cy.wait('@followsRequest');
cy.get('@followButton').should('have.text', 'Follow');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
});
});

View file

@ -28,13 +28,18 @@ describe('Preview profile from post search results', () => {
cy.findByText('Edinburgh');
cy.findByText('University of Life');
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).click();
// Check that following status has been updated
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).should(
'not.exist',
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).as(
'followUserButton',
);
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
cy.get('@followUserButton').should(
'have.attr',
'aria-pressed',
'false',
);
cy.get('@followUserButton').click();
cy.get('@followUserButton').should('have.attr', 'aria-pressed', 'true');
});
});
});

View file

@ -20,11 +20,13 @@ describe('Follow tag', () => {
cy.wait('@followsRequest');
cy.get('@followButton').should('have.text', 'Following');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
cy.get('@followButton').click();
cy.wait('@followsRequest');
cy.get('@followButton').should('have.text', 'Follow');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
});
});

View file

@ -28,13 +28,18 @@ describe('Preview profile from the tag index page', () => {
cy.findByText('Edinburgh');
cy.findByText('University of Life');
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).click();
// Check that following status has been updated
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).should(
'not.exist',
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).as(
'userFollowButton',
);
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
cy.get('@userFollowButton').should(
'have.attr',
'aria-pressed',
'false',
);
cy.get('@userFollowButton').click();
cy.get('@userFollowButton').should('have.text', 'Following');
cy.get('@userFollowButton').should('have.attr', 'aria-pressed', 'true');
});
});
});