fix: more consistent toggle button aria-label/title (#1626)
* fix: more consistent toggle button aria-label/title fixes #1624 * fixup * fix test
This commit is contained in:
parent
f8356c2eaf
commit
edc014cf8c
|
@ -1,5 +1,8 @@
|
||||||
|
<!-- Toggle buttons should have an immutable label, e.g. a mute/unmute button should just always say
|
||||||
|
"mute." For sighted users, though, I think it's nice if the title changes when the action changes.
|
||||||
|
See http://w3c.github.io/aria-practices/#button -->
|
||||||
<button type="button"
|
<button type="button"
|
||||||
title={label}
|
title={pressable ? (pressed ? pressedLabel : label) : label}
|
||||||
aria-label={label}
|
aria-label={label}
|
||||||
aria-pressed={pressable ? !!pressed : undefined}
|
aria-pressed={pressable ? !!pressed : undefined}
|
||||||
aria-hidden={ariaHidden}
|
aria-hidden={ariaHidden}
|
||||||
|
@ -102,6 +105,12 @@
|
||||||
if (elementId) {
|
if (elementId) {
|
||||||
this.refs.node.setAttribute('id', elementId)
|
this.refs.node.setAttribute('id', elementId)
|
||||||
}
|
}
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
const { pressable, pressedLabel, label } = this.get()
|
||||||
|
if (pressable && ((!pressedLabel || !label) || pressedLabel === label)) {
|
||||||
|
throw new Error('pressable buttons should have a label and a pressedLabel different from each other')
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
ondestroy () {
|
ondestroy () {
|
||||||
const { clickListener } = this.get()
|
const { clickListener } = this.get()
|
||||||
|
@ -117,6 +126,7 @@
|
||||||
elementId: undefined,
|
elementId: undefined,
|
||||||
pressable: false,
|
pressable: false,
|
||||||
pressed: false,
|
pressed: false,
|
||||||
|
pressedLabel: undefined,
|
||||||
className: undefined,
|
className: undefined,
|
||||||
sameColorWhenPressed: false,
|
sameColorWhenPressed: false,
|
||||||
ariaHidden: false,
|
ariaHidden: false,
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
{#if pinnable}
|
{#if pinnable}
|
||||||
<IconButton pressable="true"
|
<IconButton pressable="true"
|
||||||
pressed={$pinnedPage === href}
|
pressed={$pinnedPage === href}
|
||||||
label={$pinnedPage === href ? 'Unpin timeline' : 'Pin timeline'}
|
label="Pin timeline"
|
||||||
|
pressedLabel="Timeline pinned"
|
||||||
href="#fa-thumb-tack"
|
href="#fa-thumb-tack"
|
||||||
on:click="onPinClick(event)" />
|
on:click="onPinClick(event)" />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
className="compose-toolbar-button"
|
className="compose-toolbar-button"
|
||||||
label="{poll && poll.options && poll.options.length ? 'Remove poll' : 'Add poll'}"
|
label="Add poll"
|
||||||
|
pressedLabel="Remove poll"
|
||||||
href="#fa-bar-chart"
|
href="#fa-bar-chart"
|
||||||
on:click="onPollClick()"
|
on:click="onPollClick()"
|
||||||
pressable="true"
|
pressable="true"
|
||||||
|
@ -30,7 +31,8 @@
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
className="compose-toolbar-button"
|
className="compose-toolbar-button"
|
||||||
label={contentWarningShown ? 'Remove content warning' : 'Add content warning'}
|
label="Add content warning"
|
||||||
|
pressedLabel="Remove content warning"
|
||||||
href="#fa-exclamation-triangle"
|
href="#fa-exclamation-triangle"
|
||||||
on:click="onContentWarningClick()"
|
on:click="onContentWarningClick()"
|
||||||
pressable="true"
|
pressable="true"
|
||||||
|
|
|
@ -46,11 +46,13 @@
|
||||||
on:click="prev()"
|
on:click="prev()"
|
||||||
/>
|
/>
|
||||||
{#each dots as dot, i (dot.i)}
|
{#each dots as dot, i (dot.i)}
|
||||||
|
<!-- TODO: this should probably be aria-current or something, not a toggle button -->
|
||||||
<IconButton
|
<IconButton
|
||||||
className="media-control-button"
|
className="media-control-button"
|
||||||
svgClassName="media-control-button-svg"
|
svgClassName="media-control-button-svg"
|
||||||
pressable={true}
|
pressable={true}
|
||||||
label="Show {nth(i)} media"
|
label="Show {nth(i)} media"
|
||||||
|
pressedLabel="Showing {nth(i)} media"
|
||||||
pressed={i === scrolledItem}
|
pressed={i === scrolledItem}
|
||||||
href={i === scrolledItem ? '#fa-circle' : '#fa-circle-o'}
|
href={i === scrolledItem ? '#fa-circle' : '#fa-circle-o'}
|
||||||
sameColorWhenPressed={true}
|
sameColorWhenPressed={true}
|
||||||
|
@ -73,7 +75,8 @@
|
||||||
svgClassName="media-control-button-svg"
|
svgClassName="media-control-button-svg"
|
||||||
pressable={true}
|
pressable={true}
|
||||||
pressed={pinchZoomMode}
|
pressed={pinchZoomMode}
|
||||||
label={pinchZoomMode ? 'Disable pinch-zoom mode' : 'Enable pinch-zoom mode'}
|
label="Pinch-zoom mode"
|
||||||
|
pressedLabel="Exit pinch-zoom mode"
|
||||||
href="#fa-search"
|
href="#fa-search"
|
||||||
on:click="togglePinchZoomMode()"
|
on:click="togglePinchZoomMode()"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
<div class="account-profile-follow {shown ? 'shown' : ''}">
|
<div class="account-profile-follow {shown ? 'shown' : ''}">
|
||||||
|
<!--
|
||||||
|
This button has a few different states.
|
||||||
|
- If we're blocking, then it's a normal non-toggle button that unblocks.
|
||||||
|
- Otherwise it's a toggle button that changes whether we're following the account or not.
|
||||||
|
- If a follow is requested, then the button is pressed but shows as "follow requested" with
|
||||||
|
a different icon.
|
||||||
|
-->
|
||||||
<IconButton
|
<IconButton
|
||||||
className="account-profile-follow-icon-button"
|
className="account-profile-follow-icon-button"
|
||||||
label={followLabel}
|
{label}
|
||||||
href={followIcon}
|
{pressedLabel}
|
||||||
pressable="true"
|
{href}
|
||||||
pressed={following}
|
{pressable}
|
||||||
|
{pressed}
|
||||||
big={!$isVeryTinyMobileSize}
|
big={!$isVeryTinyMobileSize}
|
||||||
on:click="onFollowButtonClick(event)"
|
on:click="onFollowButtonClick(event)"
|
||||||
ref:icon
|
ref:icon
|
||||||
|
@ -35,6 +43,11 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
|
oncreate () {
|
||||||
|
if (process.browser) {
|
||||||
|
window.__button = this
|
||||||
|
}
|
||||||
|
},
|
||||||
async onFollowButtonClick (e) {
|
async onFollowButtonClick (e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
@ -75,18 +88,20 @@
|
||||||
followRequested: ({ relationship }) => {
|
followRequested: ({ relationship }) => {
|
||||||
return relationship && relationship.requested
|
return relationship && relationship.requested
|
||||||
},
|
},
|
||||||
followLabel: ({ blocking, following, followRequested }) => {
|
labelExtraText: ({ blocking, following, followRequested }) => {
|
||||||
if (blocking) {
|
if (!blocking && !following && followRequested) {
|
||||||
return 'Unblock'
|
return ' (follow requested)'
|
||||||
} else if (following) {
|
|
||||||
return 'Unfollow'
|
|
||||||
} else if (followRequested) {
|
|
||||||
return 'Unfollow (follow requested)'
|
|
||||||
} else {
|
} else {
|
||||||
return 'Follow'
|
return ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
followIcon: ({ blocking, following, followRequested }) => {
|
label: ({ blocking, labelExtraText }) => {
|
||||||
|
return (blocking ? 'Unblock' : 'Follow') + labelExtraText
|
||||||
|
},
|
||||||
|
pressedLabel: ({ labelExtraText }) => {
|
||||||
|
return 'Unfollow' + labelExtraText
|
||||||
|
},
|
||||||
|
href: ({ blocking, following, followRequested }) => {
|
||||||
if (blocking) {
|
if (blocking) {
|
||||||
return '#fa-unlock'
|
return '#fa-unlock'
|
||||||
} else if (following) {
|
} else if (following) {
|
||||||
|
@ -97,9 +112,13 @@
|
||||||
return '#fa-user-plus'
|
return '#fa-user-plus'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
shown: ({ verifyCredentials, relationship }) => {
|
shown: ({ verifyCredentials, relationship }) => (
|
||||||
return verifyCredentials && relationship && verifyCredentials.id !== relationship.id
|
verifyCredentials && relationship && verifyCredentials.id !== relationship.id
|
||||||
}
|
),
|
||||||
|
pressable: ({ blocking }) => !blocking,
|
||||||
|
pressed: ({ blocking, following, followRequested }) => (
|
||||||
|
!blocking && (following || followRequested)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
IconButton
|
IconButton
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<IconButton
|
<IconButton
|
||||||
className="status-toolbar-reply-button"
|
className="status-toolbar-reply-button"
|
||||||
label={replyLabel}
|
label={replyLabel}
|
||||||
|
pressedLabel="Close reply"
|
||||||
pressable="true"
|
pressable="true"
|
||||||
pressed={replyShown}
|
pressed={replyShown}
|
||||||
href={replyIcon}
|
href={replyIcon}
|
||||||
|
@ -10,6 +11,7 @@
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
label={reblogLabel}
|
label={reblogLabel}
|
||||||
|
pressedLabel="Unboost"
|
||||||
pressable={!reblogDisabled}
|
pressable={!reblogDisabled}
|
||||||
pressed={reblogged}
|
pressed={reblogged}
|
||||||
disabled={reblogDisabled}
|
disabled={reblogDisabled}
|
||||||
|
@ -19,7 +21,8 @@
|
||||||
ref:reblogIcon
|
ref:reblogIcon
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
label={favoriteLabel}
|
label="Favorite"
|
||||||
|
pressedLabel="Unfavorite"
|
||||||
pressable="true"
|
pressable="true"
|
||||||
pressed={favorited}
|
pressed={favorited}
|
||||||
href="#fa-star"
|
href="#fa-star"
|
||||||
|
@ -160,18 +163,18 @@
|
||||||
reblogAnimation: REBLOG_ANIMATION
|
reblogAnimation: REBLOG_ANIMATION
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
replyLabel: ({ replyShown, inReplyToId }) => (
|
replyLabel: ({ inReplyToId }) => (
|
||||||
replyShown ? 'Close reply' : inReplyToId ? 'Reply to thread' : 'Reply'
|
inReplyToId ? 'Reply to thread' : 'Reply'
|
||||||
),
|
),
|
||||||
replyIcon: ({ inReplyToId }) => inReplyToId ? '#fa-reply-all' : '#fa-reply',
|
replyIcon: ({ inReplyToId }) => inReplyToId ? '#fa-reply-all' : '#fa-reply',
|
||||||
reblogLabel: ({ visibility, reblogged }) => {
|
reblogLabel: ({ visibility }) => {
|
||||||
switch (visibility) {
|
switch (visibility) {
|
||||||
case 'private':
|
case 'private':
|
||||||
return 'Cannot be boosted because this is followers-only'
|
return 'Cannot be boosted because this is followers-only'
|
||||||
case 'direct':
|
case 'direct':
|
||||||
return 'Cannot be boosted because this is a direct message'
|
return 'Cannot be boosted because this is a direct message'
|
||||||
default:
|
default:
|
||||||
return reblogged ? 'Unboost' : 'Boost'
|
return 'Boost'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
reblogIcon: ({ visibility }) => {
|
reblogIcon: ({ visibility }) => {
|
||||||
|
@ -193,9 +196,6 @@
|
||||||
}
|
}
|
||||||
return originalStatus.reblogged
|
return originalStatus.reblogged
|
||||||
},
|
},
|
||||||
favoriteLabel: ({ favorited }) => (
|
|
||||||
favorited ? 'Unfavorite' : 'Favorite'
|
|
||||||
),
|
|
||||||
favorited: ({ originalStatusId, $currentStatusModifications, originalStatus }) => {
|
favorited: ({ originalStatusId, $currentStatusModifications, originalStatus }) => {
|
||||||
if ($currentStatusModifications && originalStatusId in $currentStatusModifications.favorites) {
|
if ($currentStatusModifications && originalStatusId in $currentStatusModifications.favorites) {
|
||||||
return $currentStatusModifications.favorites[originalStatusId]
|
return $currentStatusModifications.favorites[originalStatusId]
|
||||||
|
|
|
@ -30,7 +30,8 @@ test('shows account profile 2', async t => {
|
||||||
.expect(accountProfileName.innerText).contains('admin')
|
.expect(accountProfileName.innerText).contains('admin')
|
||||||
.expect(accountProfileUsername.innerText).contains('@admin')
|
.expect(accountProfileUsername.innerText).contains('@admin')
|
||||||
.expect(accountProfileFollowedBy.innerText).match(/follows you/i)
|
.expect(accountProfileFollowedBy.innerText).match(/follows you/i)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unfollow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unfollow')
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('true')
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('true')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
import { Selector as $ } from 'testcafe'
|
import { Selector as $ } from 'testcafe'
|
||||||
import {
|
import {
|
||||||
favoritesCountElement, getFavoritesCount, getNthStatus, getReblogsCount, getUrl,
|
favoritesCountElement,
|
||||||
|
getFavoritesCount,
|
||||||
|
getNthFavoriteButton,
|
||||||
|
getNthReblogButton,
|
||||||
|
getNthStatus,
|
||||||
|
getReblogsCount,
|
||||||
|
getUrl,
|
||||||
reblogsCountElement
|
reblogsCountElement
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { loginAsFoobar } from '../roles'
|
import { loginAsFoobar } from '../roles'
|
||||||
|
@ -13,9 +19,10 @@ test('shows favorites', async t => {
|
||||||
await t
|
await t
|
||||||
.click(getNthStatus(1))
|
.click(getNthStatus(1))
|
||||||
.expect(getUrl()).contains('/statuses/')
|
.expect(getUrl()).contains('/statuses/')
|
||||||
|
.expect(getNthStatus(1).exists).ok()
|
||||||
.expect(getFavoritesCount()).eql(2)
|
.expect(getFavoritesCount()).eql(2)
|
||||||
.expect(favoritesCountElement.getAttribute('aria-label')).eql('Favorited 2 times')
|
.expect(favoritesCountElement.getAttribute('aria-label')).eql('Favorited 2 times')
|
||||||
.expect($('.icon-button[aria-label="Unfavorite"]').getAttribute('aria-pressed')).eql('true')
|
.expect(getNthFavoriteButton(1).getAttribute('aria-pressed')).eql('true')
|
||||||
.click(favoritesCountElement)
|
.click(favoritesCountElement)
|
||||||
.expect(getUrl()).match(/\/statuses\/[^/]+\/favorites/)
|
.expect(getUrl()).match(/\/statuses\/[^/]+\/favorites/)
|
||||||
.expect($('.search-result-account-name').nth(0).innerText).eql('foobar')
|
.expect($('.search-result-account-name').nth(0).innerText).eql('foobar')
|
||||||
|
@ -29,9 +36,10 @@ test('shows boosts', async t => {
|
||||||
await t
|
await t
|
||||||
.click(getNthStatus(1))
|
.click(getNthStatus(1))
|
||||||
.expect(getUrl()).contains('/statuses/')
|
.expect(getUrl()).contains('/statuses/')
|
||||||
|
.expect(getNthStatus(1).exists).ok()
|
||||||
.expect(getReblogsCount()).eql(1)
|
.expect(getReblogsCount()).eql(1)
|
||||||
.expect(reblogsCountElement.getAttribute('aria-label')).eql('Boosted 1 time')
|
.expect(reblogsCountElement.getAttribute('aria-label')).eql('Boosted 1 time')
|
||||||
.expect($('.icon-button[aria-label="Boost"]').getAttribute('aria-pressed')).eql('false')
|
.expect(getNthReblogButton(1).getAttribute('aria-pressed')).eql('false')
|
||||||
.click(reblogsCountElement)
|
.click(reblogsCountElement)
|
||||||
.expect(getUrl()).match(/\/statuses\/[^/]+\/reblogs/)
|
.expect(getUrl()).match(/\/statuses\/[^/]+\/reblogs/)
|
||||||
.expect($('.search-result-account-name').nth(0).innerText).eql('admin')
|
.expect($('.search-result-account-name').nth(0).innerText).eql('admin')
|
||||||
|
|
|
@ -12,16 +12,19 @@ test('Changes content warnings', async t => {
|
||||||
await t
|
await t
|
||||||
.expect(composeContentWarning.exists).notOk()
|
.expect(composeContentWarning.exists).notOk()
|
||||||
.expect(contentWarningButton.getAttribute('aria-label')).eql('Add content warning')
|
.expect(contentWarningButton.getAttribute('aria-label')).eql('Add content warning')
|
||||||
|
.expect(contentWarningButton.getAttribute('title')).eql('Add content warning')
|
||||||
.expect(contentWarningButton.getAttribute('aria-pressed')).eql('false')
|
.expect(contentWarningButton.getAttribute('aria-pressed')).eql('false')
|
||||||
.click(contentWarningButton)
|
.click(contentWarningButton)
|
||||||
.expect(composeContentWarning.exists).ok()
|
.expect(composeContentWarning.exists).ok()
|
||||||
.expect(contentWarningButton.getAttribute('aria-label')).eql('Remove content warning')
|
.expect(contentWarningButton.getAttribute('aria-label')).eql('Add content warning')
|
||||||
|
.expect(contentWarningButton.getAttribute('title')).eql('Remove content warning')
|
||||||
.expect(contentWarningButton.getAttribute('aria-pressed')).eql('true')
|
.expect(contentWarningButton.getAttribute('aria-pressed')).eql('true')
|
||||||
.typeText(composeContentWarning, 'hello content warning', { paste: true })
|
.typeText(composeContentWarning, 'hello content warning', { paste: true })
|
||||||
.typeText(composeInput, 'secret text', { paste: true })
|
.typeText(composeInput, 'secret text', { paste: true })
|
||||||
.click(notificationsNavButton)
|
.click(notificationsNavButton)
|
||||||
.click(homeNavButton)
|
.click(homeNavButton)
|
||||||
.expect(contentWarningButton.getAttribute('aria-label')).eql('Remove content warning')
|
.expect(contentWarningButton.getAttribute('aria-label')).eql('Add content warning')
|
||||||
|
.expect(contentWarningButton.getAttribute('title')).eql('Remove content warning')
|
||||||
.expect(contentWarningButton.getAttribute('aria-pressed')).eql('true')
|
.expect(contentWarningButton.getAttribute('aria-pressed')).eql('true')
|
||||||
.expect(composeContentWarning.value).eql('hello content warning')
|
.expect(composeContentWarning.value).eql('hello content warning')
|
||||||
.expect(composeInput.value).eql('secret text')
|
.expect(composeInput.value).eql('secret text')
|
||||||
|
@ -34,6 +37,7 @@ test('Changes content warnings', async t => {
|
||||||
.click(contentWarningButton)
|
.click(contentWarningButton)
|
||||||
.expect(composeContentWarning.exists).notOk()
|
.expect(composeContentWarning.exists).notOk()
|
||||||
.expect(contentWarningButton.getAttribute('aria-label')).eql('Add content warning')
|
.expect(contentWarningButton.getAttribute('aria-label')).eql('Add content warning')
|
||||||
|
.expect(contentWarningButton.getAttribute('title')).eql('Add content warning')
|
||||||
.expect(contentWarningButton.getAttribute('aria-pressed')).eql('false')
|
.expect(contentWarningButton.getAttribute('aria-pressed')).eql('false')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -5,23 +5,32 @@ import {
|
||||||
sleep
|
sleep
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import {
|
import {
|
||||||
authorizeFollowRequestAs, getFollowRequestsAs
|
authorizeFollowRequestAs, getFollowRequestsAs, unfollowAs
|
||||||
} from '../serverActions'
|
} from '../serverActions'
|
||||||
|
|
||||||
fixture`106-follow-requests.js`
|
fixture`106-follow-requests.js`
|
||||||
.page`http://localhost:4002`
|
.page`http://localhost:4002`
|
||||||
|
|
||||||
test('can request to follow an account', async t => {
|
test('can request to follow an account', async t => {
|
||||||
|
await unfollowAs('foobar', 'LockedAccount') // reset
|
||||||
await loginAsFoobar(t)
|
await loginAsFoobar(t)
|
||||||
await t
|
await t
|
||||||
.navigateTo('/accounts/6')
|
.navigateTo('/accounts/6')
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('false')
|
||||||
.click(accountProfileFollowButton)
|
.click(accountProfileFollowButton)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unfollow (follow requested)')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow (follow requested)')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unfollow (follow requested)')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('true')
|
||||||
.click(accountProfileFollowButton)
|
.click(accountProfileFollowButton)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('false')
|
||||||
.click(accountProfileFollowButton)
|
.click(accountProfileFollowButton)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unfollow (follow requested)')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow (follow requested)')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unfollow (follow requested)')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('true')
|
||||||
|
|
||||||
const requests = await getFollowRequestsAs('LockedAccount')
|
const requests = await getFollowRequestsAs('LockedAccount')
|
||||||
await authorizeFollowRequestAs('LockedAccount', requests.slice(-1)[0].id)
|
await authorizeFollowRequestAs('LockedAccount', requests.slice(-1)[0].id)
|
||||||
|
@ -29,8 +38,12 @@ test('can request to follow an account', async t => {
|
||||||
await sleep(2000)
|
await sleep(2000)
|
||||||
|
|
||||||
await t.navigateTo('/accounts/6')
|
await t.navigateTo('/accounts/6')
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unfollow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unfollow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('true')
|
||||||
.expect(getNthStatus(1).innerText).contains('This account is locked')
|
.expect(getNthStatus(1).innerText).contains('This account is locked')
|
||||||
.click(accountProfileFollowButton)
|
.click(accountProfileFollowButton)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('false')
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { Selector as $ } from 'testcafe'
|
import { Selector as $ } from 'testcafe'
|
||||||
import { loginAsFoobar } from '../roles'
|
import { loginAsFoobar } from '../roles'
|
||||||
import { postAs } from '../serverActions'
|
import { postAs, unfollowAs } from '../serverActions'
|
||||||
|
|
||||||
fixture`113-block-unblock.js`
|
fixture`113-block-unblock.js`
|
||||||
.page`http://localhost:4002`
|
.page`http://localhost:4002`
|
||||||
|
@ -28,14 +28,21 @@ test('Can block and unblock an account from a status', async t => {
|
||||||
.expect(getUrl()).contains('/accounts/1')
|
.expect(getUrl()).contains('/accounts/1')
|
||||||
.expect(accountProfileFollowedBy.innerText).match(/blocked/i)
|
.expect(accountProfileFollowedBy.innerText).match(/blocked/i)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unblock')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unblock')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unblock')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql(undefined)
|
||||||
.click(accountProfileFollowButton)
|
.click(accountProfileFollowButton)
|
||||||
.expect(accountProfileFollowedBy.innerText).contains('')
|
.expect(accountProfileFollowedBy.innerText).contains('')
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('false')
|
||||||
.click(accountProfileFollowButton)
|
.click(accountProfileFollowButton)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unfollow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unfollow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('true')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Can block and unblock an account from the account profile page', async t => {
|
test('Can block and unblock an account from the account profile page', async t => {
|
||||||
|
await unfollowAs('foobar', 'baz') // reset
|
||||||
await loginAsFoobar(t)
|
await loginAsFoobar(t)
|
||||||
await t
|
await t
|
||||||
.navigateTo('/accounts/5')
|
.navigateTo('/accounts/5')
|
||||||
|
@ -47,11 +54,19 @@ test('Can block and unblock an account from the account profile page', async t =
|
||||||
.click(getNthDialogOptionsOption(3))
|
.click(getNthDialogOptionsOption(3))
|
||||||
.expect(accountProfileFollowedBy.innerText).match(/blocked/i)
|
.expect(accountProfileFollowedBy.innerText).match(/blocked/i)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unblock')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unblock')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unblock')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql(undefined)
|
||||||
.click(accountProfileFollowButton)
|
.click(accountProfileFollowButton)
|
||||||
.expect(accountProfileFollowedBy.innerText).contains('')
|
.expect(accountProfileFollowedBy.innerText).contains('')
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
.click(accountProfileFollowButton)
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Follow')
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unfollow')
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('false')
|
||||||
.click(accountProfileFollowButton)
|
.click(accountProfileFollowButton)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unfollow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('true')
|
||||||
|
.click(accountProfileFollowButton)
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('false')
|
||||||
})
|
})
|
||||||
|
|
|
@ -60,5 +60,7 @@ test('Can mute and unmute an account', async t => {
|
||||||
await sleep(1000)
|
await sleep(1000)
|
||||||
await t
|
await t
|
||||||
.click(closeDialogButton)
|
.click(closeDialogButton)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unfollow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unfollow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('true')
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,26 +4,36 @@ import {
|
||||||
getNthDialogOptionsOption
|
getNthDialogOptionsOption
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { loginAsFoobar } from '../roles'
|
import { loginAsFoobar } from '../roles'
|
||||||
|
import { unfollowAs } from '../serverActions'
|
||||||
|
|
||||||
fixture`115-follow-unfollow.js`
|
fixture`115-follow-unfollow.js`
|
||||||
.page`http://localhost:4002`
|
.page`http://localhost:4002`
|
||||||
|
|
||||||
test('Can follow and unfollow an account from the profile page', async t => {
|
test('Can follow and unfollow an account from the profile page', async t => {
|
||||||
|
await unfollowAs('foobar', 'baz') // reset
|
||||||
await loginAsFoobar(t)
|
await loginAsFoobar(t)
|
||||||
await t
|
await t
|
||||||
.navigateTo('/accounts/5')
|
.navigateTo('/accounts/5')
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('false')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Follow')
|
||||||
.click(accountProfileMoreOptionsButton)
|
.click(accountProfileMoreOptionsButton)
|
||||||
.expect(getNthDialogOptionsOption(1).innerText).contains('Mention @baz')
|
.expect(getNthDialogOptionsOption(1).innerText).contains('Mention @baz')
|
||||||
.expect(getNthDialogOptionsOption(2).innerText).contains('Follow @baz')
|
.expect(getNthDialogOptionsOption(2).innerText).contains('Follow @baz')
|
||||||
.click(getNthDialogOptionsOption(2))
|
.click(getNthDialogOptionsOption(2))
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unfollow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('true')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unfollow')
|
||||||
.click(accountProfileMoreOptionsButton)
|
.click(accountProfileMoreOptionsButton)
|
||||||
.expect(getNthDialogOptionsOption(2).innerText).contains('Unfollow @baz')
|
.expect(getNthDialogOptionsOption(2).innerText).contains('Unfollow @baz')
|
||||||
.click(getNthDialogOptionsOption(2))
|
.click(getNthDialogOptionsOption(2))
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('false')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Follow')
|
||||||
.click(accountProfileMoreOptionsButton)
|
.click(accountProfileMoreOptionsButton)
|
||||||
.expect(getNthDialogOptionsOption(2).innerText).contains('Follow @baz')
|
.expect(getNthDialogOptionsOption(2).innerText).contains('Follow @baz')
|
||||||
.click(closeDialogButton)
|
.click(closeDialogButton)
|
||||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Follow')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('aria-pressed')).eql('false')
|
||||||
|
.expect(accountProfileFollowButton.getAttribute('title')).eql('Follow')
|
||||||
})
|
})
|
||||||
|
|
|
@ -27,6 +27,8 @@ test('Can add and remove poll', async t => {
|
||||||
.expect(getNthStatus(1).exists).ok()
|
.expect(getNthStatus(1).exists).ok()
|
||||||
.expect(composePoll.exists).notOk()
|
.expect(composePoll.exists).notOk()
|
||||||
.expect(pollButton.getAttribute('aria-label')).eql('Add poll')
|
.expect(pollButton.getAttribute('aria-label')).eql('Add poll')
|
||||||
|
.expect(pollButton.getAttribute('title')).eql('Add poll')
|
||||||
|
.expect(pollButton.getAttribute('aria-pressed')).eql('false')
|
||||||
.click(pollButton)
|
.click(pollButton)
|
||||||
.expect(composePoll.exists).ok()
|
.expect(composePoll.exists).ok()
|
||||||
.expect(getComposePollNthInput(1).value).eql('')
|
.expect(getComposePollNthInput(1).value).eql('')
|
||||||
|
@ -35,7 +37,9 @@ test('Can add and remove poll', async t => {
|
||||||
.expect(getComposePollNthInput(4).exists).notOk()
|
.expect(getComposePollNthInput(4).exists).notOk()
|
||||||
.expect(composePollMultipleChoice.checked).notOk()
|
.expect(composePollMultipleChoice.checked).notOk()
|
||||||
.expect(composePollExpiry.value).eql(POLL_EXPIRY_DEFAULT.toString())
|
.expect(composePollExpiry.value).eql(POLL_EXPIRY_DEFAULT.toString())
|
||||||
.expect(pollButton.getAttribute('aria-label')).eql('Remove poll')
|
.expect(pollButton.getAttribute('aria-label')).eql('Add poll')
|
||||||
|
.expect(pollButton.getAttribute('title')).eql('Remove poll')
|
||||||
|
.expect(pollButton.getAttribute('aria-pressed')).eql('true')
|
||||||
.click(pollButton)
|
.click(pollButton)
|
||||||
.expect(composePoll.exists).notOk()
|
.expect(composePoll.exists).notOk()
|
||||||
})
|
})
|
||||||
|
@ -46,6 +50,8 @@ test('Can add and remove poll options', async t => {
|
||||||
.expect(getNthStatus(1).exists).ok()
|
.expect(getNthStatus(1).exists).ok()
|
||||||
.expect(composePoll.exists).notOk()
|
.expect(composePoll.exists).notOk()
|
||||||
.expect(pollButton.getAttribute('aria-label')).eql('Add poll')
|
.expect(pollButton.getAttribute('aria-label')).eql('Add poll')
|
||||||
|
.expect(pollButton.getAttribute('title')).eql('Add poll')
|
||||||
|
.expect(pollButton.getAttribute('aria-pressed')).eql('false')
|
||||||
.click(pollButton)
|
.click(pollButton)
|
||||||
.expect(composePoll.exists).ok()
|
.expect(composePoll.exists).ok()
|
||||||
.typeText(getComposePollNthInput(1), 'first', { paste: true })
|
.typeText(getComposePollNthInput(1), 'first', { paste: true })
|
||||||
|
|
Loading…
Reference in a new issue