454 lines
22 KiB
QML
454 lines
22 KiB
QML
import QtQuick 2.15
|
|
import QtQuick.Controls 2.15
|
|
import QtQml 2.15
|
|
import QtQml.Models 2.15
|
|
|
|
import StatusQ 0.1
|
|
import StatusQ.Core.Utils 0.1
|
|
|
|
import QtTest 1.15
|
|
|
|
import shared.panels 1.0
|
|
import utils 1.0
|
|
|
|
Item {
|
|
id: root
|
|
width: 600
|
|
height: 400
|
|
|
|
TestCase {
|
|
name: "EnterSeedPhraseTest"
|
|
when: windowShown
|
|
|
|
Component {
|
|
id: enterSeedPhraseComponent
|
|
EnterSeedPhrase {
|
|
id: enterSeedPhrase
|
|
anchors.fill: parent
|
|
dictionary: ListModel {}
|
|
|
|
readonly property SignalSpy submitSpy: SignalSpy { target: enterSeedPhrase; signalName: "submitSeedPhrase" }
|
|
readonly property SignalSpy seedPhraseUpdatedSpy: SignalSpy { target: enterSeedPhrase; signalName: "seedPhraseUpdated" }
|
|
}
|
|
}
|
|
|
|
property EnterSeedPhrase itemUnderTest: null
|
|
|
|
function generateDictionaryVariation(baseDictionary) {
|
|
let dictionaryVariation = baseDictionary.map((word) => word + "a")
|
|
dictionaryVariation = baseDictionary.map((word) => word + "b").concat(dictionaryVariation)
|
|
dictionaryVariation = baseDictionary.map((word) => word + "c").concat(dictionaryVariation)
|
|
dictionaryVariation = baseDictionary.map((word) => word + "d").concat(dictionaryVariation)
|
|
dictionaryVariation.sort()
|
|
return dictionaryVariation
|
|
}
|
|
|
|
function init() {
|
|
itemUnderTest = createTemporaryObject(enterSeedPhraseComponent, root)
|
|
waitForItemPolished(itemUnderTest)
|
|
waitForRendering(itemUnderTest)
|
|
}
|
|
|
|
// regression test for https://github.com/status-im/status-desktop/issues/16291
|
|
function test_threeLetterPrefixSuggestionInput() {
|
|
const commonPrefixToTest = "cat"
|
|
|
|
//generate a seed phrase
|
|
const expectedSeedPhrase = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", commonPrefixToTest]
|
|
const baseDictionary = [...expectedSeedPhrase, "cow", "catalog", "catch", "category", "cattle"]
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
verify(seedPhrase === expectedSeedPhrase.join(" "), "Seed phrase is not valid")
|
|
isSeedPhraseValidCalled = true
|
|
return true
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(baseDictionary.map((word) => ({seedWord: word})))
|
|
|
|
//Type the seed phrase except the last word
|
|
const str = expectedSeedPhrase.join(" ")
|
|
for (let i = 0; i < str.length - commonPrefixToTest.length; i++) {
|
|
keyPress(str.charAt(i))
|
|
}
|
|
|
|
const lastInputField = findChild(itemUnderTest, "enterSeedPhraseInputField12")
|
|
verify(!!lastInputField)
|
|
mouseClick(lastInputField)
|
|
tryCompare(lastInputField, "activeFocus", true)
|
|
|
|
// type the common prefix -> "cat..."
|
|
keyClick(Qt.Key_C)
|
|
keyClick(Qt.Key_A)
|
|
keyClick(Qt.Key_T)
|
|
tryCompare(lastInputField, "text", "cat")
|
|
|
|
// hit Enter to accept "cat"
|
|
keyClick(Qt.Key_Enter)
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid was not called")
|
|
|
|
// hit Enter to submit the form
|
|
keyClick(Qt.Key_Enter)
|
|
verify(itemUnderTest.submitSpy.count === 1, "submitSeedPhrase signal was not emitted")
|
|
// This signal is emitted multiple times due to the way the seed phrase is updated and validated
|
|
// The minimum is the length if the seed phrase
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
}
|
|
|
|
function test_componentCreation() {
|
|
verify(itemUnderTest !== null, "Component creation failed")
|
|
}
|
|
|
|
// Test seed phrase input by typing on the keyboard
|
|
// The seed phrase is valid and the typing is done without any space between words
|
|
// This is the most common way to input a seed phrase
|
|
function test_seedPhraseKeyboardInput() {
|
|
//generate a seed phrase
|
|
const expectedSeedPhrase = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident"]
|
|
expectedSeedPhrase.sort();
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
verify(seedPhrase === expectedSeedPhrase.join(" "), "Seed phrase is not valid")
|
|
isSeedPhraseValidCalled = true
|
|
return true
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(expectedSeedPhrase.map((word) => ({seedWord: word})))
|
|
|
|
//Type the seed phrase. No space is needed between words
|
|
const str = expectedSeedPhrase.join("")
|
|
for (let i = 0; i < str.length; i++) {
|
|
keyPress(str.charAt(i))
|
|
}
|
|
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid was not called")
|
|
|
|
keyClick(Qt.Key_Enter)
|
|
verify(itemUnderTest.submitSpy.count === 1, "submitSeedPhrase signal was not emitted")
|
|
// This signal is emitted multiple times due to the way the seed phrase is updated and validated
|
|
// The minimum is the length if the seed phrase
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
}
|
|
|
|
// Test seed phrase input by typing on the keyboard
|
|
// The seed phrase is valid and the typing is done with a space between words
|
|
// The space between words is ignored and the seed should be valid
|
|
function test_seedPhraseKeyboardInputWithExtraSpace() {
|
|
//generate a seed phrase
|
|
const expectedSeedPhrase = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident"]
|
|
expectedSeedPhrase.sort();
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
verify(seedPhrase === expectedSeedPhrase.join(" "), "Seed phrase is not valid")
|
|
isSeedPhraseValidCalled = true
|
|
return true
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(expectedSeedPhrase.map((word) => ({seedWord: word})))
|
|
|
|
//Type the seed phrase. A space is needed between words
|
|
const str = expectedSeedPhrase.join(" ")
|
|
for (let i = 0; i < str.length; i++) {
|
|
keyPress(str.charAt(i))
|
|
}
|
|
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid was not called")
|
|
keyClick(Qt.Key_Enter)
|
|
verify(itemUnderTest.submitSpy.count === 1, "submitSeedPhrase signal was not emitted")
|
|
// This signal is emitted multiple times due to the way the seed phrase is updated and validated
|
|
// The minimum is the length if the seed phrase
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
}
|
|
|
|
// Test seed phrase input by pasting from clipboard
|
|
// The seed phrase is valid and the clipboard seed is space separated
|
|
function test_seedPhrasePaste() {
|
|
//generate a seed phrase
|
|
const expectedSeedPhrase = ["abandona", "abilityb", "ablec", "aboutd", "abovea", "absentb", "absorbc", "abstractd", "absurda", "abuseb", "accessc", "accidentd"]
|
|
const baseDictionary = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident"]
|
|
|
|
expectedSeedPhrase.sort();
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
verify(seedPhrase === expectedSeedPhrase.join(" "), "Seed phrase is not valid")
|
|
isSeedPhraseValidCalled = true
|
|
return true
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(expectedSeedPhrase.map((word) => ({seedWord: word})))
|
|
|
|
ClipboardUtils.setText(expectedSeedPhrase.join(" "))
|
|
|
|
// Trigger the paste action
|
|
keyClick("v", Qt.ControlModifier)
|
|
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid was not called")
|
|
|
|
keyClick(Qt.Key_Enter)
|
|
verify(itemUnderTest.submitSpy.count === 1, "submitSeedPhrase signal was not emitted")
|
|
// This signal is emitted multiple times due to the way the seed phrase is updated and validated
|
|
// The minimum is the length if the seed phrase
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
}
|
|
|
|
// Test the seed phrase by choosing from the suggestions
|
|
// The seed phrase is valid and the user selects the words from the suggestions
|
|
function test_seedPhraseChooseFromSuggestions() {
|
|
//generate a seed phrase
|
|
const expectedSeedPhrase = ["abandona", "abilityb", "ablec", "aboutd", "abovea", "absentb", "absorbc", "abstractd", "absurda", "abuseb", "accessc", "accidentd"]
|
|
expectedSeedPhrase.sort()
|
|
|
|
const baseDictionary = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident"]
|
|
let dictionaryVariation = generateDictionaryVariation(baseDictionary)
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
verify(seedPhrase === expectedSeedPhrase.join(" "), "Seed phrase is not valid")
|
|
isSeedPhraseValidCalled = true
|
|
return true
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(dictionaryVariation.map((word) => ({seedWord: word})))
|
|
|
|
// Suggestions dialog is expected to receive key events when there's multiple suggestions
|
|
let downKeyEvents = 0
|
|
for (let i = 0; i < expectedSeedPhrase.length; i++) {
|
|
keySequence(expectedSeedPhrase[i].substring(0, 4).split('').join(','))
|
|
for (let j = 0; j < downKeyEvents; j++) {
|
|
keyClick(Qt.Key_Down)
|
|
}
|
|
downKeyEvents = downKeyEvents === 3 ? 0 : downKeyEvents + 1
|
|
keyClick(Qt.Key_Tab)
|
|
}
|
|
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid was not called")
|
|
|
|
keyPress(Qt.Key_Enter)
|
|
verify(itemUnderTest.submitSpy.count === 1, "submitSeedPhrase signal was not emitted")
|
|
// This signal is emitted multiple times due to the way the seed phrase is updated and validated
|
|
// The minimum is the length if the seed phrase
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
}
|
|
|
|
// Test seed phrase input by typing on the keyboard
|
|
// The seed phrase is invalidated by the external isSeedPhraseValid
|
|
function test_invalidatedSeedPhraseKeyboardInput() {
|
|
//generate a seed phrase
|
|
const expectedSeedPhrase = ["abandona", "abilityb", "ablec", "aboutd", "abovea", "absentb", "absorbc", "abstractd", "absurda", "abuseb", "accessc", "accidentd"]
|
|
expectedSeedPhrase.sort()
|
|
|
|
const baseDictionary = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident"]
|
|
let dictionaryVariation = generateDictionaryVariation(baseDictionary)
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
verify(seedPhrase === expectedSeedPhrase.join(" "), "Seed phrase is not valid")
|
|
isSeedPhraseValidCalled = true
|
|
return false
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(dictionaryVariation.map((word) => ({seedWord: word})))
|
|
|
|
//Type the seed phrase
|
|
const str = expectedSeedPhrase.join("")
|
|
for (let i = 0; i < str.length; i++) {
|
|
keyPress(str.charAt(i))
|
|
}
|
|
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid was not called")
|
|
|
|
keyClick(Qt.Key_Enter)
|
|
verify(itemUnderTest.submitSpy.count === 0, "submitSeedPhrase signal was emitted")
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
}
|
|
|
|
// Test seed phrase input by pasting from clipboard
|
|
// The seed phrase is invalidated by the external isSeedPhraseValid
|
|
function test_invalidatedSeedPhrasePaste() {
|
|
//generate a seed phrase
|
|
const expectedSeedPhrase = ["abandona", "abilityb", "ablec", "aboutd", "abovea", "absentb", "absorbc", "abstractd", "absurda", "abuseb", "accessc", "accidentd"]
|
|
expectedSeedPhrase.sort()
|
|
|
|
const baseDictionary = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident"]
|
|
let dictionaryVariation = generateDictionaryVariation(baseDictionary)
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
verify(seedPhrase === expectedSeedPhrase.join(" "), "Seed phrase is not valid")
|
|
isSeedPhraseValidCalled = true
|
|
return false
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(dictionaryVariation.map((word) => ({seedWord: word})))
|
|
|
|
ClipboardUtils.setText(expectedSeedPhrase.join(" "))
|
|
|
|
// Trigger the paste action
|
|
keyClick("v", Qt.ControlModifier)
|
|
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid was not called")
|
|
|
|
keyClick(Qt.Key_Enter)
|
|
verify(itemUnderTest.submitSpy.count === 0, "submitSeedPhrase signal was emitted")
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
}
|
|
|
|
// Test seed phrase input by typing on the keyboard
|
|
// The seed phrase is invalid due to the length
|
|
function test_invalidLengthSeedPhrase() {
|
|
const expectedSeedPhrase = ["abandona", "abilityb", "ablec"]
|
|
expectedSeedPhrase.sort()
|
|
|
|
const baseDictionary = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident"]
|
|
let dictionaryVariation = generateDictionaryVariation(baseDictionary)
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
verify(seedPhrase === expectedSeedPhrase.join(" "), "Seed phrase is not valid")
|
|
isSeedPhraseValidCalled = true
|
|
return true
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(dictionaryVariation.map((word) => ({seedWord: word})))
|
|
|
|
//Type the seed phrase
|
|
const str = expectedSeedPhrase.join("")
|
|
for (let i = 0; i < str.length; i++) {
|
|
keyPress(str.charAt(i))
|
|
}
|
|
|
|
keyClick(Qt.Key_Enter)
|
|
verify(!isSeedPhraseValidCalled, "isSeedPhraseValid was called when it should not have been")
|
|
verify(itemUnderTest.submitSpy.count === 0, "submitSeedPhrase signal was emitted")
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
}
|
|
|
|
// Test seed phrase input by typing on the keyboard
|
|
// The seed phrase is invalid due to the dictionary word
|
|
function test_invalidDictionarySeedPhrase() {
|
|
const expectedSeedPhrase = ["abandonna", "abilityb", "ablec", "aboutd", "abovea", "absentb", "absorbc", "abstractd", "absurda", "abuseb", "accessc", "accidentd"]
|
|
// ^^ invalid word
|
|
expectedSeedPhrase.sort()
|
|
|
|
const baseDictionary = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident"]
|
|
let dictionaryVariation = generateDictionaryVariation(baseDictionary)
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
verify(seedPhrase === expectedSeedPhrase.join(" "), "Seed phrase is not valid")
|
|
isSeedPhraseValidCalled = true
|
|
return true
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(dictionaryVariation.map((word) => ({seedWord: word})))
|
|
|
|
//Type the seed phrase
|
|
const str = expectedSeedPhrase.join("")
|
|
for (let i = 0; i < str.length; i++) {
|
|
keyPress(str.charAt(i))
|
|
if (i === 8) {
|
|
// The first word is invalid. Move on to the next word
|
|
keyPress(Qt.Key_Tab)
|
|
}
|
|
}
|
|
|
|
keyClick(Qt.Key_Enter)
|
|
verify(itemUnderTest.submitSpy.count === 0, "submitSeedPhrase signal was emitted")
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
}
|
|
|
|
// Test suggestions are active after the seed phrase word is updated
|
|
function test_suggestionsActiveAfterUpdatingWord() {
|
|
const expectedSeedPhrase = ["abandona", "abilityb", "ablec", "aboutd", "abovea", "absentb", "absorbc", "abstractd", "absurda", "abuseb", "accessc", "accidentd"]
|
|
expectedSeedPhrase.sort()
|
|
|
|
const baseDictionary = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident"]
|
|
let dictionaryVariation = generateDictionaryVariation(baseDictionary)
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
let lastVerifiedSeedPhrase = ""
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
lastVerifiedSeedPhrase = seedPhrase
|
|
isSeedPhraseValidCalled = true
|
|
return true
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(dictionaryVariation.map((word) => ({seedWord: word})))
|
|
|
|
// Suggestions dialog is expected to receive key events when there's multiple suggestions
|
|
let downKeyEvents = 0
|
|
for (let i = 0; i < expectedSeedPhrase.length; i++) {
|
|
keySequence(expectedSeedPhrase[i].substring(0, 4).split('').join(','))
|
|
for (let j = 0; j < downKeyEvents; j++) {
|
|
keyClick(Qt.Key_Down)
|
|
}
|
|
downKeyEvents = downKeyEvents === 3 ? 0 : downKeyEvents + 1
|
|
keyClick(Qt.Key_Tab)
|
|
}
|
|
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid was not called")
|
|
|
|
isSeedPhraseValidCalled = false
|
|
|
|
keyPress(Qt.Key_Backspace)
|
|
wait (500) // Wait for the suggestions to appear
|
|
keyClick(Qt.Key_Tab)
|
|
keyClick(Qt.Key_Enter)
|
|
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid was not called")
|
|
verify(lastVerifiedSeedPhrase === expectedSeedPhrase.join(" ").slice(0, -1) + "a", "Seed phrase is not updated")
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
}
|
|
|
|
// Test suggestions are active after the seed phrase word is fixed
|
|
function test_suggestionsActiveAfterFixingWord() {
|
|
const expectedSeedPhrase = ["abandona", "abilityb", "ablec", "aboutd", "abovea", "absentb", "absorbc", "abstractd", "absurda", "abuseb", "accessc", "accidenntd"]
|
|
expectedSeedPhrase.sort()
|
|
|
|
const baseDictionary = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident"]
|
|
let dictionaryVariation = generateDictionaryVariation(baseDictionary)
|
|
|
|
let isSeedPhraseValidCalled = false
|
|
let lastVerifiedSeedPhrase = ""
|
|
itemUnderTest.isSeedPhraseValid = (seedPhrase) => {
|
|
lastVerifiedSeedPhrase = seedPhrase
|
|
isSeedPhraseValidCalled = true
|
|
return true
|
|
}
|
|
|
|
itemUnderTest.dictionary.append(dictionaryVariation.map((word) => ({seedWord: word})))
|
|
|
|
// Suggestions dialog is expected to receive key events when there's multiple suggestions
|
|
let downKeyEvents = 0
|
|
for (let i = 0; i < expectedSeedPhrase.length; i++) {
|
|
keySequence(expectedSeedPhrase[i].substring(0, 4).split('').join(','))
|
|
for (let j = 0; j < downKeyEvents; j++) {
|
|
keyClick(Qt.Key_Down)
|
|
}
|
|
downKeyEvents = downKeyEvents === 3 ? 0 : downKeyEvents + 1
|
|
keyClick(Qt.Key_Tab)
|
|
}
|
|
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid is not called")
|
|
|
|
isSeedPhraseValidCalled = false
|
|
|
|
for (let i = 0; i < 2; i++) {
|
|
keyPress(Qt.Key_Backspace)
|
|
}
|
|
|
|
wait (500) // Wait for the suggestions to appear
|
|
keyClick(Qt.Key_Tab)
|
|
keyClick(Qt.Key_Enter)
|
|
|
|
verify(isSeedPhraseValidCalled, "isSeedPhraseValid was not called")
|
|
verify(lastVerifiedSeedPhrase === expectedSeedPhrase.join(" ").slice(0, -3) + "ta", "Seed phrase is not updated")
|
|
verify(itemUnderTest.seedPhraseUpdatedSpy.count >= expectedSeedPhrase.length, "seedPhraseUpdate signal was not emitted")
|
|
verify(itemUnderTest.submitSpy.count === 1, "submitSeedPhrase signal was emitted")
|
|
}
|
|
}
|
|
}
|