Merge pull request #1356 from MetaMask/mascaraTuneUps
Mascara tune upsfeature/default_network_editable
commit
012f837c1d
@ -1,20 +1,24 @@ |
|||||||
start the dual servers (dapp + mascara) |
start the dual servers (dapp + mascara) |
||||||
``` |
``` |
||||||
node server.js |
npm run mascara |
||||||
``` |
``` |
||||||
|
|
||||||
## First time use: |
## First time use: |
||||||
|
|
||||||
- navigate to: http://localhost:9001/popup/popup.html |
- navigate to: http://localhost:9001 |
||||||
- Create an Account |
- Create an Account |
||||||
- go back to http://localhost:9002/ |
- go back to http://localhost:9002 |
||||||
- open devTools |
- open devTools |
||||||
- click Sync Tx |
- click Sync Tx |
||||||
|
|
||||||
### Todos |
## Tests: |
||||||
|
|
||||||
- [ ] Figure out user flows and UI redesign |
``` |
||||||
- [ ] Figure out FireFox |
npm run testMascara |
||||||
Standing problems: |
``` |
||||||
- [ ] IndexDb |
|
||||||
|
Test will run in browser, you will have to have these browsers installed: |
||||||
|
|
||||||
|
- Chrome |
||||||
|
- Firefox |
||||||
|
- Opera |
||||||
|
@ -1,71 +0,0 @@ |
|||||||
const EventEmitter = require('events') |
|
||||||
module.exports = class IndexDbController extends EventEmitter { |
|
||||||
|
|
||||||
constructor (opts) { |
|
||||||
super() |
|
||||||
global.IDBTransaction = global.IDBTransaction || global.webkitIDBTransaction || global.msIDBTransaction || {READ_WRITE: "readwrite"}; // This line should only be needed if it is needed to support the object's constants for older browsers
|
|
||||||
global.IDBKeyRange = global.IDBKeyRange || global.webkitIDBKeyRange || global.msIDBKeyRange |
|
||||||
this.migrations = opts.migrations |
|
||||||
this.key = opts.key |
|
||||||
this.version = opts.version |
|
||||||
this.initialState = opts.initialState |
|
||||||
} |
|
||||||
|
|
||||||
// Opens the database connection and returns a promise
|
|
||||||
open () { |
|
||||||
return this.get('dataStore') |
|
||||||
.then((data) => { |
|
||||||
if (!data) { |
|
||||||
return this._add('dataStore', this.initialState) |
|
||||||
.then(() => this.get('dataStore')) |
|
||||||
.then((versionedData) => Promise.resolve(versionedData)) |
|
||||||
} |
|
||||||
return Promise.resolve(data) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
get (key = 'dataStore') { |
|
||||||
return this._request('get', key) |
|
||||||
} |
|
||||||
put (state) { |
|
||||||
return this._request('put', state, 'dataStore') |
|
||||||
} |
|
||||||
|
|
||||||
_add (key = 'dataStore', objStore) { |
|
||||||
return this._request('add', objStore, key) |
|
||||||
} |
|
||||||
|
|
||||||
_request (call, ...args) { |
|
||||||
return new Promise((resolve, reject) => { |
|
||||||
const self = this |
|
||||||
const dbOpenRequest = global.indexedDB.open(this.key, this.version) |
|
||||||
|
|
||||||
dbOpenRequest.addEventListener('upgradeneeded', (event) => { |
|
||||||
this.db = event.target.result |
|
||||||
this.db.createObjectStore('dataStore') |
|
||||||
}) |
|
||||||
|
|
||||||
dbOpenRequest.onsuccess = (event) => { |
|
||||||
this.db = dbOpenRequest.result |
|
||||||
this.emit('success') |
|
||||||
const dbTransaction = this.db.transaction('dataStore', 'readwrite') |
|
||||||
const request = dbTransaction.objectStore('dataStore') |
|
||||||
const objRequest = request[call](...args) |
|
||||||
objRequest.addEventListener('success', (event) => { |
|
||||||
return resolve(objRequest.result) |
|
||||||
}) |
|
||||||
objRequest.addEventListener('error', (err) => { |
|
||||||
return reject(`IndexDBController - ${call} failed to excute on indexedDB`) |
|
||||||
}) |
|
||||||
dbTransaction.addEventListener('complete', (event) => { |
|
||||||
this.emit('complete') |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
dbOpenRequest.addEventListener('error', (event) => { |
|
||||||
return reject({message: `IndexDBController - open:@${call} failed to excute on indexedDB`, errorEvent: event}) |
|
||||||
}) |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,7 @@ |
|||||||
|
function wait(time) { |
||||||
|
return new Promise(function(resolve, reject) { |
||||||
|
setTimeout(function() { |
||||||
|
resolve() |
||||||
|
}, time * 3 || 1500) |
||||||
|
}) |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<meta name="viewport" content="width=device-width"> |
||||||
|
<title>QUnit Example</title> |
||||||
|
<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.0.0.css"> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div id="qunit"></div> |
||||||
|
<div id="qunit-fixture"></div> |
||||||
|
<script src="https://code.jquery.com/qunit/qunit-2.0.0.js"></script> |
||||||
|
<script src="./jquery-3.1.0.min.js"></script> |
||||||
|
<script src="./helpers.js"></script> |
||||||
|
<script src="./test-bundle.js"></script> |
||||||
|
<script src="/testem.js"></script> |
||||||
|
|
||||||
|
<div id="app-content"></div> |
||||||
|
<script src="./bundle.js"></script> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,22 @@ |
|||||||
|
var fs = require('fs') |
||||||
|
var path = require('path') |
||||||
|
var browserify = require('browserify'); |
||||||
|
var tests = fs.readdirSync(path.join(__dirname, 'lib')) |
||||||
|
var bundlePath = path.join(__dirname, 'test-bundle.js') |
||||||
|
var b = browserify(); |
||||||
|
|
||||||
|
// Remove old bundle
|
||||||
|
try { |
||||||
|
fs.unlinkSync(bundlePath) |
||||||
|
} catch (e) { |
||||||
|
console.error(e) |
||||||
|
} |
||||||
|
|
||||||
|
var writeStream = fs.createWriteStream(bundlePath) |
||||||
|
|
||||||
|
tests.forEach(function(fileName) { |
||||||
|
b.add(path.join(__dirname, 'lib', fileName)) |
||||||
|
}) |
||||||
|
|
||||||
|
b.bundle().pipe(writeStream); |
||||||
|
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,119 @@ |
|||||||
|
const PASSWORD = 'password123' |
||||||
|
|
||||||
|
QUnit.module('first time usage') |
||||||
|
|
||||||
|
QUnit.test('render init screen', function (assert) { |
||||||
|
var done = assert.async() |
||||||
|
let app |
||||||
|
|
||||||
|
wait(1000).then(function() { |
||||||
|
app = $('#app-content').contents() |
||||||
|
const recurseNotices = function () { |
||||||
|
let button = app.find('button') |
||||||
|
if (button.html() === 'Continue') { |
||||||
|
let termsPage = app.find('.markdown')[0] |
||||||
|
termsPage.scrollTop = termsPage.scrollHeight |
||||||
|
return wait().then(() => { |
||||||
|
button.click() |
||||||
|
return wait() |
||||||
|
}).then(() => { |
||||||
|
return recurseNotices() |
||||||
|
}) |
||||||
|
} else { |
||||||
|
return wait() |
||||||
|
} |
||||||
|
} |
||||||
|
return recurseNotices() |
||||||
|
}).then(function() { |
||||||
|
// Scroll through terms
|
||||||
|
var title = app.find('h1').text() |
||||||
|
assert.equal(title, 'MetaMask', 'title screen') |
||||||
|
|
||||||
|
// enter password
|
||||||
|
var pwBox = app.find('#password-box')[0] |
||||||
|
var confBox = app.find('#password-box-confirm')[0] |
||||||
|
pwBox.value = PASSWORD |
||||||
|
confBox.value = PASSWORD |
||||||
|
|
||||||
|
return wait() |
||||||
|
}).then(function() { |
||||||
|
|
||||||
|
// create vault
|
||||||
|
var createButton = app.find('button.primary')[0] |
||||||
|
createButton.click() |
||||||
|
|
||||||
|
return wait(1500) |
||||||
|
}).then(function() { |
||||||
|
|
||||||
|
var created = app.find('h3')[0] |
||||||
|
assert.equal(created.textContent, 'Vault Created', 'Vault created screen') |
||||||
|
|
||||||
|
// Agree button
|
||||||
|
var button = app.find('button')[0] |
||||||
|
assert.ok(button, 'button present') |
||||||
|
button.click() |
||||||
|
|
||||||
|
return wait(1000) |
||||||
|
}).then(function() { |
||||||
|
|
||||||
|
var detail = app.find('.account-detail-section')[0] |
||||||
|
assert.ok(detail, 'Account detail section loaded.') |
||||||
|
|
||||||
|
var sandwich = app.find('.sandwich-expando')[0] |
||||||
|
sandwich.click() |
||||||
|
|
||||||
|
return wait() |
||||||
|
}).then(function() { |
||||||
|
|
||||||
|
var sandwich = app.find('.menu-droppo')[0] |
||||||
|
var children = sandwich.children |
||||||
|
var lock = children[children.length - 2] |
||||||
|
assert.ok(lock, 'Lock menu item found') |
||||||
|
lock.click() |
||||||
|
|
||||||
|
return wait(1000) |
||||||
|
}).then(function() { |
||||||
|
|
||||||
|
var pwBox = app.find('#password-box')[0] |
||||||
|
pwBox.value = PASSWORD |
||||||
|
|
||||||
|
var createButton = app.find('button.primary')[0] |
||||||
|
createButton.click() |
||||||
|
|
||||||
|
return wait(1000) |
||||||
|
}).then(function() { |
||||||
|
|
||||||
|
var detail = app.find('.account-detail-section')[0] |
||||||
|
assert.ok(detail, 'Account detail section loaded again.') |
||||||
|
|
||||||
|
return wait() |
||||||
|
}).then(function (){ |
||||||
|
|
||||||
|
var qrButton = app.find('.fa.fa-qrcode')[0] |
||||||
|
qrButton.click() |
||||||
|
|
||||||
|
return wait(1000) |
||||||
|
}).then(function (){ |
||||||
|
|
||||||
|
var qrHeader = app.find('.qr-header')[0] |
||||||
|
var qrContainer = app.find('#qr-container')[0] |
||||||
|
assert.equal(qrHeader.textContent, 'Account 1', 'Should show account label.') |
||||||
|
assert.ok(qrContainer, 'QR Container found') |
||||||
|
|
||||||
|
return wait() |
||||||
|
}).then(function (){ |
||||||
|
|
||||||
|
var networkMenu = app.find('.network-indicator')[0] |
||||||
|
networkMenu.click() |
||||||
|
|
||||||
|
return wait() |
||||||
|
}).then(function (){ |
||||||
|
|
||||||
|
var networkMenu = app.find('.network-indicator')[0] |
||||||
|
var children = networkMenu.children |
||||||
|
children.length[3] |
||||||
|
assert.ok(children, 'All network options present') |
||||||
|
|
||||||
|
done() |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,13 @@ |
|||||||
|
launch_in_dev: |
||||||
|
- Chrome |
||||||
|
- Firefox |
||||||
|
- Opera |
||||||
|
launch_in_ci: |
||||||
|
- Chrome |
||||||
|
- Firefox |
||||||
|
- Opera |
||||||
|
framework: |
||||||
|
- qunit |
||||||
|
before_tests: "npm run mascaraCi" |
||||||
|
after_tests: "rm ./background.js ./test-bundle.js ./bundle.js" |
||||||
|
test_page: "./index.html" |
@ -0,0 +1,40 @@ |
|||||||
|
const EventEmitter = require('events') |
||||||
|
const IDB = require('idb-global') |
||||||
|
const KEY = 'metamask-test-config' |
||||||
|
module.exports = class Helper extends EventEmitter { |
||||||
|
constructor () { |
||||||
|
super() |
||||||
|
} |
||||||
|
|
||||||
|
tryToCleanContext () { |
||||||
|
this.unregister() |
||||||
|
.then(() => this.clearDb()) |
||||||
|
.then(() => super.emit('complete')) |
||||||
|
.catch((err) => super.emit('complete')) |
||||||
|
} |
||||||
|
|
||||||
|
unregister () { |
||||||
|
return global.navigator.serviceWorker.getRegistration() |
||||||
|
.then((registration) => { |
||||||
|
if (registration) return registration.unregister() |
||||||
|
.then((b) => b ? Promise.resolve() : Promise.reject()) |
||||||
|
else return Promise.resolve() |
||||||
|
}) |
||||||
|
} |
||||||
|
clearDb () { |
||||||
|
return new Promise ((resolve, reject) => { |
||||||
|
const deleteRequest = global.indexDB.deleteDatabase(KEY) |
||||||
|
deleteRequest.addEventListener('success', resolve) |
||||||
|
deleteRequest.addEventListener('error', reject) |
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
mockState (state) { |
||||||
|
const db = new IDB({ |
||||||
|
version: 2, |
||||||
|
key: KEY, |
||||||
|
initialState: state |
||||||
|
}) |
||||||
|
return db.open() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
const Helper = require('./util/mascara-test-helper.js') |
||||||
|
|
||||||
|
window.addEventListener('load', () => { |
||||||
|
require('../src/ui.js') |
||||||
|
}) |
Loading…
Reference in new issue