diff --git a/src/app/components/login/login.js b/src/app/components/login/login.js index 43eed4c50..bbbbbd31b 100644 --- a/src/app/components/login/login.js +++ b/src/app/components/login/login.js @@ -11,7 +11,7 @@ app.component('login', { onLogin: '&', }, controller: class login { - constructor($scope, $rootScope, $timeout, $document, $mdDialog, $mdMedia, $cookies) { + constructor($scope, $rootScope, $timeout, $document, $mdDialog, $mdMedia, $cookies, $peers) { this.$scope = $scope; this.$rootScope = $rootScope; this.$timeout = $timeout; @@ -19,6 +19,7 @@ app.component('login', { this.$mdDialog = $mdDialog; this.$mdMedia = $mdMedia; this.$cookies = $cookies; + this.$peers = $peers; this.$scope.$watch('$ctrl.input_passphrase', this.isValidPassphrase.bind(this)); this.$timeout(this.devTestAccount.bind(this), 200); @@ -26,6 +27,14 @@ app.component('login', { this.$scope.$watch(() => this.$mdMedia('xs') || this.$mdMedia('sm'), (wantsFullScreen) => { this.$scope.customFullscreen = wantsFullScreen === true; }); + this.$scope.$watch('$ctrl.$peers.currentPeerConfig', () => { + this.$peers.setActive(this.$peers.currentPeerConfig); + }); + this.$scope.$watch('$ctrl.$peers.stack', (val) => { + if (val && !this.$peers.currentPeerConfig.node) { + this.$peers.setActive($peers.stack.official[0]); + } + }); } reset() { diff --git a/src/app/components/login/login.pug b/src/app/components/login/login.pug index 858736d9c..ed28135bb 100644 --- a/src/app/components/login/login.pug +++ b/src/app/components/login/login.pug @@ -2,10 +2,15 @@ md-card md-card-title md-card-title-text span.md-title Sign In - md-card-content + md-card-content(flex='100', flex-gt-sm='70', flex-offset-gt-sm='15') form(ng-submit='$ctrl.doTheLogin()') md-input-container.md-block(md-is-error='$ctrl.valid === 0') - label Enter your passphrase + label.select Choose a peer + md-select(ng-model='$ctrl.$peers.currentPeerConfig', aria-label='Peer') + md-optgroup(ng-repeat='(name, peers) in $ctrl.$peers.stack', ng-if='peers.length', label='{{ name }}') + md-option(ng-repeat='peer in peers', ng-value='peer') {{ peer.node }}{{ peer.port ? ':' + peer.port : '' }} + md-input-container.md-block(md-is-error='$ctrl.valid === 0') + label.pass Enter your passphrase input(type="{{ $ctrl.show_passphrase ? 'text' : 'password' }}", ng-model='$ctrl.input_passphrase', ng-disabled='$ctrl.generatingNewPassphrase', autofocus) md-input-container.md-block md-checkbox.md-primary(ng-model="$ctrl.show_passphrase", aria-label="Show passphrase") Show passphrase diff --git a/src/app/components/main/main.js b/src/app/components/main/main.js index 00bd8088b..07ab7f46b 100644 --- a/src/app/components/main/main.js +++ b/src/app/components/main/main.js @@ -16,14 +16,6 @@ app.component('main', { this.error = error; this.$scope.$on('login', this.login.bind(this)); - this.$scope.$on('peerUpdate', this.update.bind(this)); - - $scope.$watch('$ctrl.$peers.active', (peer, old) => { - if (peer && old) { - this.$peers.check(); - this.$rootScope.$broadcast('peerUpdate'); - } - }); } reset() { @@ -65,7 +57,6 @@ app.component('main', { update() { this.reset(); - return this.$peers.active.getAccountPromise(this.address) .then((res) => { this.account = res; diff --git a/src/app/components/top/top.js b/src/app/components/top/top.js index e846ea4b2..4cfe1bc22 100644 --- a/src/app/components/top/top.js +++ b/src/app/components/top/top.js @@ -6,12 +6,8 @@ app.component('top', { account: '<', }, controller: class top { - constructor($peers, $scope) { + constructor($peers) { this.$peers = $peers; - - $scope.$watch('$ctrl.$peers.currentPeerConfig', () => { - this.$peers.setActive(this.$peers.currentPeerConfig); - }); } }, }); diff --git a/src/app/components/top/top.pug b/src/app/components/top/top.pug index e4b44c60c..f3672dbfc 100644 --- a/src/app/components/top/top.pug +++ b/src/app/components/top/top.pug @@ -9,9 +9,10 @@ md-content(layout='column', layout-gt-xs='row') i.material-icons.offline(ng-show='!$ctrl.$peers.online') error i.material-icons.online(ng-show='$ctrl.$peers.online') check circle span.md-title.title Peer - md-select(ng-model='$ctrl.$peers.currentPeerConfig', aria-label='Peer') - md-optgroup(ng-repeat='(name, peers) in $ctrl.$peers.stack', ng-if='peers.length', label='{{ name }}') - md-option(ng-repeat='peer in peers', ng-value='peer') {{ peer.node }}{{ name === 'localhost' ? ':' + peer.port : '' }} + div.active-peer.value + span(ng-bind="$ctrl.$peers.currentPeerConfig.node") + span(ng-if="$ctrl.$peers.currentPeerConfig.port") : + span(ng-bind="$ctrl.$peers.currentPeerConfig.port") md-card.offline-hide(flex-gt-xs=33) md-card-content(layout='column', layout-align='center center') span.md-title.title Balance diff --git a/src/app/index.less b/src/app/index.less index 50e3f28a4..b3f5892e6 100644 --- a/src/app/index.less +++ b/src/app/index.less @@ -10,3 +10,7 @@ body { md-card { margin-bottom: 20px; } +login, login md-card { + display: block; + height: auto; +} \ No newline at end of file diff --git a/src/karma.conf.js b/src/karma.conf.js index 1077ec696..a64f0f41d 100644 --- a/src/karma.conf.js +++ b/src/karma.conf.js @@ -95,6 +95,7 @@ module.exports = function (config) { // If true, Karma captures browsers, runs the tests and exits singleRun: !opts.live, client: { + captureConsole: true, mocha: { opts: 'test/mocha.opts', // You can set opts to equal true then plugin will load opts from default location 'test/mocha.opts' }, diff --git a/src/package.json b/src/package.json index 0faca8ec2..1b6553031 100644 --- a/src/package.json +++ b/src/package.json @@ -52,7 +52,7 @@ "jasmine-spec-reporter": "^3.2.0", "jit-grunt": "=0.10.0", "json-loader": "=0.5.4", - "karma": "^1.5.0", + "karma": "=1.4.1", "karma-babel-preprocessor": "=6.0.1", "karma-chai": "=0.1.0", "karma-chrome-launcher": "=2.0.0", diff --git a/src/spec/spec.js b/src/spec/spec.js index 3b7fae730..d73704e22 100644 --- a/src/spec/spec.js +++ b/src/spec/spec.js @@ -28,6 +28,7 @@ function checkErrorMessage(message) { function launchApp() { browser.ignoreSynchronization = true; + browser.driver.manage().window().setSize(1000, 1000); browser.get('http://localhost:8080#?peerStack=localhost'); } @@ -83,11 +84,15 @@ function testNewAccount() { launchApp(); element.all(by.css('.md-button.md-primary')).get(0).click(); + /** + * Generates a sequence of random pairs of x,y coordinates on the screen that simulates + * the movement of mouse to produce a pass phrase. + */ for (let i = 0; i < 250; i++) { browser.actions() .mouseMove(element(by.css('body')), { - x: Math.floor(Math.random() * 1000), - y: Math.floor(Math.random() * 1000), + x: 500 + (Math.floor((((i % 2) * 2) - 1) * (249 + (Math.random() * 250)))), + y: 500 + (Math.floor((((i % 2) * 2) - 1) * (249 + (Math.random() * 250)))), }).perform(); browser.sleep(5); } @@ -120,22 +125,19 @@ function testAddress() { } function testPeer() { - login(masterAccount); - waitForElemAndCheckItsText('.peer md-select-value .md-text', 'localhost:4000'); + expect(element.all(by.css('form md-select md-select-value span:first-child')).get(0).getText()).toEqual('Choose a peer'); } function testChangePeer() { - login(masterAccount); - - const peerElem = element(by.css('.peer md-select-value')); - browser.wait(EC.presenceOf(peerElem), waitTime); + const peerElem = element(by.css('form md-select')); + // browser.wait(EC.presenceOf(peerElem), waitTime); peerElem.click(); const optionElem = element.all(by.css('md-select-menu md-optgroup md-option')).get(0); browser.wait(EC.presenceOf(optionElem), waitTime); optionElem.click(); - waitForElemAndCheckItsText('.peer md-select-value .md-text', 'node01.lisk.io'); + waitForElemAndCheckItsText('form md-select-value .md-text', 'node01.lisk.io'); } function testShowBalance() { @@ -177,6 +179,7 @@ function testLoadMoreTransactions() { const moreButton = element(by.css('transactions button.more')); browser.wait(EC.presenceOf(moreButton), waitTime); moreButton.click(); + browser.sleep(200); expect(element.all(by.css('transactions table tbody tr')).count()).toEqual(20); } @@ -184,9 +187,9 @@ function testLoadMoreTransactions() { describe('Lisk Nano functionality', () => { it('should allow to login', testLogin); it('should allow to logout', testLogout); - it('should show address', testAddress); it('should show peer', testPeer); it('should allow to change peer', testChangePeer); + it('should show address', testAddress); it('should show balance', testShowBalance); it('should allow to send transaction when enough funds and correct address form', testSend); it('should not allow to send transaction when not enough funds', testSendWithNotEnoughFunds); diff --git a/src/test/components/login/login.spec.js b/src/test/components/login/login.spec.js index 4371845b8..38889290a 100644 --- a/src/test/components/login/login.spec.js +++ b/src/test/components/login/login.spec.js @@ -32,9 +32,14 @@ describe('Login component', () => { expect(element.find('.md-title').text()).to.equal(HEADER_TEXT); }); - const LABEL_TEXT = 'Enter your passphrase'; - it(`should contain a form with label saying "${LABEL_TEXT}"`, () => { - expect(element.find('form label').text()).to.equal(LABEL_TEXT); + const PASS_LABEL_TEXT = 'Enter your passphrase'; + it(`should contain a form input with label saying "${PASS_LABEL_TEXT}"`, () => { + expect(element.find('form md-input-container label.pass').text()).to.equal(PASS_LABEL_TEXT); + }); + + const SELECT_LABEL_TEXT = 'Choose a peer'; + it(`should contain a select element with label saying "${SELECT_LABEL_TEXT}"`, () => { + expect(element.find('form md-input-container label.select').text()).to.equal(SELECT_LABEL_TEXT); }); it('should contain an input field', () => { @@ -67,6 +72,29 @@ describe('Login controller', () => { controller.passphrase = ''; }); + describe('controller()', () => { + it('should define a watcher for $ctrl.$peers.currentPeerConfig', () => { + $scope.$apply(); + const peers = controller.$peers; + const spy = sinon.spy(peers, 'setActive'); + peers.currentPeerConfig = peers.stack.localhost[0]; + $scope.$apply(); + peers.currentPeerConfig = peers.stack.official[0]; + $scope.$apply(); + expect(spy).to.have.been.calledWith(); + }); + + it('should be able to change the active peer', () => { + $scope.$apply(); + controller.$peers.setActive(controller.$peers.stack.localhost[0]); + $scope.$apply(); + expect(controller.$peers.currentPeerConfig).to.equal(controller.$peers.stack.localhost[0]); + controller.$peers.setActive(controller.$peers.stack.official[0]); + $scope.$apply(); + expect(controller.$peers.currentPeerConfig).to.equal(controller.$peers.stack.official[0]); + }); + }); + describe('$scope.reset()', () => { it('makes input_passphrase empty', () => { const passphrase = 'TEST'; diff --git a/src/test/components/main/main.spec.js b/src/test/components/main/main.spec.js index 172a08c1e..c663f2a27 100644 --- a/src/test/components/main/main.spec.js +++ b/src/test/components/main/main.spec.js @@ -28,21 +28,6 @@ describe('main component controller', () => { }); }); - describe('controller()', () => { - it.skip('sets $watch on $ctrl.$peers.active to broadcast it changed', () => { - // Skipped as it doesn't work - $scope.$apply(); - const mock = sinon.mock(controller.$rootScope); - mock.expects('$broadcast').withArgs('peerUpdate').returns(); - controller.$peers.active = { name: 'CHANGED' }; - $scope.$apply(); - controller.$peers.active.name = 'CHANGED AGAIN'; - $scope.$apply(); - mock.verify(); - mock.restore(); - }); - }); - describe('reset()', () => { it('cancels $timeout', () => { const spy = sinon.spy(controller.$timeout, 'cancel'); diff --git a/src/webpack.config.babel.js b/src/webpack.config.babel.js index 03a537efe..f8ef63449 100644 --- a/src/webpack.config.babel.js +++ b/src/webpack.config.babel.js @@ -16,6 +16,7 @@ const PATHS = { }; const common = { + devtool: 'source-map', entry: nodeEnvironment === 'test' ? {} : { app: PATHS.app, },