add test for compose, and emoji
This commit is contained in:
parent
b26fdc7f55
commit
2614e451b2
Binary file not shown.
Binary file not shown.
|
@ -2,6 +2,7 @@ import { cacheFirstUpdateAfter } from '../_utils/sync'
|
|||
import { database } from '../_database/database'
|
||||
import { getCustomEmoji } from '../_api/emoji'
|
||||
import { store } from '../_store/store'
|
||||
import { substring } from 'stringz'
|
||||
|
||||
export async function updateCustomEmojiForInstance (instanceName) {
|
||||
await cacheFirstUpdateAfter(
|
||||
|
@ -17,5 +18,12 @@ export async function updateCustomEmojiForInstance (instanceName) {
|
|||
}
|
||||
|
||||
export function insertEmoji (emoji) {
|
||||
store.set({emojiToInsert: emoji})
|
||||
let idx = store.get('composeSelectionStart') || 0
|
||||
let oldText = store.get('rawComposeText')
|
||||
let pre = substring(oldText, 0, idx)
|
||||
let post = substring(oldText, idx)
|
||||
let newText = `${pre}:${emoji.shortcode}: ${post}`
|
||||
store.set({
|
||||
rawComposeText: newText
|
||||
})
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
placeholder="What's on your mind?"
|
||||
ref:textarea
|
||||
bind:value=$rawComposeText
|
||||
on:blur="onBlur()"
|
||||
></textarea>
|
||||
<style>
|
||||
.compose-box-input {
|
||||
|
@ -48,34 +49,21 @@
|
|||
this.store.set({composeText: composeText})
|
||||
saveText()
|
||||
}, {init: false})
|
||||
|
||||
this.observe('emojiToInsert', emojiToInsert => {
|
||||
if (!emojiToInsert) {
|
||||
return
|
||||
}
|
||||
requestAnimationFrame(() => {
|
||||
let idx = this.refs.textarea.selectionStart || 0
|
||||
let oldText = this.store.get('rawComposeText')
|
||||
let newText = oldText.substring(0, idx) +
|
||||
':' + emojiToInsert.shortcode + ': ' +
|
||||
oldText.substring(idx)
|
||||
this.store.set({
|
||||
rawComposeText: newText,
|
||||
emojiToInsert: null
|
||||
})
|
||||
})
|
||||
}, {init: false})
|
||||
},
|
||||
ondestroy() {
|
||||
mark('autosize.destroy()')
|
||||
autosize.destroy(this.refs.textarea)
|
||||
stop('autosize.destroy()')
|
||||
},
|
||||
methods: {
|
||||
onBlur() {
|
||||
this.store.set({composeSelectionStart: this.refs.textarea.selectionStart})
|
||||
}
|
||||
},
|
||||
store: () => store,
|
||||
computed: {
|
||||
rawComposeText: ($rawComposeText) => $rawComposeText,
|
||||
currentComposeText: ($currentComposeText) => $currentComposeText,
|
||||
emojiToInsert: ($emojiToInsert) => $emojiToInsert
|
||||
currentComposeText: ($currentComposeText) => $currentComposeText
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -34,15 +34,13 @@
|
|||
store: () => store,
|
||||
computed: {
|
||||
inputLengthToDisplay: ($rawComposeTextLength) => {
|
||||
return ($rawComposeTextLength <= CHAR_LIMIT
|
||||
? $rawComposeTextLength
|
||||
: CHAR_LIMIT - $rawComposeTextLength)
|
||||
return CHAR_LIMIT - $rawComposeTextLength
|
||||
},
|
||||
inputLengthLabel: ($rawComposeTextOverLimit, inputLengthToDisplay) => {
|
||||
if ($rawComposeTextOverLimit) {
|
||||
return `${inputLengthToDisplay} characters over limit`
|
||||
} else {
|
||||
return `${inputLengthToDisplay} characters`
|
||||
return `${inputLengthToDisplay} characters remaining`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
.custom-emoji-list {
|
||||
list-style: none;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(48px, 1fr));
|
||||
grid-template-columns: repeat(auto-fill, minmax(48px, 1fr));
|
||||
grid-gap: 5px;
|
||||
padding: 20px 10px;
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
import {
|
||||
composeButton, composeInput, composeLengthIndicator, getUrl, homeNavButton, notificationsNavButton
|
||||
} from '../utils'
|
||||
import { foobarRole } from '../roles'
|
||||
import times from 'lodash/times'
|
||||
|
||||
fixture`12-compose-limits.js`
|
||||
.page`http://localhost:4002`
|
||||
|
||||
test('shows compose limits', async t => {
|
||||
await t.useRole(foobarRole)
|
||||
.hover(composeInput)
|
||||
.expect(composeLengthIndicator.innerText).eql('0')
|
||||
.expect(composeButton.getAttribute('disabled')).eql('')
|
||||
.typeText(composeInput, 'typing some text')
|
||||
.expect(composeLengthIndicator.innerText).eql('16')
|
||||
.expect(composeButton.hasAttribute('disabled')).notOk()
|
||||
.typeText(composeInput, times(50, () => 'hello world').join(' '), {replace: true, paste: true})
|
||||
.expect(composeLengthIndicator.innerText).eql('-99')
|
||||
.expect(composeButton.getAttribute('disabled')).eql('')
|
||||
.typeText(composeInput, 'hello world', {replace: true})
|
||||
.click(notificationsNavButton)
|
||||
.expect(getUrl()).contains('/notifications')
|
||||
.click(homeNavButton)
|
||||
.expect(getUrl()).eql('http://localhost:4002/')
|
||||
.expect(composeInput.value).eql('hello world')
|
||||
.expect(composeLengthIndicator.innerText).eql('11')
|
||||
.expect(composeButton.hasAttribute('disabled')).notOk()
|
||||
.selectText(composeInput)
|
||||
.pressKey('delete')
|
||||
.expect(composeInput.value).eql('')
|
||||
.expect(composeLengthIndicator.innerText).eql('0')
|
||||
.expect(composeButton.getAttribute('disabled')).eql('')
|
||||
})
|
83
tests/spec/12-compose.js
Normal file
83
tests/spec/12-compose.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
import { Selector as $ } from 'testcafe'
|
||||
import {
|
||||
composeButton, composeInput, composeLengthIndicator, emojiButton, getComposeSelectionStart, getUrl,
|
||||
homeNavButton,
|
||||
notificationsNavButton
|
||||
} from '../utils'
|
||||
import { foobarRole } from '../roles'
|
||||
import times from 'lodash/times'
|
||||
|
||||
fixture`12-compose.js`
|
||||
.page`http://localhost:4002`
|
||||
|
||||
test('shows compose limits', async t => {
|
||||
await t.useRole(foobarRole)
|
||||
.hover(composeInput)
|
||||
.expect(composeLengthIndicator.innerText).eql('500')
|
||||
.expect(composeButton.getAttribute('disabled')).eql('')
|
||||
.typeText(composeInput, 'typing some text')
|
||||
.expect(composeLengthIndicator.innerText).eql('484')
|
||||
.expect(composeButton.hasAttribute('disabled')).notOk()
|
||||
.typeText(composeInput, times(50, () => 'hello world').join(' '), {replace: true, paste: true})
|
||||
.expect(composeLengthIndicator.innerText).eql('-99')
|
||||
.expect(composeButton.getAttribute('disabled')).eql('')
|
||||
.typeText(composeInput, 'hello world', {replace: true})
|
||||
.click(notificationsNavButton)
|
||||
.expect(getUrl()).contains('/notifications')
|
||||
.click(homeNavButton)
|
||||
.expect(getUrl()).eql('http://localhost:4002/')
|
||||
.expect(composeInput.value).eql('hello world')
|
||||
.expect(composeLengthIndicator.innerText).eql('489')
|
||||
.expect(composeButton.hasAttribute('disabled')).notOk()
|
||||
.selectText(composeInput)
|
||||
.pressKey('delete')
|
||||
.expect(composeInput.value).eql('')
|
||||
.expect(composeLengthIndicator.innerText).eql('500')
|
||||
.expect(composeButton.getAttribute('disabled')).eql('')
|
||||
})
|
||||
|
||||
test('shows compose limits for URLs/handles', async t => {
|
||||
await t.useRole(foobarRole)
|
||||
.expect(composeLengthIndicator.innerText).eql('500')
|
||||
.expect(composeButton.getAttribute('disabled')).eql('')
|
||||
.typeText(composeInput, 'hello world ' +
|
||||
'http://foo.bar.baz.whatever.example.com/hello ' +
|
||||
'@reallylongnamethatstretchesonandon@foo.example.com', {paste: true})
|
||||
.expect(composeLengthIndicator.innerText).eql('429')
|
||||
.expect(composeButton.hasAttribute('disabled')).notOk()
|
||||
})
|
||||
|
||||
test('shows compose limits for emoji', async t => {
|
||||
await t.useRole(foobarRole)
|
||||
.typeText(composeInput, 'hello world \ud83c\ude01 \ud83d\udc6a')
|
||||
.expect(composeLengthIndicator.innerText).eql('485')
|
||||
.expect(composeButton.hasAttribute('disabled')).notOk()
|
||||
})
|
||||
|
||||
test('shows compose limits for custom emoji', async t => {
|
||||
await t.useRole(foobarRole)
|
||||
.typeText(composeInput, 'hello world ')
|
||||
.click(emojiButton)
|
||||
.click($('button img[title=":blobnom:"]'))
|
||||
.expect(composeInput.value).eql('hello world :blobnom: ')
|
||||
.expect(composeLengthIndicator.innerText).eql('478')
|
||||
})
|
||||
|
||||
test('inserts custom emoji correctly', async t => {
|
||||
await t.useRole(foobarRole)
|
||||
.typeText(composeInput, 'hello world')
|
||||
.selectText(composeInput, 6, 6)
|
||||
.expect(getComposeSelectionStart()).eql(6)
|
||||
.click(emojiButton)
|
||||
.click($('button img[title=":blobpats:"]'))
|
||||
.expect(composeInput.value).eql('hello :blobpats: world')
|
||||
.selectText(composeInput, 0, 0)
|
||||
.expect(getComposeSelectionStart()).eql(0)
|
||||
.click(emojiButton)
|
||||
.click($('button img[title=":blobnom:"]'))
|
||||
.expect(composeInput.value).eql(':blobnom: hello :blobpats: world')
|
||||
.typeText(composeInput, ' foobar ')
|
||||
.click(emojiButton)
|
||||
.click($('button img[title=":blobpeek:"]'))
|
||||
.expect(composeInput.value).eql(':blobnom: hello :blobpats: world foobar :blobpeek: ')
|
||||
})
|
|
@ -13,6 +13,7 @@ export const formError = $('.form-error-user-error')
|
|||
export const composeInput = $('.compose-box-input')
|
||||
export const composeButton = $('.compose-box-button')
|
||||
export const composeLengthIndicator = $('.compose-box-length')
|
||||
export const emojiButton = $('.compose-box-toolbar button:first-child')
|
||||
|
||||
export const favoritesCountElement = $('.status-favs-reblogs:nth-child(3)').addCustomDOMProperties({
|
||||
innerCount: el => parseInt(el.innerText, 10)
|
||||
|
@ -30,6 +31,10 @@ export const getActiveElementClass = exec(() =>
|
|||
|
||||
export const goBack = exec(() => window.history.back())
|
||||
|
||||
export const getComposeSelectionStart = exec(() => composeInput().selectionStart, {
|
||||
dependencies: { composeInput }
|
||||
})
|
||||
|
||||
export function getNthStatus (n) {
|
||||
return $(`div[aria-hidden="false"] > article[aria-posinset="${n}"]`)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue