diff --git a/.eslintrc b/.eslintrc index bbe3a8a7..5c87b414 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,6 +4,9 @@ "plugin:flowtype/recommended", "plugin:jest/recommended" ], + "globals": { + "COMMITHASH": true + }, "env": { "browser": true, "jest": true diff --git a/jest.config.js b/jest.config.js index d7e1c86a..d9c12451 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,11 +1,19 @@ module.exports = { rootDir: './src', + automock: false, + coverageDirectory: 'coverage/', collectCoverage: true, testURL: 'http://localhost', modulePathIgnorePatterns: [ 'node_modules', + 'utils/windowUtils.js', + 'utils/promiseUtils.js', + 'utils/networkUtils.js', ], collectCoverageFrom: [ 'utils/**.js', ], + setupFiles: [ + './support/setupJest.js', + ], }; diff --git a/package.json b/package.json index d920fb90..27532f4c 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,11 @@ "ethereumjs-tx": "^1.3.3", "ethereumjs-units": "^0.2.0", "ethereumjs-util": "^5.1.4", + "git-revision-webpack-plugin": "^3.0.3", + "flow-webpack-plugin": "^1.2.0", "hdkey": "^0.8.0", "html-webpack-plugin": "^3.2.0", + "jest-fetch-mock": "^1.6.5", "npm-run-all": "^4.1.3", "prop-types": "^15.6.2", "raf": "^3.4.0", diff --git a/src/components/Checkbox/index.js b/src/components/Checkbox/index.js index 1f4eef2b..0201a2f1 100644 --- a/src/components/Checkbox/index.js +++ b/src/components/Checkbox/index.js @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; import colors from 'config/colors'; import Icon from 'components/Icon'; import icons from 'config/icons'; @@ -34,8 +34,10 @@ const IconWrapper = styled.div` &:hover, &:focus { - border: 1px solid ${colors.TEXT_PRIMARY}; - background: ${props => (props.checked ? colors.TEXT_PRIMARY : colors.WHITE)}; + ${props => !props.checked && css` + border: 1px solid ${colors.GREEN_PRIMARY}; + `} + background: ${props => (props.checked ? colors.GREEN_PRIMARY : colors.WHITE)}; } `; diff --git a/src/components/Footer/index.js b/src/components/Footer/index.js index fa695d98..8f19462c 100644 --- a/src/components/Footer/index.js +++ b/src/components/Footer/index.js @@ -29,7 +29,7 @@ const Copy = styled.div` const Footer = ({ toggle }) => ( - © {getYear(new Date())} + © {getYear(new Date())} SatoshiLabs Terms Show Log diff --git a/src/components/Icon/index.js b/src/components/Icon/index.js index 6e5b0d71..1879547c 100644 --- a/src/components/Icon/index.js +++ b/src/components/Icon/index.js @@ -27,7 +27,7 @@ const SvgWrapper = styled.svg` :hover { path { - fill: ${props => props.hoverColor || colors.TEXT_SECONDARY} + fill: ${props => props.hoverColor} } } `; diff --git a/src/components/Paragraph/index.js b/src/components/Paragraph/index.js index 88a24fb8..34f498de 100644 --- a/src/components/Paragraph/index.js +++ b/src/components/Paragraph/index.js @@ -26,10 +26,7 @@ const P = ({ children, className, isSmaller = false }) => ( P.propTypes = { className: PropTypes.string, isSmaller: PropTypes.bool, - children: PropTypes.oneOfType([ - PropTypes.array, - PropTypes.string, - ]), + children: PropTypes.node, }; export default P; diff --git a/src/components/inputs/Input/index.js b/src/components/inputs/Input/index.js index 339b73cc..5bd17dc5 100644 --- a/src/components/inputs/Input/index.js +++ b/src/components/inputs/Input/index.js @@ -114,6 +114,7 @@ class Input extends Component { /> )} { } = this.state; // } = this.props.modal; - let passphraseInputValue: string = passphrase; - let passphraseRevisionInputValue: string = passphraseRevision; - if (!visible && !passphraseFocused) { - passphraseInputValue = passphrase.replace(/./g, '•'); - } - if (!visible && !passphraseRevisionFocused) { - passphraseRevisionInputValue = passphraseRevision.replace(/./g, '•'); - } + const passphraseInputValue: string = passphrase; + const passphraseRevisionInputValue: string = passphraseRevision; + // if (!visible && !passphraseFocused) { + // passphraseInputValue = passphrase.replace(/./g, '•'); + // } + // if (!visible && !passphraseRevisionFocused) { + // passphraseRevisionInputValue = passphraseRevision.replace(/./g, '•'); + // } + if (this.passphraseInput) { - this.passphraseInput.value = passphraseInputValue; - this.passphraseInput.setAttribute('type', visible || (!visible && !passphraseFocused) ? 'text' : 'password'); + // this.passphraseInput.value = passphraseInputValue; + // this.passphraseInput.setAttribute('type', visible || (!visible && !passphraseFocused) ? 'text' : 'password'); + this.passphraseInput.setAttribute('type', visible ? 'text' : 'password'); } if (this.passphraseRevisionInput) { - this.passphraseRevisionInput.value = passphraseRevisionInputValue; - this.passphraseRevisionInput.setAttribute('type', visible || (!visible && !passphraseRevisionFocused) ? 'text' : 'password'); + // this.passphraseRevisionInput.value = passphraseRevisionInputValue; + // this.passphraseRevisionInput.setAttribute('type', visible || (!visible && !passphraseRevisionFocused) ? 'text' : 'password'); + this.passphraseRevisionInput.setAttribute('type', visible ? 'text' : 'password'); } } @@ -174,6 +181,14 @@ export default class PinModal extends Component { match: previousState.singleInput || previousState.passphraseRevision === value, passphrase: value, })); + + if (this.state.visible && this.passphraseRevisionInput) { + this.setState({ + match: true, + passphraseRevision: value, + }); + this.passphraseRevisionInput.value = value; + } } else { this.setState(previousState => ({ match: previousState.passphrase === value, @@ -211,12 +226,29 @@ export default class PinModal extends Component { this.setState({ visible: true, }); + if (this.passphraseRevisionInput) { + this.passphraseRevisionInput.disabled = true; + this.passphraseRevisionInput.value = this.state.passphrase; + this.setState(previousState => ({ + passphraseRevision: previousState.passphrase, + match: true, + })); + } } onPassphraseHide = (): void => { this.setState({ visible: false, }); + if (this.passphraseRevisionInput) { + const emptyPassphraseRevisionValue = ''; + this.passphraseRevisionInput.value = emptyPassphraseRevisionValue; + this.setState(previousState => ({ + passphraseRevision: emptyPassphraseRevisionValue, + match: emptyPassphraseRevisionValue === previousState.passphrase, + })); + this.passphraseRevisionInput.disabled = false; + } } submit = (empty: boolean = false): void => { @@ -232,7 +264,7 @@ export default class PinModal extends Component { //this.passphraseRevisionInput.style.display = 'none'; //this.passphraseRevisionInput.setAttribute('readonly', 'readonly'); - const p = passphrase; + // const p = passphrase; this.setState({ passphrase: '', @@ -271,11 +303,10 @@ export default class PinModal extends Component { //let passphraseRevisionInputType: string = visible || passphraseRevisionFocused ? "text" : "password"; const showPassphraseCheckboxFn: Function = visible ? this.onPassphraseHide : this.onPassphraseShow; - console.log('passphraseInputType', passphraseInputType); return ( - {/* ?

Enter { deviceLabel } passphrase

*/} - {/*

Note that passphrase is case-sensitive.

*/} +

Enter { deviceLabel } passphrase

+

Note that passphrase is case-sensitive.

{ data-lpignore="true" onFocus={() => this.onPassphraseFocus('passphrase')} onBlur={() => this.onPassphraseBlur('passphrase')} - tabIndex="1" + tabIndex="0" /> {!singleInput && ( @@ -306,7 +337,6 @@ export default class PinModal extends Component { data-lpignore="true" onFocus={() => this.onPassphraseFocus('revision')} onBlur={() => this.onPassphraseBlur('revision')} - tabIndex="2" /> {!match && passphraseRevisionTouched && Passphrases do not match } @@ -315,7 +345,7 @@ export default class PinModal extends Component { Show passphrase - +