diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 14fabad4c..bc0423dbe 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -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 diff --git a/app/javascript/packs/followButtons.js b/app/javascript/packs/followButtons.js index c690a614f..7ce104554 100644 --- a/app/javascript/packs/followButtons.js +++ b/app/javascript/packs/followButtons.js @@ -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); } /** diff --git a/cypress/integration/seededFlows/articleFlows/followAuthor.spec.js b/cypress/integration/seededFlows/articleFlows/followAuthor.spec.js index 7002814ad..f7471d9cd 100644 --- a/cypress/integration/seededFlows/articleFlows/followAuthor.spec.js +++ b/cypress/integration/seededFlows/articleFlows/followAuthor.spec.js @@ -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'); }); }); }); diff --git a/cypress/integration/seededFlows/articleFlows/followFromArticleLiquidTag.spec.js b/cypress/integration/seededFlows/articleFlows/followFromArticleLiquidTag.spec.js index 8e89e735c..67bbdc17e 100644 --- a/cypress/integration/seededFlows/articleFlows/followFromArticleLiquidTag.spec.js +++ b/cypress/integration/seededFlows/articleFlows/followFromArticleLiquidTag.spec.js @@ -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', + ); }); }); }); diff --git a/cypress/integration/seededFlows/articleFlows/previewProfile.spec.js b/cypress/integration/seededFlows/articleFlows/previewProfile.spec.js index f664f494b..67fa5aaa0 100644 --- a/cypress/integration/seededFlows/articleFlows/previewProfile.spec.js +++ b/cypress/integration/seededFlows/articleFlows/previewProfile.spec.js @@ -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', () => { diff --git a/cypress/integration/seededFlows/articleFlows/seriesFlows/previewProfileFromSeries.spec.js b/cypress/integration/seededFlows/articleFlows/seriesFlows/previewProfileFromSeries.spec.js index 57032242a..d8799bc6a 100644 --- a/cypress/integration/seededFlows/articleFlows/seriesFlows/previewProfileFromSeries.spec.js +++ b/cypress/integration/seededFlows/articleFlows/seriesFlows/previewProfileFromSeries.spec.js @@ -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'); }); }); }); diff --git a/cypress/integration/seededFlows/articleFlows/viewArticleDiscussion.spec.js b/cypress/integration/seededFlows/articleFlows/viewArticleDiscussion.spec.js index 40ea97bfd..4164d046a 100644 --- a/cypress/integration/seededFlows/articleFlows/viewArticleDiscussion.spec.js +++ b/cypress/integration/seededFlows/articleFlows/viewArticleDiscussion.spec.js @@ -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'); }); }); diff --git a/cypress/integration/seededFlows/homeFeedFlows/profilePreviewCards.spec.js b/cypress/integration/seededFlows/homeFeedFlows/profilePreviewCards.spec.js index 2c07dc052..ea8df75f9 100644 --- a/cypress/integration/seededFlows/homeFeedFlows/profilePreviewCards.spec.js +++ b/cypress/integration/seededFlows/homeFeedFlows/profilePreviewCards.spec.js @@ -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'); }); }); }); diff --git a/cypress/integration/seededFlows/loggedOutFlows/homeFeed.spec.js b/cypress/integration/seededFlows/loggedOutFlows/homeFeed.spec.js index cf08f6868..ecd75474e 100644 --- a/cypress/integration/seededFlows/loggedOutFlows/homeFeed.spec.js +++ b/cypress/integration/seededFlows/loggedOutFlows/homeFeed.spec.js @@ -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 diff --git a/cypress/integration/seededFlows/loggedOutFlows/tagIndex.spec.js b/cypress/integration/seededFlows/loggedOutFlows/tagIndex.spec.js index 5953456a7..55ef7db11 100644 --- a/cypress/integration/seededFlows/loggedOutFlows/tagIndex.spec.js +++ b/cypress/integration/seededFlows/loggedOutFlows/tagIndex.spec.js @@ -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 diff --git a/cypress/integration/seededFlows/notificationsFlows/followUserFromNotifications.spec.js b/cypress/integration/seededFlows/notificationsFlows/followUserFromNotifications.spec.js index 8c7f9985d..a82e66d36 100644 --- a/cypress/integration/seededFlows/notificationsFlows/followUserFromNotifications.spec.js +++ b/cypress/integration/seededFlows/notificationsFlows/followUserFromNotifications.spec.js @@ -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'); }); }); diff --git a/cypress/integration/seededFlows/podcastFlows/followPodcast.spec.js b/cypress/integration/seededFlows/podcastFlows/followPodcast.spec.js index 981f96dee..bd43168b4 100644 --- a/cypress/integration/seededFlows/podcastFlows/followPodcast.spec.js +++ b/cypress/integration/seededFlows/podcastFlows/followPodcast.spec.js @@ -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'); diff --git a/cypress/integration/seededFlows/profileFlows/followOrganisation.spec.js b/cypress/integration/seededFlows/profileFlows/followOrganisation.spec.js index 6c7a8091e..0809b630c 100644 --- a/cypress/integration/seededFlows/profileFlows/followOrganisation.spec.js +++ b/cypress/integration/seededFlows/profileFlows/followOrganisation.spec.js @@ -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'); }); }); diff --git a/cypress/integration/seededFlows/profileFlows/followUser.spec.js b/cypress/integration/seededFlows/profileFlows/followUser.spec.js index c1584b27b..ed734cd0d 100644 --- a/cypress/integration/seededFlows/profileFlows/followUser.spec.js +++ b/cypress/integration/seededFlows/profileFlows/followUser.spec.js @@ -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'); }); }); diff --git a/cypress/integration/seededFlows/searchFlows/followUser.spec.js b/cypress/integration/seededFlows/searchFlows/followUser.spec.js index d04da1fcf..4ba243792 100644 --- a/cypress/integration/seededFlows/searchFlows/followUser.spec.js +++ b/cypress/integration/seededFlows/searchFlows/followUser.spec.js @@ -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'); }); }); diff --git a/cypress/integration/seededFlows/searchFlows/previewProfileFromPostSearchResults.spec.js b/cypress/integration/seededFlows/searchFlows/previewProfileFromPostSearchResults.spec.js index 3e64f35cc..90656b18e 100644 --- a/cypress/integration/seededFlows/searchFlows/previewProfileFromPostSearchResults.spec.js +++ b/cypress/integration/seededFlows/searchFlows/previewProfileFromPostSearchResults.spec.js @@ -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'); }); }); }); diff --git a/cypress/integration/seededFlows/tagsFlows/followTag.spec.js b/cypress/integration/seededFlows/tagsFlows/followTag.spec.js index e6dbb554a..05855d648 100644 --- a/cypress/integration/seededFlows/tagsFlows/followTag.spec.js +++ b/cypress/integration/seededFlows/tagsFlows/followTag.spec.js @@ -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'); }); }); diff --git a/cypress/integration/seededFlows/tagsFlows/previewProfileFromTagIndex.spec.js b/cypress/integration/seededFlows/tagsFlows/previewProfileFromTagIndex.spec.js index 0b7f0e1e9..4e61cc28f 100644 --- a/cypress/integration/seededFlows/tagsFlows/previewProfileFromTagIndex.spec.js +++ b/cypress/integration/seededFlows/tagsFlows/previewProfileFromTagIndex.spec.js @@ -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'); }); }); });