From fba17d77de9e60de0e02e90dc6dbcbbf7454158a Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 23 Jan 2019 07:25:34 -0800 Subject: Refactor first time flow, remove seed phrase from state (#5994) * Refactor and fix styling for first time flow. Remove seed phrase from persisted metamask state * Fix linting and tests * Fix translations, initialization notice routing * Fix drizzle tests * Fix e2e tests * Fix integration tests * Fix styling * Fix migration naming from 030 to 031 * Open extension in browser when user has not completed onboarding --- test/e2e/beta/drizzle.spec.js | 35 +++++++------- test/e2e/beta/from-import-beta-ui.spec.js | 17 +++---- test/e2e/beta/metamask-beta-responsive-ui.spec.js | 36 ++++++++------- test/e2e/beta/metamask-beta-ui.spec.js | 35 +++++++------- test/e2e/func.js | 2 +- test/unit/migrations/031-test.js | 56 +++++++++++++++++++++++ test/unit/ui/app/actions.spec.js | 6 +-- 7 files changed, 124 insertions(+), 63 deletions(-) create mode 100644 test/unit/migrations/031-test.js (limited to 'test') diff --git a/test/e2e/beta/drizzle.spec.js b/test/e2e/beta/drizzle.spec.js index e669dabcc..309df952c 100644 --- a/test/e2e/beta/drizzle.spec.js +++ b/test/e2e/beta/drizzle.spec.js @@ -112,7 +112,7 @@ describe('MetaMask', function () { await loadExtension(driver, extensionId) await delay(regularDelayMs) - const continueBtn = await findElement(driver, By.css('.welcome-screen__button')) + const continueBtn = await findElement(driver, By.css('.first-time-flow__button')) await continueBtn.click() await delay(regularDelayMs) }) @@ -120,9 +120,9 @@ describe('MetaMask', function () { describe('Going through the first time flow', () => { it('accepts a secure password', async () => { - const passwordBox = await findElement(driver, By.css('.create-password #create-password')) - const passwordBoxConfirm = await findElement(driver, By.css('.create-password #confirm-password')) - const button = await findElement(driver, By.css('.create-password button')) + const passwordBox = await findElement(driver, By.css('.first-time-flow__form #create-password')) + const passwordBoxConfirm = await findElement(driver, By.css('.first-time-flow__form #confirm-password')) + const button = await findElement(driver, By.css('.first-time-flow__form button')) await passwordBox.sendKeys('correct horse battery staple') await passwordBoxConfirm.sendKeys('correct horse battery staple') @@ -131,19 +131,21 @@ describe('MetaMask', function () { }) it('clicks through the unique image screen', async () => { - const nextScreen = await findElement(driver, By.css('.unique-image button')) + await findElement(driver, By.css('.first-time-flow__unique-image')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) it('clicks through the ToS', async () => { // terms of use - const canClickThrough = await driver.findElement(By.css('.tou button')).isEnabled() + await findElement(driver, By.css('.first-time-flow__markdown')) + const canClickThrough = await driver.findElement(By.css('button.first-time-flow__button')).isEnabled() assert.equal(canClickThrough, false, 'disabled continue button') const bottomOfTos = await findElement(driver, By.linkText('Attributions')) await driver.executeScript('arguments[0].scrollIntoView(true)', bottomOfTos) await delay(regularDelayMs) - const acceptTos = await findElement(driver, By.css('.tou button')) + const acceptTos = await findElement(driver, By.css('button.first-time-flow__button')) driver.wait(until.elementIsEnabled(acceptTos)) await acceptTos.click() await delay(regularDelayMs) @@ -151,17 +153,17 @@ describe('MetaMask', function () { it('clicks through the privacy notice', async () => { // privacy notice - const nextScreen = await findElement(driver, By.css('.tou button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) it('clicks through the phishing notice', async () => { // phishing notice - const noticeElement = await driver.findElement(By.css('.markdown')) + const noticeElement = await driver.findElement(By.css('.first-time-flow__markdown')) await driver.executeScript('arguments[0].scrollTop = arguments[0].scrollHeight', noticeElement) await delay(regularDelayMs) - const nextScreen = await findElement(driver, By.css('.tou button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) @@ -169,24 +171,23 @@ describe('MetaMask', function () { let seedPhrase it('reveals the seed phrase', async () => { - const byRevealButton = By.css('.backup-phrase__secret-blocker .backup-phrase__reveal-button') + const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button') await driver.wait(until.elementLocated(byRevealButton, 10000)) const revealSeedPhraseButton = await findElement(driver, byRevealButton, 10000) await revealSeedPhraseButton.click() await delay(regularDelayMs) - seedPhrase = await driver.findElement(By.css('.backup-phrase__secret-words')).getText() + seedPhrase = await driver.findElement(By.css('.reveal-seed-phrase__secret-words')).getText() assert.equal(seedPhrase.split(' ').length, 12) await delay(regularDelayMs) - const nextScreen = await findElement(driver, By.css('.backup-phrase button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) async function clickWordAndWait (word) { - const xpathClass = 'backup-phrase__confirm-seed-option backup-phrase__confirm-seed-option--unselected' - const xpath = `//button[@class='${xpathClass}' and contains(text(), '${word}')]` + const xpath = `//div[contains(@class, 'confirm-seed-phrase__seed-word--shuffled') and not(contains(@class, 'confirm-seed-phrase__seed-word--selected')) and contains(text(), '${word}')]` const word0 = await findElement(driver, By.xpath(xpath), 10000) await word0.click() @@ -196,13 +197,13 @@ describe('MetaMask', function () { async function retypeSeedPhrase (words, wasReloaded, count = 0) { try { if (wasReloaded) { - const byRevealButton = By.css('.backup-phrase__secret-blocker .backup-phrase__reveal-button') + const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button') await driver.wait(until.elementLocated(byRevealButton, 10000)) const revealSeedPhraseButton = await findElement(driver, byRevealButton, 10000) await revealSeedPhraseButton.click() await delay(regularDelayMs) - const nextScreen = await findElement(driver, By.css('.backup-phrase button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) } diff --git a/test/e2e/beta/from-import-beta-ui.spec.js b/test/e2e/beta/from-import-beta-ui.spec.js index aa951a243..d4a380584 100644 --- a/test/e2e/beta/from-import-beta-ui.spec.js +++ b/test/e2e/beta/from-import-beta-ui.spec.js @@ -95,7 +95,7 @@ describe('Using MetaMask with an existing account', function () { describe('First time flow starting from an existing seed phrase', () => { it('clicks the continue button on the welcome screen', async () => { - const welcomeScreenBtn = await findElement(driver, By.css('.welcome-screen__button')) + const welcomeScreenBtn = await findElement(driver, By.css('.welcome-page .first-time-flow__button')) welcomeScreenBtn.click() await delay(largeDelayMs) }) @@ -105,7 +105,7 @@ describe('Using MetaMask with an existing account', function () { await seedPhrase.click() await delay(regularDelayMs) - const [seedTextArea] = await findElements(driver, By.css('textarea.import-account__secret-phrase')) + const [seedTextArea] = await findElements(driver, By.css('textarea.first-time-flow__textarea')) await seedTextArea.sendKeys(testSeedPhrase) await delay(regularDelayMs) @@ -121,30 +121,31 @@ describe('Using MetaMask with an existing account', function () { it('clicks through the ToS', async () => { // terms of use - await delay(largeDelayMs) - const canClickThrough = await driver.findElement(By.css('.tou button')).isEnabled() + await findElement(driver, By.css('.first-time-flow__markdown')) + const canClickThrough = await driver.findElement(By.css('button.first-time-flow__button')).isEnabled() assert.equal(canClickThrough, false, 'disabled continue button') const bottomOfTos = await findElement(driver, By.linkText('Attributions')) await driver.executeScript('arguments[0].scrollIntoView(true)', bottomOfTos) await delay(regularDelayMs) - const acceptTos = await findElement(driver, By.css('.tou button')) + const acceptTos = await findElement(driver, By.css('button.first-time-flow__button')) + driver.wait(until.elementIsEnabled(acceptTos)) await acceptTos.click() await delay(regularDelayMs) }) it('clicks through the privacy notice', async () => { // privacy notice - const nextScreen = await findElement(driver, By.css('.tou button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) it('clicks through the phishing notice', async () => { // phishing notice - const noticeElement = await driver.findElement(By.css('.markdown')) + const noticeElement = await driver.findElement(By.css('.first-time-flow__markdown')) await driver.executeScript('arguments[0].scrollTop = arguments[0].scrollHeight', noticeElement) await delay(regularDelayMs) - const nextScreen = await findElement(driver, By.css('.tou button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) diff --git a/test/e2e/beta/metamask-beta-responsive-ui.spec.js b/test/e2e/beta/metamask-beta-responsive-ui.spec.js index 2ab8d86ce..98f0e02d5 100644 --- a/test/e2e/beta/metamask-beta-responsive-ui.spec.js +++ b/test/e2e/beta/metamask-beta-responsive-ui.spec.js @@ -81,15 +81,15 @@ describe('MetaMask', function () { describe('Going through the first time flow', () => { it('clicks the continue button on the welcome screen', async () => { - const welcomeScreenBtn = await findElement(driver, By.css('.welcome-screen__button')) + const welcomeScreenBtn = await findElement(driver, By.css('.welcome-page .first-time-flow__button')) welcomeScreenBtn.click() await delay(largeDelayMs) }) it('accepts a secure password', async () => { - const passwordBox = await findElement(driver, By.css('.create-password #create-password')) - const passwordBoxConfirm = await findElement(driver, By.css('.create-password #confirm-password')) - const button = await findElement(driver, By.css('.create-password button')) + const passwordBox = await findElement(driver, By.css('.first-time-flow__form #create-password')) + const passwordBoxConfirm = await findElement(driver, By.css('.first-time-flow__form #confirm-password')) + const button = await findElement(driver, By.css('.first-time-flow__form button')) await passwordBox.sendKeys('correct horse battery staple') await passwordBoxConfirm.sendKeys('correct horse battery staple') @@ -98,19 +98,21 @@ describe('MetaMask', function () { }) it('clicks through the unique image screen', async () => { - const nextScreen = await findElement(driver, By.css('.unique-image button')) + await findElement(driver, By.css('.first-time-flow__unique-image')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) it('clicks through the ToS', async () => { // terms of use - const canClickThrough = await driver.findElement(By.css('.tou button')).isEnabled() + await findElement(driver, By.css('.first-time-flow__markdown')) + const canClickThrough = await driver.findElement(By.css('button.first-time-flow__button')).isEnabled() assert.equal(canClickThrough, false, 'disabled continue button') const bottomOfTos = await findElement(driver, By.linkText('Attributions')) await driver.executeScript('arguments[0].scrollIntoView(true)', bottomOfTos) await delay(regularDelayMs) - const acceptTos = await findElement(driver, By.css('.tou button')) + const acceptTos = await findElement(driver, By.css('button.first-time-flow__button')) driver.wait(until.elementIsEnabled(acceptTos)) await acceptTos.click() await delay(regularDelayMs) @@ -118,17 +120,17 @@ describe('MetaMask', function () { it('clicks through the privacy notice', async () => { // privacy notice - const nextScreen = await findElement(driver, By.css('.tou button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) it('clicks through the phishing notice', async () => { // phishing notice - const noticeElement = await driver.findElement(By.css('.markdown')) + const noticeElement = await driver.findElement(By.css('.first-time-flow__markdown')) await driver.executeScript('arguments[0].scrollTop = arguments[0].scrollHeight', noticeElement) await delay(regularDelayMs) - const nextScreen = await findElement(driver, By.css('.tou button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) @@ -136,24 +138,23 @@ describe('MetaMask', function () { let seedPhrase it('reveals the seed phrase', async () => { - const byRevealButton = By.css('.backup-phrase__secret-blocker .backup-phrase__reveal-button') + const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button') await driver.wait(until.elementLocated(byRevealButton, 10000)) const revealSeedPhraseButton = await findElement(driver, byRevealButton, 10000) await revealSeedPhraseButton.click() await delay(regularDelayMs) - seedPhrase = await driver.findElement(By.css('.backup-phrase__secret-words')).getText() + seedPhrase = await driver.findElement(By.css('.reveal-seed-phrase__secret-words')).getText() assert.equal(seedPhrase.split(' ').length, 12) await delay(regularDelayMs) - const nextScreen = await findElement(driver, By.css('.backup-phrase button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) async function clickWordAndWait (word) { - const xpathClass = 'backup-phrase__confirm-seed-option backup-phrase__confirm-seed-option--unselected' - const xpath = `//button[@class='${xpathClass}' and contains(text(), '${word}')]` + const xpath = `//div[contains(@class, 'confirm-seed-phrase__seed-word--shuffled') and not(contains(@class, 'confirm-seed-phrase__seed-word--selected')) and contains(text(), '${word}')]` const word0 = await findElement(driver, By.xpath(xpath), 10000) await word0.click() @@ -163,13 +164,13 @@ describe('MetaMask', function () { async function retypeSeedPhrase (words, wasReloaded, count = 0) { try { if (wasReloaded) { - const byRevealButton = By.css('.backup-phrase__secret-blocker .backup-phrase__reveal-button') + const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button') await driver.wait(until.elementLocated(byRevealButton, 10000)) const revealSeedPhraseButton = await findElement(driver, byRevealButton, 10000) await revealSeedPhraseButton.click() await delay(regularDelayMs) - const nextScreen = await findElement(driver, By.css('.backup-phrase button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) } @@ -191,6 +192,7 @@ describe('MetaMask', function () { const words = seedPhrase.split(' ') await retypeSeedPhrase(words) + await delay(regularDelayMs) const confirm = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`)) await confirm.click() diff --git a/test/e2e/beta/metamask-beta-ui.spec.js b/test/e2e/beta/metamask-beta-ui.spec.js index a69b25e77..489b9b9da 100644 --- a/test/e2e/beta/metamask-beta-ui.spec.js +++ b/test/e2e/beta/metamask-beta-ui.spec.js @@ -102,15 +102,15 @@ describe('MetaMask', function () { describe('Going through the first time flow', () => { it('clicks the continue button on the welcome screen', async () => { - const welcomeScreenBtn = await findElement(driver, By.css('.welcome-screen__button')) + const welcomeScreenBtn = await findElement(driver, By.css('.welcome-page .first-time-flow__button')) welcomeScreenBtn.click() await delay(largeDelayMs) }) it('accepts a secure password', async () => { - const passwordBox = await findElement(driver, By.css('.create-password #create-password')) - const passwordBoxConfirm = await findElement(driver, By.css('.create-password #confirm-password')) - const button = await findElement(driver, By.css('.create-password button')) + const passwordBox = await findElement(driver, By.css('.first-time-flow__form #create-password')) + const passwordBoxConfirm = await findElement(driver, By.css('.first-time-flow__form #confirm-password')) + const button = await findElement(driver, By.css('.first-time-flow__form button')) await passwordBox.sendKeys('correct horse battery staple') await passwordBoxConfirm.sendKeys('correct horse battery staple') @@ -119,19 +119,21 @@ describe('MetaMask', function () { }) it('clicks through the unique image screen', async () => { - const nextScreen = await findElement(driver, By.css('.unique-image button')) + await findElement(driver, By.css('.first-time-flow__unique-image')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) it('clicks through the ToS', async () => { // terms of use - const canClickThrough = await driver.findElement(By.css('.tou button')).isEnabled() + await findElement(driver, By.css('.first-time-flow__markdown')) + const canClickThrough = await driver.findElement(By.css('button.first-time-flow__button')).isEnabled() assert.equal(canClickThrough, false, 'disabled continue button') const bottomOfTos = await findElement(driver, By.linkText('Attributions')) await driver.executeScript('arguments[0].scrollIntoView(true)', bottomOfTos) await delay(regularDelayMs) - const acceptTos = await findElement(driver, By.css('.tou button')) + const acceptTos = await findElement(driver, By.css('button.first-time-flow__button')) driver.wait(until.elementIsEnabled(acceptTos)) await acceptTos.click() await delay(regularDelayMs) @@ -139,17 +141,17 @@ describe('MetaMask', function () { it('clicks through the privacy notice', async () => { // privacy notice - const nextScreen = await findElement(driver, By.css('.tou button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) it('clicks through the phishing notice', async () => { // phishing notice - const noticeElement = await driver.findElement(By.css('.markdown')) + const noticeElement = await driver.findElement(By.css('.first-time-flow__markdown')) await driver.executeScript('arguments[0].scrollTop = arguments[0].scrollHeight', noticeElement) await delay(regularDelayMs) - const nextScreen = await findElement(driver, By.css('.tou button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) @@ -157,24 +159,23 @@ describe('MetaMask', function () { let seedPhrase it('reveals the seed phrase', async () => { - const byRevealButton = By.css('.backup-phrase__secret-blocker .backup-phrase__reveal-button') + const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button') await driver.wait(until.elementLocated(byRevealButton, 10000)) const revealSeedPhraseButton = await findElement(driver, byRevealButton, 10000) await revealSeedPhraseButton.click() await delay(regularDelayMs) - seedPhrase = await driver.findElement(By.css('.backup-phrase__secret-words')).getText() + seedPhrase = await driver.findElement(By.css('.reveal-seed-phrase__secret-words')).getText() assert.equal(seedPhrase.split(' ').length, 12) await delay(regularDelayMs) - const nextScreen = await findElement(driver, By.css('.backup-phrase button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) }) async function clickWordAndWait (word) { - const xpathClass = 'backup-phrase__confirm-seed-option backup-phrase__confirm-seed-option--unselected' - const xpath = `//button[@class='${xpathClass}' and contains(text(), '${word}')]` + const xpath = `//div[contains(@class, 'confirm-seed-phrase__seed-word--shuffled') and not(contains(@class, 'confirm-seed-phrase__seed-word--selected')) and contains(text(), '${word}')]` const word0 = await findElement(driver, By.xpath(xpath), 10000) await word0.click() @@ -184,13 +185,13 @@ describe('MetaMask', function () { async function retypeSeedPhrase (words, wasReloaded, count = 0) { try { if (wasReloaded) { - const byRevealButton = By.css('.backup-phrase__secret-blocker .backup-phrase__reveal-button') + const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button') await driver.wait(until.elementLocated(byRevealButton, 10000)) const revealSeedPhraseButton = await findElement(driver, byRevealButton, 10000) await revealSeedPhraseButton.click() await delay(regularDelayMs) - const nextScreen = await findElement(driver, By.css('.backup-phrase button')) + const nextScreen = await findElement(driver, By.css('button.first-time-flow__button')) await nextScreen.click() await delay(regularDelayMs) } diff --git a/test/e2e/func.js b/test/e2e/func.js index 5301d78ae..dfad8466c 100644 --- a/test/e2e/func.js +++ b/test/e2e/func.js @@ -85,7 +85,7 @@ function buildFirefoxWebdriver (opts = {}) { async function getExtensionIdChrome (driver) { await driver.get('chrome://extensions') - const extensionId = await driver.executeScript('return document.querySelector("extensions-manager").shadowRoot.querySelector("extensions-view-manager extensions-item-list").shadowRoot.querySelector("extensions-item:nth-child(2)").getAttribute("id")') + const extensionId = await driver.executeScript('return document.querySelector("extensions-manager").shadowRoot.querySelector("extensions-item-list").shadowRoot.querySelector("extensions-item:nth-child(2)").getAttribute("id")') return extensionId } diff --git a/test/unit/migrations/031-test.js b/test/unit/migrations/031-test.js new file mode 100644 index 000000000..c85fd7af4 --- /dev/null +++ b/test/unit/migrations/031-test.js @@ -0,0 +1,56 @@ +const assert = require('assert') +const migration31 = require('../../../app/scripts/migrations/031') + + describe('migration #31', () => { + it('should set completedOnboarding to true if vault exists', done => { + const oldStorage = { + 'meta': {}, + 'data': { + 'PreferencesController': { + 'tokens': [{address: '0xa', symbol: 'A', decimals: 4}, {address: '0xb', symbol: 'B', decimals: 4}], + 'identities': { + '0x6d14': {}, + '0x3695': {}, + }, + }, + 'KeyringController': { + 'vault': { + 'data': 'test0', + 'iv': 'test1', + 'salt': 'test2', + }, + }, + }, + } + + migration31.migrate(oldStorage) + .then(newStorage => { + assert.equal(newStorage.data.PreferencesController.completedOnboarding, true) + done() + }) + .catch(done) + }) + + it('should set completedOnboarding to false if vault does not exist', done => { + const oldStorage = { + 'meta': {}, + 'data': { + 'PreferencesController': { + 'tokens': [{address: '0xa', symbol: 'A', decimals: 4}, {address: '0xb', symbol: 'B', decimals: 4}], + 'identities': { + '0x6d14': {}, + '0x3695': {}, + }, + }, + 'KeyringController': {}, + }, + } + + migration31.migrate(oldStorage) + .then(newStorage => { + assert.equal(newStorage.data.PreferencesController.completedOnboarding, false) + done() + }) + .catch(done) + }) +}) diff --git a/test/unit/ui/app/actions.spec.js b/test/unit/ui/app/actions.spec.js index c7ac8b6cf..8d7de8b02 100644 --- a/test/unit/ui/app/actions.spec.js +++ b/test/unit/ui/app/actions.spec.js @@ -198,7 +198,7 @@ describe('Actions', () => { createNewVaultAndRestoreSpy = sinon.spy(background, 'createNewVaultAndRestore') clearSeedWordCacheSpy = sinon.spy(background, 'clearSeedWordCache') return store.dispatch(actions.createNewVaultAndRestore()) - .then(() => { + .catch(() => { assert(clearSeedWordCacheSpy.calledOnce) assert(createNewVaultAndRestoreSpy.calledOnce) }) @@ -218,7 +218,7 @@ describe('Actions', () => { }) return store.dispatch(actions.createNewVaultAndRestore()) - .then(() => { + .catch(() => { assert.deepEqual(store.getActions(), expectedActions) }) }) @@ -240,7 +240,7 @@ describe('Actions', () => { }) return store.dispatch(actions.createNewVaultAndRestore()) - .then(() => { + .catch(() => { assert.deepEqual(store.getActions(), expectedActions) }) }) -- cgit v1.2.3