Accessible names for follow buttons (#14389)
* added follow hidden tags for accessibility * fixed failing tests * replaced hidden span with screen-reader-only with aria-label * add aria-label dynamically to follow buttons * fixed followButtons * fixed cypress tests and updated addAriaLabelToButton helper * Fixed failing tests * fixed failing tests * Update cypress/integration/seededFlows/notificationsFlows/followUserFromNotifications.spec.js Co-authored-by: Suzanne Aitchison <suzanne@forem.com> Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
This commit is contained in:
parent
5fc3f52299
commit
42c9a10f57
33 changed files with 231 additions and 87 deletions
|
|
@ -187,7 +187,7 @@ function buildArticleHTML(article) {
|
|||
</a>
|
||||
</div>
|
||||
<div class="print-hidden">
|
||||
<button class="crayons-btn follow-action-button whitespace-nowrap follow-user w-100" data-info='{"id": ${article.user_id}, "className": "User", "style": "full"}'>Follow</button>
|
||||
<button class="crayons-btn follow-action-button whitespace-nowrap follow-user w-100" data-info='{"id": ${article.user_id}, "className": "User", "style": "full", "name": "${article.user.name}"}'>Follow</button>
|
||||
</div>
|
||||
<div class="author-preview-metadata-container" data-author-id="${article.user_id}"></div>
|
||||
</div>
|
||||
|
|
@ -196,7 +196,7 @@ function buildArticleHTML(article) {
|
|||
|
||||
var meta = `
|
||||
<div class="crayons-story__meta">
|
||||
<div class="crayons-story__author-pic">
|
||||
<div class="crayons-story__author-pic">
|
||||
${organizationLogo}
|
||||
<a href="/${profileUsername}" class="crayons-avatar ${organizationClasses}">
|
||||
<img src="${picUrl}" alt="${profileUsername} profile" class="crayons-avatar__image" loading="lazy" />
|
||||
|
|
@ -262,13 +262,13 @@ function buildArticleHTML(article) {
|
|||
<span class="bm-success">Saved</span>\
|
||||
</button>';
|
||||
} else if (article.class_name === 'User') {
|
||||
saveButton =
|
||||
'<button type="button" class="crayons-btn crayons-btn--secondary crayons-btn--icon-left fs-s bookmark-button article-engagement-count engage-button follow-action-button follow-user"\
|
||||
data-info=\'{"id":' +
|
||||
article.id +
|
||||
',"className":"User"}\' data-follow-action-button>\
|
||||
\
|
||||
</button>';
|
||||
saveButton = `
|
||||
<button type="button"
|
||||
class="crayons-btn crayons-btn--secondary crayons-btn--icon-left fs-s bookmark-button article-engagement-count engage-button follow-action-button follow-user"
|
||||
data-info='{"id": ${article.id},"className":"User", "name": "${article.user.name}"}'
|
||||
data-follow-action-button>
|
||||
|
||||
</button>`;
|
||||
}
|
||||
|
||||
var videoHTML = '';
|
||||
|
|
|
|||
|
|
@ -123,6 +123,13 @@ module ApplicationHelper
|
|||
return if followable == DELETED_USER
|
||||
|
||||
user_follow = followable.instance_of?(User) ? "follow-user" : ""
|
||||
followable_type = if followable.respond_to?(:decorated?) && followable.decorated?
|
||||
followable.object.class.name.downcase
|
||||
else
|
||||
followable.class.name.downcase
|
||||
end
|
||||
|
||||
followable_name = followable.name
|
||||
|
||||
tag.button(
|
||||
"Follow",
|
||||
|
|
@ -131,11 +138,13 @@ module ApplicationHelper
|
|||
data: {
|
||||
info: {
|
||||
id: followable.id,
|
||||
className: followable.class.name,
|
||||
className: followable_type,
|
||||
name: followable_name,
|
||||
style: style
|
||||
}
|
||||
},
|
||||
class: "crayons-btn follow-action-button whitespace-nowrap #{classes} #{user_follow}",
|
||||
aria: { label: "Follow #{followable_type}: #{followable_name}" },
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ Object {
|
|||
>
|
||||
<button
|
||||
class="crayons-btn follow-action-button whitespace-nowrap follow-user w-100"
|
||||
data-info="{\\"id\\":23289,\\"className\\":\\"User\\",\\"style\\":\\"full\\"}"
|
||||
data-info="{\\"id\\":23289,\\"className\\":\\"User\\",\\"name\\":\\"Stella Macejkovic\\",\\"style\\":\\"full\\"}"
|
||||
>
|
||||
Follow
|
||||
</button>
|
||||
|
|
@ -362,7 +362,7 @@ Object {
|
|||
>
|
||||
<button
|
||||
class="crayons-btn follow-action-button whitespace-nowrap follow-user w-100"
|
||||
data-info="{\\"id\\":23289,\\"className\\":\\"User\\",\\"style\\":\\"full\\"}"
|
||||
data-info="{\\"id\\":23289,\\"className\\":\\"User\\",\\"name\\":\\"Stella Macejkovic\\",\\"style\\":\\"full\\"}"
|
||||
>
|
||||
Follow
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -9,18 +9,67 @@ import { getInstantClick } from '../topNavigation/utilities';
|
|||
* @param {string} style The style of the button from its "info" data attribute
|
||||
*/
|
||||
function addButtonFollowText(button, style) {
|
||||
const { name, className } = JSON.parse(button.dataset.info);
|
||||
|
||||
switch (style) {
|
||||
case 'small':
|
||||
addAriaLabelToButton({
|
||||
button,
|
||||
followName: name,
|
||||
followType: className,
|
||||
style: 'follow',
|
||||
});
|
||||
button.textContent = '+';
|
||||
break;
|
||||
case 'follow-back':
|
||||
addAriaLabelToButton({
|
||||
button,
|
||||
followName: name,
|
||||
followType: className,
|
||||
style: 'follow-back',
|
||||
});
|
||||
button.textContent = 'Follow back';
|
||||
break;
|
||||
default:
|
||||
addAriaLabelToButton({
|
||||
button,
|
||||
followName: name,
|
||||
followType: className,
|
||||
style: 'follow',
|
||||
});
|
||||
button.textContent = 'Follow';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the aria-label of the button
|
||||
*
|
||||
* @param {HTMLElement} button The Follow button to update.
|
||||
* @param {string} followType The followableType of the button.
|
||||
* @param {string} followName The name of the followable to be followed.
|
||||
* @param {string} style The style of the button from its "info" data attribute
|
||||
*/
|
||||
function addAriaLabelToButton({ button, followType, followName, style = '' }) {
|
||||
let label = '';
|
||||
switch (style) {
|
||||
case 'follow':
|
||||
label = `Follow ${followType.toLowerCase()}: ${followName}`;
|
||||
break;
|
||||
case 'follow-back':
|
||||
label = `Follow ${followType.toLowerCase()} back: ${followName}`;
|
||||
break;
|
||||
case 'following':
|
||||
label = `Unfollow ${followType.toLowerCase()}: ${followName}`;
|
||||
break;
|
||||
case 'self':
|
||||
label = `Edit profile`;
|
||||
break;
|
||||
default:
|
||||
label = `Follow ${followType.toLowerCase()}: ${followName}`;
|
||||
}
|
||||
button.setAttribute('aria-label', label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text content of the button to the correct 'Following' state
|
||||
*
|
||||
|
|
@ -81,11 +130,18 @@ function optimisticallyUpdateButtonUI(button) {
|
|||
* @param {string} style Style of the follow button (e.g. 'small')
|
||||
*/
|
||||
function updateFollowingButton(button, style) {
|
||||
const { name, className } = JSON.parse(button.dataset.info);
|
||||
button.dataset.verb = 'follow';
|
||||
addButtonFollowingText(button, style);
|
||||
button.classList.remove('crayons-btn--primary');
|
||||
button.classList.remove('crayons-btn--secondary');
|
||||
button.classList.add('crayons-btn--outlined');
|
||||
addAriaLabelToButton({
|
||||
button,
|
||||
followName: name,
|
||||
followType: className,
|
||||
style: 'following',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -96,6 +152,12 @@ function updateFollowingButton(button, style) {
|
|||
function updateUserOwnFollowButton(button) {
|
||||
button.dataset.verb = 'self';
|
||||
button.textContent = 'Edit profile';
|
||||
addAriaLabelToButton({
|
||||
button,
|
||||
followName: '',
|
||||
followType: '',
|
||||
style: 'self',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -251,11 +313,14 @@ function initializeAllUserFollowButtons() {
|
|||
Array.from(buttons, (button) => {
|
||||
button.dataset.fetched = 'fetched';
|
||||
const { userStatus } = document.body.dataset;
|
||||
const buttonInfo = JSON.parse(button.dataset.info);
|
||||
const { name, className } = buttonInfo;
|
||||
|
||||
if (userStatus === 'logged-out') {
|
||||
const { style } = JSON.parse(button.dataset.info);
|
||||
addButtonFollowText(button, style);
|
||||
} else {
|
||||
addAriaLabelToButton({ button, followType: className, followName: name });
|
||||
const { id: userId } = JSON.parse(button.dataset.info);
|
||||
if (userIds[userId]) {
|
||||
userIds[userId].push(button);
|
||||
|
|
@ -317,7 +382,9 @@ function initializeNonUserFollowButtons() {
|
|||
nonUserFollowButtons.forEach((button) => {
|
||||
const { info } = button.dataset;
|
||||
const buttonInfo = JSON.parse(info);
|
||||
if (buttonInfo.className === 'Tag' && user) {
|
||||
const { className, name } = buttonInfo;
|
||||
addAriaLabelToButton({ button, followType: className, followName: name });
|
||||
if (className === 'Tag' && user) {
|
||||
// We don't need to make a network request to 'fetch' the status of tag buttons
|
||||
button.dataset.fetched = true;
|
||||
const initialButtonFollowState = followedTagIds.has(buttonInfo.id)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ export const MinimalProfilePreviewCard = ({
|
|||
data-info={JSON.stringify({
|
||||
id: userId,
|
||||
className: 'User',
|
||||
name,
|
||||
style: 'full',
|
||||
})}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
<div class="print-hidden">
|
||||
<button
|
||||
class="crayons-btn follow-action-button whitespace-nowrap follow-user w-100"
|
||||
data-info='{"id": <%= story.user_id %>, "className": "User", "style": "full"}'>
|
||||
data-info='{"id": <%= story.user_id %>, "className": "User", "style": "full", "name": "<%= story.cached_user.name %>"}'>
|
||||
Follow
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
</a>
|
||||
<a class="follow-action-button sidebar-nav-link-follow crayons-btn crayons-btn--s"
|
||||
href="#" id="sidebar-nav-link-follow-<%= tag_array.second %>"
|
||||
data-info='{"id":<%= tag_array.first %>,"className":"Tag"}'>
|
||||
data-info='{"id":<%= tag_array.first %>,"className":"Tag", "name": "<%= tag_array.second %>"}'>
|
||||
Follow
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,12 @@
|
|||
</span>
|
||||
|
||||
<div class="profile-header__actions">
|
||||
<button id="user-follow-butt" class="crayons-btn whitespace-nowrap follow-action-button user-profile-follow-button" data-info='{"id":<%= @user.id %>,"className":"<%= @user.class.name %>"}'>Follow</button>
|
||||
<button
|
||||
id="user-follow-butt"
|
||||
class="crayons-btn whitespace-nowrap follow-action-button user-profile-follow-button"
|
||||
data-info='{"id":<%= @user.id %>,"className":"<%= @user.class.name %>", "name": "<%= @user.name %>"}'>
|
||||
Follow
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,10 @@
|
|||
</div>
|
||||
</a>
|
||||
<div class="ltag__user__content">
|
||||
<h2><a href="/<%= organization.slug %>" class="ltag__user__link"><%= organization.name %></a><%= follow_button %></h2>
|
||||
<h2>
|
||||
<a href="/<%= organization.slug %>" class="ltag__user__link"><%= organization.name %></a>
|
||||
<%= follow_button(organization) %>
|
||||
</h2>
|
||||
<div class="ltag__user__summary">
|
||||
<a href="/<%= organization.slug %>" class="ltag__user__link">
|
||||
<%= organization.summary %>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
</a>
|
||||
<a href="/<%= podcast.slug %>" style="display:block">
|
||||
<h2 class="podcastliquidtag__info__podcasttitle">
|
||||
<%= podcast.title %> <button class="crayons-btn follow-action-button" data-info='{"id":<%= podcast.id %>,"className":"<%= podcast.class.name %>"}'> </button>
|
||||
<%= podcast.title %> <button class="crayons-btn follow-action-button" data-info='{"id":<%= podcast.id %>,"className":"<%= podcast.class.name %>", "name": <%= podcast.name %>}'> </button>
|
||||
|
||||
</h2>
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,12 @@
|
|||
<div class="tag-or-query-header-container">
|
||||
<h1><img class="record main-image" src="<%= Images::Optimizer.call(@podcast.image_url, crop: "fill", width: 420, height: 420) %>"
|
||||
alt="<%= @podcast.title %>" /> <%= @podcast.title %>
|
||||
<button id="user-follow-butt" class="crayons-btn follow-action-button user-profile-follow-button" data-info='{"id":<%= @podcast.id %>,"className":"<%= @podcast.class.name %>"}'> </button>
|
||||
<button
|
||||
id="user-follow-butt"
|
||||
class="crayons-btn follow-action-button user-profile-follow-button"
|
||||
data-info='{"id":<%= @podcast.id %>,"className":"<%= @podcast.class.name %>", "name": "<%= @podcast.name %>"}'>
|
||||
|
||||
</button>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,12 @@
|
|||
<a href="/<%= @podcast.slug %>">
|
||||
<img aria-hidden="true" alt="<%= @podcast.title %>" src="<%= optimized_image_url(@podcast.image_url, width: 60, quality: 80) %>" /><%= @podcast.title %>
|
||||
</a>
|
||||
<button id="user-follow-butt" class="crayons-btn follow-action-button" data-info='{"id":<%= @podcast.id %>,"className":"<%= @podcast.class.name %>"}'> </button>
|
||||
<button
|
||||
id="user-follow-butt"
|
||||
class="crayons-btn follow-action-button"
|
||||
data-info='{"id":<%= @podcast.id %>,"className":"<%= @podcast.class.name %>", "name": "<%= @podcast.name %>"}'>
|
||||
|
||||
</button>
|
||||
</h2>
|
||||
<% if @episode.title.size > 60 %>
|
||||
<h1 class="smaller"><%= @episode.title %></h1>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,12 @@
|
|||
<% end %>
|
||||
</h1>
|
||||
<% if @tag_model %>
|
||||
<button id="user-follow-butt" class="crayons-btn follow-action-button" data-info='{"id":<%= @tag_model.id %>,"className":"Tag"}'>Follow</button>
|
||||
<button
|
||||
id="user-follow-butt"
|
||||
class="crayons-btn follow-action-button"
|
||||
data-info='{"id":<%= @tag_model.id %>,"className":"Tag", "name": "<%= @tag_model.pretty_name || @tag %>"}'>
|
||||
Follow
|
||||
</button>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if @tag_model && @tag_model.short_summary.present? %>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
<div class="mt-auto">
|
||||
<button
|
||||
class="crayons-btn crayons-btn--secondary follow-action-button"
|
||||
data-info='{"id":<%= tag.id %>,"className":"Tag", "followStyle":"secondary"}'>
|
||||
data-info='{"id":<%= tag.id %>,"className":"Tag", "followStyle":"secondary", "name": "<%= tag.name %>"}'>
|
||||
Follow
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
</div>
|
||||
<% end %>
|
||||
<div class="ltag__user__content">
|
||||
<h2><%= link_to_if user_path.present?, user.name, user_path, class: "ltag__user__link" %><%= follow_button %></h2>
|
||||
<h2><%= link_to_if user_path.present?, user.name, user_path, class: "ltag__user__link" %><%= follow_button(user) %></h2>
|
||||
<div class="ltag__user__summary">
|
||||
<%= link_to_if user_path.present?, user.tag_line, user_path, class: "ltag__user__link" %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
<button class="chat-action-button crayons-btn crayons-btn--outlined hidden" id="modal-opener">Chat</button>
|
||||
</a>
|
||||
<% end %>
|
||||
<button id="user-follow-butt" class="crayons-btn whitespace-nowrap follow-action-button user-profile-follow-button follow-user" data-info='{"id":<%= @user.id %>,"className":"<%= @user.class.name %>"}'>Follow</button>
|
||||
<button id="user-follow-butt" class="crayons-btn whitespace-nowrap follow-action-button user-profile-follow-button follow-user" data-info='{"id":<%= @user.id %>,"className":"<%= @user.class.name %>", "name": "<%= @user.name %>"}'>Follow</button>
|
||||
<div class="profile-dropdown ml-2 relative hidden" data-username="<%= @user.username %>">
|
||||
<button id="user-profile-dropdown" aria-expanded="false" aria-controls="user-profile-dropdownmenu" aria-haspopup="true" class="crayons-btn crayons-btn--ghost-dimmed crayons-btn--icon">
|
||||
<%= inline_svg_tag("overflow-horizontal.svg", class: "dropdown-icon crayons-icon", aria: true, title: "User actions") %>
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@ describe('Follow author from article sidebar', () => {
|
|||
cy.intercept('/follows').as('followRequest');
|
||||
|
||||
cy.findByRole('complementary', { name: 'Author details' }).within(() => {
|
||||
cy.findByRole('button', { name: 'Follow' }).as('followButton');
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).as(
|
||||
'followButton',
|
||||
);
|
||||
cy.get('@followButton').click();
|
||||
|
||||
cy.wait('@followRequest');
|
||||
cy.get('@followButton').should('have.text', 'Following');
|
||||
|
||||
cy.get('@followButton').click();
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ describe('Follow from article liquid tag', () => {
|
|||
|
||||
it('Follows a user from an article liquid tag', () => {
|
||||
cy.findByRole('main').within(() => {
|
||||
cy.findAllByRole('button', { name: 'Follow' })
|
||||
.first()
|
||||
.as('followUserButton');
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).as(
|
||||
'followUserButton',
|
||||
);
|
||||
cy.get('@followUserButton').should('have.text', 'Follow');
|
||||
cy.get('@followUserButton').click();
|
||||
cy.get('@followUserButton').should('have.text', 'Following');
|
||||
|
|
@ -66,10 +66,10 @@ describe('Follow from article liquid tag', () => {
|
|||
|
||||
it('Follows a user from an article liquid tag', () => {
|
||||
cy.findByRole('main').within(() => {
|
||||
cy.findAllByRole('button', { name: 'Follow back' })
|
||||
.first()
|
||||
.as('followUserButton');
|
||||
cy.get('@followUserButton').should('have.text', 'Follow back');
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).as(
|
||||
'followUserButton',
|
||||
);
|
||||
cy.get('@followUserButton').should('have.text', 'Follow');
|
||||
cy.get('@followUserButton').click();
|
||||
cy.get('@followUserButton').should('have.text', 'Following');
|
||||
cy.get('@followUserButton').click();
|
||||
|
|
@ -104,9 +104,9 @@ describe('Follow from article liquid tag', () => {
|
|||
|
||||
it('Follows a tag from an article liquid tag', () => {
|
||||
cy.findByRole('main').within(() => {
|
||||
cy.findAllByRole('button', { name: 'Follow' })
|
||||
.last()
|
||||
.as('followTagButton');
|
||||
cy.findByRole('button', { name: 'Follow tag: tag1' }).as(
|
||||
'followTagButton',
|
||||
);
|
||||
cy.get('@followTagButton').should('have.text', 'Follow');
|
||||
cy.get('@followTagButton').click();
|
||||
cy.get('@followTagButton').should('have.text', 'Following');
|
||||
|
|
|
|||
|
|
@ -78,11 +78,15 @@ describe('Preview user profile from article page', () => {
|
|||
cy.findByText('Edinburgh');
|
||||
cy.findByText('University of Life');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', {
|
||||
name: 'Follow user: Admin McAdmin',
|
||||
}).click();
|
||||
|
||||
// Wait for Follow button to disappear and Following button to be initialized
|
||||
cy.findByRole('button', { name: 'Follow' }).should('not.exist');
|
||||
cy.findByRole('button', { name: 'Following' });
|
||||
cy.findByRole('button', {
|
||||
name: 'Follow user: Admin McAdmin',
|
||||
}).should('not.exist');
|
||||
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
|
||||
});
|
||||
|
||||
// Check we can close the preview dropdown
|
||||
|
|
@ -117,11 +121,15 @@ describe('Preview user profile from article page', () => {
|
|||
cy.findByText('Edinburgh');
|
||||
cy.findByText('University of Life');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', {
|
||||
name: 'Follow user: Admin McAdmin',
|
||||
}).click();
|
||||
|
||||
// Wait for Follow button to disappear and Following button to be initialized
|
||||
cy.findByRole('button', { name: 'Follow' }).should('not.exist');
|
||||
cy.findByRole('button', { name: 'Following' });
|
||||
cy.findByRole('button', {
|
||||
name: 'Follow user: Admin McAdmin',
|
||||
}).should('not.exist');
|
||||
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -137,10 +145,14 @@ describe('Preview user profile from article page', () => {
|
|||
cy.findAllByTestId('profile-preview-card')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', {
|
||||
name: 'Follow user: Admin McAdmin',
|
||||
}).click();
|
||||
// Confirm the follow button has been updated
|
||||
cy.findByRole('button', { name: 'Follow' }).should('not.exist');
|
||||
cy.findByRole('button', { name: 'Following' });
|
||||
cy.findByRole('button', {
|
||||
name: 'Follow user: Admin McAdmin',
|
||||
}).should('not.exist');
|
||||
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
|
||||
});
|
||||
|
||||
// Close the preview card so the next preview button can be clicked
|
||||
|
|
@ -153,7 +165,7 @@ describe('Preview user profile from article page', () => {
|
|||
|
||||
cy.findAllByTestId('profile-preview-card')
|
||||
.last()
|
||||
.findByRole('button', { name: 'Following' });
|
||||
.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
|
||||
});
|
||||
|
||||
it('should detach listeners on preview card close', () => {
|
||||
|
|
@ -280,7 +292,7 @@ describe('Preview user profile from article page', () => {
|
|||
name: 'Admin McAdmin',
|
||||
}).should('have.focus');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' });
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' });
|
||||
cy.findByText('Admin user summary');
|
||||
cy.findByText('Software developer at Company');
|
||||
cy.findByText('Edinburgh');
|
||||
|
|
|
|||
|
|
@ -32,11 +32,13 @@ describe('Preview profile from series', () => {
|
|||
cy.findByText('Edinburgh');
|
||||
cy.findByText('University of Life');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', { name: 'Follow user: Series User' }).click();
|
||||
|
||||
// Check that the follow button has updated as expected
|
||||
cy.findByRole('button', { name: 'Follow' }).should('not.exist');
|
||||
cy.findByRole('button', { name: 'Following' });
|
||||
cy.findByRole('button', { name: 'Follow user: Series User' }).should(
|
||||
'not.exist',
|
||||
);
|
||||
cy.findByRole('button', { name: 'Unfollow user: Series User' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ describe('View article discussion', () => {
|
|||
cy.findByRole('button', { name: 'Admin McAdmin profile details' }).click();
|
||||
|
||||
cy.findByTestId('profile-preview-card').within(() => {
|
||||
cy.findByRole('button', { name: 'Follow' }).as('userFollowButton');
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).as(
|
||||
'userFollowButton',
|
||||
);
|
||||
cy.get('@userFollowButton').click();
|
||||
|
||||
// Confirm the follow button has been updated
|
||||
|
|
|
|||
|
|
@ -27,11 +27,13 @@ describe('Home feed profile preview cards', () => {
|
|||
cy.findByText('Edinburgh');
|
||||
cy.findByText('University of Life');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).click();
|
||||
|
||||
// Check that following status has been updated
|
||||
cy.findByRole('button', { name: 'Follow' }).should('not.exist');
|
||||
cy.findByRole('button', { name: 'Following' });
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).should(
|
||||
'not.exist',
|
||||
);
|
||||
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ describe('Logged out Home feed', () => {
|
|||
cy.findByText('Edinburgh');
|
||||
cy.findByText('University of Life');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).click();
|
||||
});
|
||||
|
||||
// Clicking a follow button while logged out should always trigger the log in to continue modal
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ describe('Show log in modal', () => {
|
|||
verifyLoginModalBehavior(() =>
|
||||
cy
|
||||
.findByRole('complementary', { name: 'Author details' })
|
||||
.findByRole('button', { name: 'Follow' }),
|
||||
.findByRole('button', { name: 'Follow user: Admin McAdmin' }),
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -72,13 +72,15 @@ describe('Show log in modal', () => {
|
|||
cy.get('[data-follow-clicks-initialized]');
|
||||
|
||||
verifyLoginModalBehavior(() =>
|
||||
cy.findAllByRole('button', { name: 'Follow' }).first(),
|
||||
cy.findByRole('button', { name: 'Follow tag: tag1' }),
|
||||
);
|
||||
|
||||
cy.visit('/t/tag1');
|
||||
cy.findByRole('heading', { name: '# tag1' });
|
||||
|
||||
verifyLoginModalBehavior(() => cy.findByRole('button', { name: 'Follow' }));
|
||||
verifyLoginModalBehavior(() =>
|
||||
cy.findByRole('button', { name: 'Follow tag: tag1' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should show login modal for user profile follow button click', () => {
|
||||
|
|
@ -86,7 +88,9 @@ describe('Show log in modal', () => {
|
|||
cy.get('[data-follow-clicks-initialized]');
|
||||
|
||||
cy.findByRole('heading', { name: 'Admin McAdmin' });
|
||||
verifyLoginModalBehavior(() => cy.findByRole('button', { name: 'Follow' }));
|
||||
verifyLoginModalBehavior(() =>
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should show login modal for podcast follow button click', () => {
|
||||
|
|
@ -97,6 +101,8 @@ describe('Show log in modal', () => {
|
|||
name: 'Developer on Fire Developer on Fire Follow',
|
||||
});
|
||||
|
||||
verifyLoginModalBehavior(() => cy.findByRole('button', { name: 'Follow' }));
|
||||
verifyLoginModalBehavior(() =>
|
||||
cy.findByRole('button', { name: 'Follow podcast: Developer on Fire' }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ describe('Logged out - tag index page', () => {
|
|||
cy.findByText('Edinburgh');
|
||||
cy.findByText('University of Life');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).click();
|
||||
});
|
||||
|
||||
// Clicking a follow button while logged out should always trigger the log in to continue modal
|
||||
|
|
|
|||
|
|
@ -10,16 +10,15 @@ describe('Follow user from notifications', () => {
|
|||
|
||||
it('Follows and unfollows a user from a follow notification', () => {
|
||||
cy.findByRole('heading', { name: 'Notifications' });
|
||||
cy.intercept('/follows').as('followsRequest');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow back' }).as('followButton');
|
||||
cy.findByRole('button', { name: 'Follow user back: User' }).as(
|
||||
'followButton',
|
||||
);
|
||||
cy.get('@followButton').click();
|
||||
cy.wait('@followsRequest');
|
||||
|
||||
cy.get('@followButton').should('have.text', 'Following');
|
||||
|
||||
cy.get('@followButton').click();
|
||||
cy.wait('@followsRequest');
|
||||
cy.get('@followButton').should('have.text', 'Follow back');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ describe('Follow podcast', () => {
|
|||
cy.findByRole('heading', {
|
||||
name: 'Developer on Fire Developer on Fire Follow',
|
||||
});
|
||||
cy.findByRole('button', { name: 'Follow' }).as('followButton');
|
||||
cy.findByRole('button', { name: 'Follow podcast: Developer on Fire' }).as(
|
||||
'followButton',
|
||||
);
|
||||
|
||||
cy.get('@followButton').click();
|
||||
// Inner text should now be following
|
||||
|
|
@ -21,7 +23,9 @@ describe('Follow podcast', () => {
|
|||
|
||||
// Check that state is persisted on refresh
|
||||
cy.visitAndWaitForUserSideEffects('/developeronfire');
|
||||
cy.findByRole('button', { name: 'Following' }).as('followButton');
|
||||
cy.findByRole('button', { name: 'Unfollow podcast: Developer on Fire' }).as(
|
||||
'followButton',
|
||||
);
|
||||
|
||||
// Check it reverts back to Follow on click
|
||||
cy.get('@followButton').click();
|
||||
|
|
@ -29,6 +33,8 @@ describe('Follow podcast', () => {
|
|||
|
||||
// Check that state is persisted on refresh
|
||||
cy.visitAndWaitForUserSideEffects('/developeronfire');
|
||||
cy.findByRole('button', { name: 'Follow' }).as('followButton');
|
||||
cy.findByRole('button', { name: 'Follow podcast: Developer on Fire' }).as(
|
||||
'followButton',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,20 +12,24 @@ describe('Follow user from profile page', () => {
|
|||
it('follows and unfollows an organisation', () => {
|
||||
cy.intercept('/follows').as('followsRequest');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', {
|
||||
name: 'Follow organization: Bachmanity',
|
||||
}).click();
|
||||
cy.wait('@followsRequest');
|
||||
cy.findByRole('button', { name: 'Following' });
|
||||
cy.findByRole('button', { name: 'Unfollow organization: Bachmanity' });
|
||||
|
||||
// Check that the update persists after reload
|
||||
cy.visitAndWaitForUserSideEffects('/bachmanity');
|
||||
|
||||
cy.findByRole('button', { name: 'Following' }).click();
|
||||
cy.findByRole('button', {
|
||||
name: 'Unfollow organization: Bachmanity',
|
||||
}).click();
|
||||
cy.wait('@followsRequest');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' });
|
||||
cy.findByRole('button', { name: 'Follow organization: Bachmanity' });
|
||||
|
||||
// Check that the update persists after reload
|
||||
cy.visitAndWaitForUserSideEffects('/bachmanity');
|
||||
cy.findByRole('button', { name: 'Follow' });
|
||||
cy.findByRole('button', { name: 'Follow organization: Bachmanity' });
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,20 +12,24 @@ describe('Follow user from profile page', () => {
|
|||
it('follows and unfollows a user', () => {
|
||||
cy.intercept('/follows').as('followsRequest');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', {
|
||||
name: 'Follow user: Article Editor v1 User',
|
||||
}).click();
|
||||
cy.wait('@followsRequest');
|
||||
cy.findByRole('button', { name: 'Following' });
|
||||
cy.findByRole('button', { name: 'Unfollow user: Article Editor v1 User' });
|
||||
|
||||
// Check that the update persists after reload
|
||||
cy.visitAndWaitForUserSideEffects('/article_editor_v1_user');
|
||||
|
||||
cy.findByRole('button', { name: 'Following' }).click();
|
||||
cy.findByRole('button', {
|
||||
name: 'Unfollow user: Article Editor v1 User',
|
||||
}).click();
|
||||
cy.wait('@followsRequest');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' });
|
||||
cy.findByRole('button', { name: 'Follow user: Article Editor v1 User' });
|
||||
|
||||
// Check that the update persists after reload
|
||||
cy.visitAndWaitForUserSideEffects('/article_editor_v1_user');
|
||||
cy.findByRole('button', { name: 'Follow' });
|
||||
cy.findByRole('button', { name: 'Follow user: Article Editor v1 User' });
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@ describe('Follow user from search results', () => {
|
|||
|
||||
cy.intercept('/follows').as('followsRequest');
|
||||
|
||||
cy.findAllByRole('button', { name: 'Follow' }).first().as('followButton');
|
||||
cy.findByRole('button', { name: 'Follow user: article_editor_v1_user' }).as(
|
||||
'followButton',
|
||||
);
|
||||
cy.get('@followButton').click();
|
||||
|
||||
cy.wait('@followsRequest');
|
||||
|
|
|
|||
|
|
@ -28,11 +28,13 @@ describe('Preview profile from post search results', () => {
|
|||
cy.findByText('Edinburgh');
|
||||
cy.findByText('University of Life');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).click();
|
||||
|
||||
// Check that following status has been updated
|
||||
cy.findByRole('button', { name: 'Follow' }).should('not.exist');
|
||||
cy.findByRole('button', { name: 'Following' });
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).should(
|
||||
'not.exist',
|
||||
);
|
||||
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ describe('Follow tag', () => {
|
|||
|
||||
it('Follows and unfollows a tag from the tag index page', () => {
|
||||
cy.intercept('/follows').as('followsRequest');
|
||||
cy.findAllByRole('button', { name: 'Follow' }).first().as('followButton');
|
||||
cy.findByRole('button', { name: 'Follow tag: tag1' }).as('followButton');
|
||||
|
||||
cy.get('@followButton').click();
|
||||
cy.wait('@followsRequest');
|
||||
|
|
@ -43,7 +43,7 @@ describe('Follow tag', () => {
|
|||
|
||||
it('Follows and unfollows a tag from the tag feed page', () => {
|
||||
cy.intercept('/follows').as('followsRequest');
|
||||
cy.findByRole('button', { name: 'Follow' }).as('followButton');
|
||||
cy.findByRole('button', { name: 'Follow tag: tag1' }).as('followButton');
|
||||
|
||||
cy.get('@followButton').click();
|
||||
cy.wait('@followsRequest');
|
||||
|
|
|
|||
|
|
@ -28,11 +28,13 @@ describe('Preview profile from the tag index page', () => {
|
|||
cy.findByText('Edinburgh');
|
||||
cy.findByText('University of Life');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow' }).click();
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).click();
|
||||
|
||||
// Check that following status has been updated
|
||||
cy.findByRole('button', { name: 'Follow' }).should('not.exist');
|
||||
cy.findByRole('button', { name: 'Following' });
|
||||
cy.findByRole('button', { name: 'Follow user: Admin McAdmin' }).should(
|
||||
'not.exist',
|
||||
);
|
||||
cy.findByRole('button', { name: 'Unfollow user: Admin McAdmin' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue