Add mock dev mode

This commit is contained in:
Dan Finlay 2016-07-21 18:08:35 -07:00
parent 0bbfedc2bf
commit 5b4e2ffeac
9 changed files with 238 additions and 20 deletions

View File

@ -18,12 +18,6 @@
npm install
```
### Developing on UI Only
You can run `npm run ui`, and your browser should open a live-reloading demo version of the plugin UI.
Some actions will crash the app, so this is only for tuning aesthetics, but it allows live-reloading styles, which is a much faster feedback loop than reloading the full extension.
### Developing with Gulp
We're using an experimental version of `gulp-cli`, so if you have the old version of gulp, you'll need to uninstall it, `npm uninstall -g gulp`, and install this one instead:
@ -37,7 +31,7 @@ After that, you can just:
gulp dev
```
### In Chrome
#### In Chrome
Open `Settings` > `Extensions`.
@ -51,7 +45,21 @@ Click `Select`.
You now have the plugin, and can click 'inspect views: background plugin' to view its dev console.
### Developing the UI
### Developing on UI Only
You can run `npm run ui`, and your browser should open a live-reloading demo version of the plugin UI.
Some actions will crash the app, so this is only for tuning aesthetics, but it allows live-reloading styles, which is a much faster feedback loop than reloading the full extension.
### Developing on UI with Mocked Background Process
You can run `npm run mock` and your browser should open a live-reloading demo version of the plugin UI, just like the `npm run ui`, except that it tries to actually perform all normal operations.
It does not yet connect to a real blockchain (this could be a good test feature later, connecting to a test blockchain), so only local operations work.
You can reset the mock ui at any time with the `Reset` button at the top of the screen.
### Developing on Dependencies
To enjoy the live-reloading that `gulp dev` offers while working on the `web3-provider-engine` or other dependencies:

View File

@ -0,0 +1,39 @@
/* MockExtension
*
* A module for importing the global extension polyfiller
* and stubbing out all the extension methods with appropriate mocks.
*/
const extension = require('../app/scripts/lib/extension')
const noop = function () {}
const apis = [
'alarms',
'bookmarks',
'browserAction',
'commands',
'contextMenus',
'cookies',
'downloads',
'events',
'extension',
'extensionTypes',
'history',
'i18n',
'idle',
'notifications',
'pageAction',
'runtime',
'storage',
'tabs',
'webNavigation',
'webRequest',
'windows',
]
apis.forEach(function (api) {
extension[api] = {}
})
extension.runtime.reload = noop
extension.tabs.create = noop

File diff suppressed because one or more lines are too long

View File

@ -1,14 +1,17 @@
{
"metamask": {
"accounts": {},
"transactions": [],
"identities": {},
"network": "2",
"isInitialized": false,
"isUnlocked": false,
"currentDomain": "example.com",
"rpcTarget": "https://rawtestrpc.metamask.io/",
"identities": {},
"unconfTxs": {},
"accounts": {},
"transactions": [],
"network": "2",
"seedWords": null,
"isConfirmed": false,
"unconfTxs": {},
"isEthConfirmed": false,
"unconfMsgs": {},
"messages": [],
"provider": {
@ -16,6 +19,17 @@
}
},
"appState": {
"currentDomain": "extensions"
}
"menuOpen": false,
"currentView": {
"name": "EthStoreWarning"
},
"accountDetail": {
"subview": "transactions"
},
"currentDomain": "127.0.0.1:9966",
"transForward": true,
"isLoading": false,
"warning": null
},
"identities": {}
}

157
mock-dev.js Normal file
View File

