fix more bugs in autocomplete (#208)

* fix more bugs in autocomplete

fully fixes #170

* fixup

* fix tests
This commit is contained in:
Nolan Lawson 2018-04-21 14:57:02 -07:00 committed by GitHub
parent 209b36c73b
commit 6bd4b05a98
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 17 deletions

View file

@ -83,7 +83,8 @@
} }
}) })
this.observe('searchText', async searchText => { this.observe('searchText', async searchText => {
if (!searchText) { let { thisComposeFocused } = this.get()
if (!thisComposeFocused || !searchText) {
return return
} }
let type = searchText.startsWith('@') ? 'account' : 'emoji' let type = searchText.startsWith('@') ? 'account' : 'emoji'
@ -98,6 +99,10 @@
}) })
}) })
this.observe('shown', shown => { this.observe('shown', shown => {
let { thisComposeFocused } = this.get()
if (!thisComposeFocused) {
return
}
this.store.set({composeAutosuggestionShown: shown}) this.store.set({composeAutosuggestionShown: shown})
}) })
}, },
@ -138,7 +143,10 @@
searchResults: ($composeAutosuggestionSearchResults) => $composeAutosuggestionSearchResults || [], searchResults: ($composeAutosuggestionSearchResults) => $composeAutosuggestionSearchResults || [],
type: ($composeAutosuggestionType) => $composeAutosuggestionType || 'account', type: ($composeAutosuggestionType) => $composeAutosuggestionType || 'account',
selected: ($composeAutosuggestionSelected) => $composeAutosuggestionSelected || 0, selected: ($composeAutosuggestionSelected) => $composeAutosuggestionSelected || 0,
searchText: (text, composeSelectionStartDeferred) => { searchText: (text, composeSelectionStartDeferred, thisComposeFocused) => {
if (!thisComposeFocused) {
return
}
let selectionStart = composeSelectionStartDeferred || 0 let selectionStart = composeSelectionStartDeferred || 0
if (!text || selectionStart < MIN_PREFIX_LENGTH) { if (!text || selectionStart < MIN_PREFIX_LENGTH) {
return return

View file

@ -8,13 +8,13 @@ import {
function login (t, username, password) { function login (t, username, password) {
return t.typeText(instanceInput, 'localhost:3000', {paste: true}) return t.typeText(instanceInput, 'localhost:3000', {paste: true})
.click(addInstanceButton) .click(addInstanceButton)
.expect(getUrl()).eql('http://localhost:3000/auth/sign_in') .expect(getUrl()).eql('http://localhost:3000/auth/sign_in', {timeout: 30000})
.typeText(emailInput, username, {paste: true}) .typeText(emailInput, username, {paste: true})
.typeText(passwordInput, password, {paste: true}) .typeText(passwordInput, password, {paste: true})
.click(mastodonLogInButton) .click(mastodonLogInButton)
.expect(getUrl()).contains('/oauth/authorize') .expect(getUrl()).contains('/oauth/authorize')
.click(authorizeInput) .click(authorizeInput)
.expect(getUrl()).eql('http://localhost:4002/', {timeout: 20000}) .expect(getUrl()).eql('http://localhost:4002/', {timeout: 30000})
} }
export const foobarRole = Role('http://localhost:4002/settings/instances/add', async t => { export const foobarRole = Role('http://localhost:4002/settings/instances/add', async t => {

View file

@ -15,7 +15,7 @@ function manualLogin (t, username, password) {
.expect(getUrl()).contains('/settings/instances/add') .expect(getUrl()).contains('/settings/instances/add')
.typeText(instanceInput, 'localhost:3000') .typeText(instanceInput, 'localhost:3000')
.click(addInstanceButton) .click(addInstanceButton)
.expect(getUrl()).eql('http://localhost:3000/auth/sign_in') .expect(getUrl()).eql('http://localhost:3000/auth/sign_in', {timeout: 30000})
.typeText(emailInput, username, {paste: true}) .typeText(emailInput, username, {paste: true})
.typeText(passwordInput, password, {paste: true}) .typeText(passwordInput, password, {paste: true})
.click(mastodonLogInButton) .click(mastodonLogInButton)

View file

@ -1,5 +1,5 @@
import { import {
composeInput, getNthAutosuggestionResult, getNthComposeReplyInput, getNthReplyButton, getNthStatus composeInput, getNthAutosuggestionResult, getNthComposeReplyInput, getNthReplyButton, getNthStatus, sleep
} from '../utils' } from '../utils'
import { Selector as $ } from 'testcafe' import { Selector as $ } from 'testcafe'
import { foobarRole } from '../roles' import { foobarRole } from '../roles'
@ -7,21 +7,25 @@ import { foobarRole } from '../roles'
fixture`018-compose-autosuggest.js` fixture`018-compose-autosuggest.js`
.page`http://localhost:4002` .page`http://localhost:4002`
const timeout = 30000
test('autosuggests user handles', async t => { test('autosuggests user handles', async t => {
await t.useRole(foobarRole) await t.useRole(foobarRole)
.hover(composeInput) .hover(composeInput)
await sleep(1000)
await t
.typeText(composeInput, 'hey @qu') .typeText(composeInput, 'hey @qu')
.click(getNthAutosuggestionResult(1)) .click(getNthAutosuggestionResult(1), {timeout})
.expect(composeInput.value).eql('hey @quux ') .expect(composeInput.value).eql('hey @quux ')
.typeText(composeInput, 'and also @adm') .typeText(composeInput, 'and also @adm')
.click(getNthAutosuggestionResult(1)) .click(getNthAutosuggestionResult(1), {timeout})
.expect(composeInput.value).eql('hey @quux and also @admin ') .expect(composeInput.value).eql('hey @quux and also @admin ')
.typeText(composeInput, 'and also @AdM') .typeText(composeInput, 'and also @AdM')
.expect(getNthAutosuggestionResult(1).innerText).contains('@admin') .expect(getNthAutosuggestionResult(1).innerText).contains('@admin', {timeout})
.pressKey('tab') .pressKey('tab')
.expect(composeInput.value).eql('hey @quux and also @admin and also @admin ') .expect(composeInput.value).eql('hey @quux and also @admin and also @admin ')
.typeText(composeInput, 'and @QU') .typeText(composeInput, 'and @QU')
.expect(getNthAutosuggestionResult(1).innerText).contains('@quux') .expect(getNthAutosuggestionResult(1).innerText).contains('@quux', {timeout})
.pressKey('enter') .pressKey('enter')
.expect(composeInput.value).eql('hey @quux and also @admin and also @admin and @quux ') .expect(composeInput.value).eql('hey @quux and also @admin and also @admin and @quux ')
}) })
@ -33,15 +37,15 @@ test('autosuggests custom emoji', async t => {
.click(getNthAutosuggestionResult(1)) .click(getNthAutosuggestionResult(1))
.expect(composeInput.value).eql(':blobnom: ') .expect(composeInput.value).eql(':blobnom: ')
.typeText(composeInput, 'and :blob') .typeText(composeInput, 'and :blob')
.expect(getNthAutosuggestionResult(1).innerText).contains(':blobnom:') .expect(getNthAutosuggestionResult(1).innerText).contains(':blobnom:', {timeout})
.expect(getNthAutosuggestionResult(2).innerText).contains(':blobpats:') .expect(getNthAutosuggestionResult(2).innerText).contains(':blobpats:')
.expect(getNthAutosuggestionResult(3).innerText).contains(':blobpeek:') .expect(getNthAutosuggestionResult(3).innerText).contains(':blobpeek:')
.pressKey('down') .pressKey('down')
.pressKey('down') .pressKey('down')
.pressKey('enter') .pressKey('enter')
.expect(composeInput.value).eql(':blobnom: and :blobpeek: ') .expect(composeInput.value).eql(':blobnom: and :blobpeek: ', {timeout})
.typeText(composeInput, 'and also :blobpa') .typeText(composeInput, 'and also :blobpa')
.expect(getNthAutosuggestionResult(1).innerText).contains(':blobpats:') .expect(getNthAutosuggestionResult(1).innerText).contains(':blobpats:', {timeout})
.pressKey('tab') .pressKey('tab')
.expect(composeInput.value).eql(':blobnom: and :blobpeek: and also :blobpats: ') .expect(composeInput.value).eql(':blobnom: and :blobpeek: and also :blobpats: ')
}) })
@ -50,7 +54,7 @@ test('autosuggest custom emoji works with regular emoji - keyboard', async t =>
await t.useRole(foobarRole) await t.useRole(foobarRole)
.hover(composeInput) .hover(composeInput)
.typeText(composeInput, '\ud83c\udf4d :blobno') .typeText(composeInput, '\ud83c\udf4d :blobno')
.expect(getNthAutosuggestionResult(1).innerText).contains(':blobnom:') .expect(getNthAutosuggestionResult(1).innerText).contains(':blobnom:', {timeout})
.pressKey('enter') .pressKey('enter')
.expect(composeInput.value).eql('\ud83c\udf4d :blobnom: ') .expect(composeInput.value).eql('\ud83c\udf4d :blobnom: ')
}) })
@ -59,7 +63,7 @@ test('autosuggest custom emoji works with regular emoji - clicking', async t =>
await t.useRole(foobarRole) await t.useRole(foobarRole)
.hover(composeInput) .hover(composeInput)
.typeText(composeInput, '\ud83c\udf4d :blobno') .typeText(composeInput, '\ud83c\udf4d :blobno')
.expect(getNthAutosuggestionResult(1).innerText).contains(':blobnom:') .expect(getNthAutosuggestionResult(1).innerText).contains(':blobnom:', {timeout})
.click(getNthAutosuggestionResult(1)) .click(getNthAutosuggestionResult(1))
.expect(composeInput.value).eql('\ud83c\udf4d :blobnom: ') .expect(composeInput.value).eql('\ud83c\udf4d :blobnom: ')
}) })
@ -68,7 +72,7 @@ test('autosuggest handles works with regular emoji - keyboard', async t => {
await t.useRole(foobarRole) await t.useRole(foobarRole)
.hover(composeInput) .hover(composeInput)
.typeText(composeInput, '\ud83c\udf4d @quu') .typeText(composeInput, '\ud83c\udf4d @quu')
.expect(getNthAutosuggestionResult(1).innerText).contains('@quux') .expect(getNthAutosuggestionResult(1).innerText).contains('@quux', {timeout})
.pressKey('enter') .pressKey('enter')
.expect(composeInput.value).eql('\ud83c\udf4d @quux ') .expect(composeInput.value).eql('\ud83c\udf4d @quux ')
}) })
@ -77,7 +81,7 @@ test('autosuggest handles works with regular emoji - clicking', async t => {
await t.useRole(foobarRole) await t.useRole(foobarRole)
.hover(composeInput) .hover(composeInput)
.typeText(composeInput, '\ud83c\udf4d @quu') .typeText(composeInput, '\ud83c\udf4d @quu')
.expect(getNthAutosuggestionResult(1).innerText).contains('@quux') .expect(getNthAutosuggestionResult(1).innerText).contains('@quux', {timeout})
.click(getNthAutosuggestionResult(1)) .click(getNthAutosuggestionResult(1))
.expect(composeInput.value).eql('\ud83c\udf4d @quux ') .expect(composeInput.value).eql('\ud83c\udf4d @quux ')
}) })
@ -93,3 +97,19 @@ test('autosuggest only shows for one input', async t => {
.typeText(getNthComposeReplyInput(0), 'uu') .typeText(getNthComposeReplyInput(0), 'uu')
.expect($('.compose-autosuggest.shown').exists).notOk() .expect($('.compose-autosuggest.shown').exists).notOk()
}) })
test('autosuggest only shows for one input part 2', async t => {
await t.useRole(foobarRole)
.hover(composeInput)
.typeText(composeInput, '@adm')
.expect($('.compose-autosuggest.shown').exists).ok({timeout})
.expect(getNthAutosuggestionResult(1).innerText).contains('@admin')
.hover(getNthStatus(0))
.click(getNthReplyButton(0))
.selectText(getNthComposeReplyInput(0))
.pressKey('delete')
.typeText(getNthComposeReplyInput(0), '@dd')
await sleep(1000)
await t.pressKey('backspace')
.expect($('.compose-autosuggest.shown').exists).notOk()
})