@ -0,0 +1,157 @@
/* MOCK DEV
*
* This is a utility module.
* It initializes a minimalist browserifiable project
* that contains the Metamask UI, with a local background process.
*
* Includes a state reset button for restoring to initial state.
*
* This is a convenient way to develop and test the plugin
* without having to re-open the plugin or even re-build it.
*
* To use, run `npm run mock`.
*/
const extend = require('xtend')
const render = require('react-dom').render
const h = require('react-hyperscript')
const Root = require('./ui/app/root')
const configureStore = require('./ui/app/store')
const actions = require('./ui/app/actions')
const states = require('./development/states')
const MetamaskController = require('./app/scripts/metamask-controller')
const extension = require('./development/mockExtension')
// Query String
const qs = require('qs')
let queryString = qs.parse(window.location.href.split('#')[1])
let selectedView = queryString.view || 'terms'
const firstState = states[selectedView]
updateQueryParams(selectedView)
// CSS
const MetaMaskUiCss = require('./ui/css')
const injectCss = require('inject-css')
function updateQueryParams(newView) {
queryString.view = newView
const params = qs.stringify(queryString)
window.location.href = window.location.href.split('#')[0] + `#${params}`
}
const noop = function () {}
const controller = new MetamaskController({
// User confirmation callbacks:
showUnconfirmedMessage: noop,
unlockAccountMessage: noop,
showUnconfirmedTx: noop,
// Persistence Methods:
setData,
loadData,
})
// Stub out localStorage for non-browser environments
if (!window.localStorage) {
window.localStorage = {}
}
const STORAGE_KEY = 'metamask-config'
function loadData () {
var oldData = getOldStyleData()
var newData
try {
newData = JSON.parse(window.localStorage[STORAGE_KEY])
} catch (e) {}
var data = extend({
meta: {
version: 0,
},
data: {
config: {
provider: {
type: 'testnet',
},
},
},
}, oldData || null, newData || null)
return data
}
function setData (data) {
window.localStorage[STORAGE_KEY] = JSON.stringify(data)
}
function getOldStyleData () {
var config, wallet, seedWords
var result = {
meta: { version: 0 },
data: {},
}
try {
config = JSON.parse(window.localStorage['config'])
result.data.config = config
} catch (e) {}
try {
wallet = JSON.parse(window.localStorage['lightwallet'])
result.data.wallet = wallet
} catch (e) {}
try {
seedWords = window.localStorage['seedWords']
result.data.seedWords = seedWords
} catch (e) {}
return result
}
actions._setAccountManager(controller.getApi())
actions.update = function(stateName) {
selectedView = stateName
updateQueryParams(stateName)
const newState = states[selectedView]
return {
type: 'GLOBAL_FORCE_UPDATE',
value: newState,
}
}
var css = MetaMaskUiCss()
injectCss(css)
const container = document.querySelector('#app-content')
// parse opts
var store = configureStore(firstState)
// start app
render(
h('.super-dev-container', [
h('button', {
onClick: (ev) => {
ev.preventDefault()
store.dispatch(actions.update('terms'))
},
style: {
margin: '19px 19px 0px 19px',
},
}, 'Reset State'),
h('.mock-app-root', {
style: {
height: '500px',
width: '360px',
boxShadow: 'grey 0px 2px 9px',
margin: '20px',
},
}, [
h(Root, {
store: store,
}),
]),
]
), container)

View File

@ -7,7 +7,8 @@
"start": "gulp dev",
"test": "mocha --require test/helper.js --compilers js:babel-register --recursive",
"watch": "mocha watch --compilers js:babel-register --recursive",
"ui": "node development/genStates.js && beefy ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./"
"ui": "node development/genStates.js && beefy ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./",
"mock": "beefy mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./"
},
"browserify": {
"transform": [

View File

@ -18,7 +18,7 @@
const render = require('react-dom').render
const h = require('react-hyperscript')
const Root = require('./ui/app/root')
const configureStore = require('./development/mockStore')
const configureStore = require('./development/uiStore')
const states = require('./development/states')
const Selector = require('./development/selector')

View File

@ -37,7 +37,6 @@ AccountsScreen.prototype.render = function () {
var actions = {
onSelect: this.onSelect.bind(this),
onShowDetail: this.onShowDetail.bind(this),
revealAccount: this.onRevealAccount.bind(this),
goHome: this.goHome.bind(this),
}
return (
@ -88,7 +87,7 @@ AccountsScreen.prototype.render = function () {
h('div.footer.hover-white.pointer', {
key: 'reveal-account-bar',
onClick: () => {
actions.revealAccount()
this.onRevealAccount()
},
style: {
display: 'flex',