<commit_before>import React from 'react';
import styled, { keyframes } from 'utils/styled-components';
import media from 'utils/media';
import FirstCloudSVG from 'components/icons/Cloud/firstCloud.svg';
import SecondCloudSVG from 'components/icons/Cloud/secondCloud.svg';
import ThirdCloudSVG from 'components/icons/Cloud/thirdCloud.svg';
import ForthCloudSVG from 'components/icons/Cloud/forthCloud.svg';

const row1Duration = '15s';
const row2Duration = '20s';
const row3Duration = '20s';
const row4Duration = '23s';

const transition = keyframes`
  0% {background-position-x: 0}
  100% {background-position-x: 200%}
`
const Wrapper = styled.div`
  position: fixed;
  width: 100%;
  height: 100vh;
  z-index: -1;
  background-position: center;
  background-size: cover;
  background-color: #00bffd;
  opacity: 0.15;
  animation-timing-function: linear;
  ${media.tablet`
    & * {
      display: none;
    }
  `}
`;
const Cloud = styled.div`
  animation: ${transition} 2s linear infinite;
  position: absolute;
  width: 100%;
  height: 100vh;
  background-repeat: no-repeat;
`
const CloudRow1 = styled(Cloud)`
  background: url(${FirstCloudSVG}) repeat-x;
  background-position-y: 90%;
  background-size: 66.6%;
  animation-duration: ${row1Duration};
`
const CloudRow2 = styled(Cloud)`
  background: url(${SecondCloudSVG}) repeat-x;
  background-position-y: 45%;
  background-size: 40%;
  animation-duration: ${row2Duration};
`
const CloudRow3 = styled(Cloud)`
  background: url(${ThirdCloudSVG}) repeat-x;
  background-position-y: 20%;
  background-size: 28.5%;
  animation-duration: ${row3Duration};
`
const CloudRow4 = styled(Cloud)`
  background: url(${ForthCloudSVG}) repeat-x;
  background-position-y: 5%;
  background-size: 20%;
  animation-duration: ${row4Duration};
`

const CloudAnimation = ({ ...props }) => (
  <Wrapper>
    <CloudRow1/>
    <CloudRow2/>
    <CloudRow3/>
    <CloudRow4/>
  </Wrapper>
)

export default CloudAnimation;
<commit_msg>Adding dynamic opacity for the CloudAnimation.<commit_after>import React from 'react';
import styled, { keyframes } from 'utils/styled-components';
import media from 'utils/media';
import FirstCloudSVG from 'components/icons/Cloud/firstCloud.svg';
import SecondCloudSVG from 'components/icons/Cloud/secondCloud.svg';
import ThirdCloudSVG from 'components/icons/Cloud/thirdCloud.svg';
import ForthCloudSVG from 'components/icons/Cloud/forthCloud.svg';

const row1Duration = '15s';
const row2Duration = '20s';
const row3Duration = '20s';
const row4Duration = '23s';

const transition = keyframes`
  0% {background-position-x: 0}
  100% {background-position-x: 200%}
`
const Wrapper = styled.div`
  position: fixed;
  width: 100%;
  height: 100vh;
  z-index: -1;
  background-position: center;
  background-size: cover;
  background-color: #00bffd;
  opacity: ${props => props.opacity};
  animation-timing-function: linear;
  ${media.tablet`
    & * {
      display: none;
    }
  `}
`;
const Cloud = styled.div`
  animation: ${transition} 2s linear infinite;
  position: absolute;
  width: 100%;
  height: 100vh;
  background-repeat: no-repeat;
`
const CloudRow1 = styled(Cloud)`
  background: url(${FirstCloudSVG}) repeat-x;
  background-position-y: 90%;
  background-size: 66.6%;
  animation-duration: ${row1Duration};
`
const CloudRow2 = styled(Cloud)`
  background: url(${SecondCloudSVG}) repeat-x;
  background-position-y: 45%;
  background-size: 40%;
  animation-duration: ${row2Duration};
`
const CloudRow3 = styled(Cloud)`
  background: url(${ThirdCloudSVG}) repeat-x;
  background-position-y: 20%;
  background-size: 28.5%;
  animation-duration: ${row3Duration};
`
const CloudRow4 = styled(Cloud)`
  background: url(${ForthCloudSVG}) repeat-x;
  background-position-y: 5%;
  background-size: 20%;
  animation-duration: ${row4Duration};
`

const CloudAnimation = ({ opacity, ...props }) => (
  <Wrapper opacity={opacity}>
    <CloudRow1/>
    <CloudRow2/>
    <CloudRow3/>
    <CloudRow4/>
  </Wrapper>
)

export default CloudAnimation;
<|endoftext|>


<commit_before>'use strict';
var config = require('./saucelabs.config');
var assert = require('assert');
var test = require('selenium-webdriver/testing');
var webdriver = require('selenium-webdriver');

var isSauceLabsTest = false;
var sauceLabsCaps = config.saucelabs.browserCaps;

var SAUCE_URL = 'http://ondemand.saucelabs.com:80/wd/hub';
var DBC_URLS = ['http://uxwin7-01:4444/wd/hub', 'http://uxwin81-01:4444/wd/hub', 'http://uxwin10-01:5432/wd/hub'];
var BASE_URL = isSauceLabsTest ? 'https://pg.demo.dbc.dk' : process.env.SELENIUM_URL || 'http://localhost:8080'; // eslint-disable-line

function runAllTests(driverCaps) {
  test.describe('Express endpoint', function () {
    test.it('/profile/login can be reached', function () {
      var endpoint = '/profile/login';
      var driver = driverCaps.build();
      driver.get(BASE_URL + endpoint);
      driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'body'})), 12000);
      var body = driver.findElement({tagName: 'body'});
      var header = body.findElement({id: 'header'});

      header.getId()
        .then(function (id) {
          assert.notEqual(typeof id, 'undefined');
        });

      driver.quit();
    });

    test.it('/profile/signup can be reached', function () {
      var endpoint = '/profile/signup';
      var driver = driverCaps.build();
      driver.get(BASE_URL + endpoint);
      driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'body'})), 12000);
      var body = driver.findElement({tagName: 'body'});
      var header = body.findElement({id: 'header'});

      header.getId()
        .then(function (id) {
          assert.notEqual(typeof id, 'undefined');
        });

      driver.quit();
    });
  });

  test.describe('Login page', function () {
    test.it('is rendered', function () {
      var endpoint = '/profile/login';
      var driver = driverCaps.build();
      driver.get(BASE_URL + endpoint);
      driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'input', name: 'username'})), 5000);
      var emailInput = driver.findElement({tagName: 'input', name: 'username'});
      emailInput.sendKeys('rasmussen.matias@gmail.com');
      driver.quit();
    });
  });

  test.describe('Signup page', function () {
    test.it('is rendered', function () {
      var endpoint = '/profile/signup';
      var driver = driverCaps.build();
      driver.get(BASE_URL + endpoint);
      driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'input', name: 'username'})), 5000);
      driver.quit();
    });
  });

  test.describe('Library Suggest - Autocomplete', function () {
    test.it('returns suggestions', function () {
      var driver = driverCaps.build();

      driver.get(BASE_URL + '/library/suggest');

      driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'input'})), 5000);

      var searchField = driver.findElement({tagName: 'input'});

      searchField.sendKeys('køb');

      driver.wait(webdriver.until.elementLocated(webdriver.By.className('autocomplete--row-text')), 5000);

      var acRow = driver.findElement(webdriver.By.className('autocomplete--row-text'));

      acRow.getInnerHtml().then(function(html) {
        assert.notEqual(typeof html, 'undefined');
      });

      acRow.click();

      driver.quit();
    });
  });

  test.describe('Library', function () {
    test.it('SSR rendering of library', function () {
      var driver = driverCaps.build();
      var libraryId = '710100';
      var branchName = 'Hovedbiblioteket, Krystalgade';

      // ssrTimeout url param sets how many milliseconds to wait for data
      // Test times out before the ssrTimeout to ensure whats sent is rendered server side
      // If this test functions it SSR must work
      driver.get(BASE_URL + '/library?id=' + libraryId + '&ssrTimeout=900000');
      driver.wait(webdriver.until.elementLocated(webdriver.By.className('library--branch-name')), 5000);

      var libraryTitle = driver.findElement(webdriver.By.className('library--branch-name'));
      libraryTitle.getInnerHtml().then(function (html) {
        assert.equal(html, branchName);
      });

      driver.quit();
    });
  });
}

if (isSauceLabsTest) {
  for (var k in sauceLabsCaps) {
    if (sauceLabsCaps.hasOwnProperty(k)) {
      var caps = sauceLabsCaps[k];
      caps.username = config.saucelabs.username;
      caps.accessKey = config.saucelabs.accessKey;
      var sauceDriverCaps = new webdriver.Builder().
        usingServer(SAUCE_URL).
        withCapabilities(caps);

      runAllTests(sauceDriverCaps);
    }
  }
}
else if (process.env.JENKINS_TESTING || false) { // eslint-disable-line
  var driver = new webdriver.Builder()
    .forBrowser(process.env.SELENIUM_BROWSER_NAME || 'internet explorer') // eslint-disable-line
    .usingServer(process.env.SELENIUM_TEST_SERVER || DBC_URLS[1]); // eslint-disable-line

  runAllTests(driver);
}
else {
  var chromeCaps = new webdriver.Builder()
    .withCapabilities(webdriver.Capabilities.chrome());

  runAllTests(chromeCaps);
}
<commit_msg>us145: timeout<commit_after>'use strict';
var config = require('./saucelabs.config');
var assert = require('assert');
var test = require('selenium-webdriver/testing');
var webdriver = require('selenium-webdriver');

var isSauceLabsTest = false;
var sauceLabsCaps = config.saucelabs.browserCaps;

var SAUCE_URL = 'http://ondemand.saucelabs.com:80/wd/hub';
var DBC_URLS = ['http://uxwin7-01:4444/wd/hub', 'http://uxwin81-01:4444/wd/hub', 'http://uxwin10-01:5432/wd/hub'];
var BASE_URL = isSauceLabsTest ? 'https://pg.demo.dbc.dk' : process.env.SELENIUM_URL || 'http://localhost:8080'; // eslint-disable-line
var driverTimeout = process.env.DRIVER_TIMEOUT || 10000; // eslint-disable-line no-process-env

function runAllTests(driverCaps) {
  test.describe('Express endpoint', function () {
    test.it('/profile/login can be reached', function () {
      var endpoint = '/profile/login';
      var driver = driverCaps.build();
      driver.get(BASE_URL + endpoint);
      driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'body'})), driverTimeout);
      var body = driver.findElement({tagName: 'body'});
      var header = body.findElement({id: 'header'});

      header.getId()
        .then(function (id) {
          assert.notEqual(typeof id, 'undefined');
        });

      driver.quit();
    });

    test.it('/profile/signup can be reached', function () {
      var endpoint = '/profile/signup';
      var driver = driverCaps.build();
      driver.get(BASE_URL + endpoint);
      driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'body'})), driverTimeout);
      var body = driver.findElement({tagName: 'body'});
      var header = body.findElement({id: 'header'});

      header.getId()
        .then(function (id) {
          assert.notEqual(typeof id, 'undefined');
        });

      driver.quit();
    });
  });

  test.describe('Login page', function () {
    test.it('is rendered', function () {
      var endpoint = '/profile/login';
      var driver = driverCaps.build();
      driver.get(BASE_URL + endpoint);
      driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'input', name: 'username'})), driverTimeout);
      var emailInput = driver.findElement({tagName: 'input', name: 'username'});
      emailInput.sendKeys('rasmussen.matias@gmail.com');
      driver.quit();
    });
  });

  test.describe('Signup page', function () {
    test.it('is rendered', function () {
      var endpoint = '/profile/signup';
      var driver = driverCaps.build();
      driver.get(BASE_URL + endpoint);
      driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'input', name: 'username'})), driverTimeout);
      driver.quit();
    });
  });

  test.describe('Library Suggest - Autocomplete', function () {
    test.it('returns suggestions', function () {
      var driver = driverCaps.build();

      driver.get(BASE_URL + '/library/suggest');

      driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'input'})), driverTimeout);

      var searchField = driver.findElement({tagName: 'input'});

      searchField.sendKeys('køb');

      driver.wait(webdriver.until.elementLocated(webdriver.By.className('autocomplete--row-text')), driverTimeout);

      var acRow = driver.findElement(webdriver.By.className('autocomplete--row-text'));

      acRow.getInnerHtml().then(function(html) {
        assert.notEqual(typeof html, 'undefined');
      });

      acRow.click();

      driver.quit();
    });
  });

  test.describe('Library', function () {
    test.it('SSR rendering of library', function () {
      var driver = driverCaps.build();
      var libraryId = '710100';
      var branchName = 'Hovedbiblioteket, Krystalgade';

      // ssrTimeout url param sets how many milliseconds to wait for data
      // Test times out before the ssrTimeout to ensure whats sent is rendered server side
      // If this test functions it SSR must work
      driver.get(BASE_URL + '/library?id=' + libraryId + '&ssrTimeout=900000');
      driver.wait(webdriver.until.elementLocated(webdriver.By.className('library--branch-name')), driverTimeout);

      var libraryTitle = driver.findElement(webdriver.By.className('library--branch-name'));
      libraryTitle.getInnerHtml().then(function (html) {
        assert.equal(html, branchName);
      });

      driver.quit();
    });
  });
}

if (isSauceLabsTest) {
  for (var k in sauceLabsCaps) {
    if (sauceLabsCaps.hasOwnProperty(k)) {
      var caps = sauceLabsCaps[k];
      caps.username = config.saucelabs.username;
      caps.accessKey = config.saucelabs.accessKey;
      var sauceDriverCaps = new webdriver.Builder().
        usingServer(SAUCE_URL).
        withCapabilities(caps);

      runAllTests(sauceDriverCaps);
    }
  }
}
else if (process.env.JENKINS_TESTING || false) { // eslint-disable-line
  var driver = new webdriver.Builder()
    .forBrowser(process.env.SELENIUM_BROWSER_NAME || 'internet explorer') // eslint-disable-line
    .usingServer(process.env.SELENIUM_TEST_SERVER || DBC_URLS[1]); // eslint-disable-line

  runAllTests(driver);
}
else {
  var chromeCaps = new webdriver.Builder()
    .withCapabilities(webdriver.Capabilities.chrome());

  runAllTests(chromeCaps);
}
<|endoftext|>


<commit_before>// taxbrain.js

//
//  Input page
//

// sidebar - scrollspy
$('body').scrollspy({
  target: '.inputs-sidebar'
});

// Scroll to taxbrain form input areas, instead of jumping
$('.inputs-form a, .btn-explore').click(function(event) {
  if ($(this).attr('id') === 'current-year-link') {
    return;
  }
  // ensure link is indeed a hash link on current page <<-- Zach's stuff
  if (this.host == location.host && this.pathname == location.pathname) {
    event.preventDefault();
    var target = this.hash;
    if (this.href != '#') {
      $('body, html').animate({
        scrollTop: $(target).offset().top
      }, 700);
    }
  }

});

// CPI buttons
$('.form-group > label.btn-cpi').click(function (e) {
  label = $(this)
  field = label.attr('for')
  prev_value = label.hasClass('active')

  // add button-toggle functionality without hijacking click
  prev_value ? label.removeClass('active') : label.addClass('active');
  value = !prev_value

  // find the default value
  select = label.siblings('.form-control');
  placeholder = select.attr('placeholder')
  placeholder_true = placeholder == 'True'
  placeholder_false = placeholder == 'False'
  has_boolean_default = placeholder_true || placeholder_false

  // default-based logic
  if (has_boolean_default) {
    default_value = placeholder_true;
    is_default = (value == default_value);
    console.log(
    'setting CPI field ' + field  +
    ' from value ' + prev_value +
    ' to value ' + value +
    ' with default ' + default_value +
    ' is default ' + is_default )

    // only allow values to be entered if not equal to default
    // if new values entered, show info about default value
    group = label.closest('.form-group')
    if (!is_default) {
      if (value) {select.val('2');} else {select.val('3');}
      group.addClass('edited');

    } else {
      select.val('1'); // set to "Unknown"
      group.removeClass('edited');
    }

  } else {
    // we don't recognize the placeholder value
    console.log('setting CPI field with no default ' + field  +
      ' to value ' + value )

    // pass changes directly to the select
    if (value) {select.val('2');} else {select.val('3');}
  }
});

$("#tax-submit[type='reset']").click(function(){
  $('.form-group.edited').each(function(){
    $(this).removeClass("edited")
  })
});

//
//  Results page
//

// Select behavior for dropdowns
$(".dropdown-select .dropdown-menu li a").click(function(){
  selection = $(this);
  dropdown_label = $(this).parents('.dropdown-select').find('.dropdown-toggle')
  dropdown_label.html(selection.text() + ' ');
});

// Switch behavior for dropdowns
$(".data-switch .dropdown-menu li a").click(function(){
  switch_key = $(this).text().trim();

  /*
  //Without fade-out-in
  $( ".data-switchable" ).each(function(){
    $this = $(this)
    switch_value = $this.data("switch-options")[switch_key]
    $this.text(switch_value)
  })
  */

  // With fade-out-in
  $('.data-switchable').fadeOut('fast',function(){
    $this = $(this)
    switch_value = $this.data("switch-options")[switch_key]
    $this.text(switch_value).fadeIn('fast');
  });

});

$('input[name="growth_choice"]').click(function () {
  if ($(this).val() === 'factor_target') {
    $('#id_factor_adjustment').val('');
  } else {
    $('#id_factor_target').val('');
  }
});

$('#id_factor_adjustment, #id_factor_target').focus(function() {
  if ($(this).attr('id') === 'id_factor_target') {
    $('input[type="radio"][value="factor_target"]').click();
  } else {
    $('input[type="radio"][value="factor_adjustment"]').click();
  }
});

var currentYear = $('#start-year-select').val();
$('#start-year-select').change(function(e) {
  $('#current-year-link').attr('href', '/taxbrain/?start_year=' + $(this).val());
  $('#current-year-modal').modal('show');
});

$('#current-year-modal').on('hide.bs.modal', function (e) {
  $('#start-year-select option').removeAttr("selected");
  $('#start-year-select option[value="' + currentYear + '"]').attr("selected", "selected");
});
<commit_msg>track JS changes<commit_after>// taxbrain.js

//
//  Input page
//

// sidebar - scrollspy
$('body').scrollspy({
  target: '.inputs-sidebar'
});

// Scroll to taxbrain form input areas, instead of jumping
$('.inputs-form a, .btn-explore').click(function(event) {
  if ($(this).attr('id') === 'current-year-link') {
    return;
  }
  // ensure link is indeed a hash link on current page <<-- Zach's stuff
  if (this.host == location.host && this.pathname == location.pathname) {
    event.preventDefault();
    var target = this.hash;
    if (this.href != '#') {
      $('body, html').animate({
        scrollTop: $(target).offset().top
      }, 700);
    }
  }

});

// CPI buttons
$('.form-group > label.btn-cpi').click(function (e) {
  label = $(this)
  field = label.attr('for')
  prev_value = label.hasClass('active')

  // add button-toggle functionality without hijacking click
  prev_value ? label.removeClass('active') : label.addClass('active');
  value = !prev_value

  // find the default value
  select = label.siblings('.form-control');
  placeholder = select.attr('placeholder')
  placeholder_true = placeholder == 'True'
  placeholder_false = placeholder == 'False'
  has_boolean_default = placeholder_true || placeholder_false

  // default-based logic
  if (has_boolean_default) {
    default_value = placeholder_true;
    is_default = (value == default_value);
    console.log(
    'setting CPI field ' + field  +
    ' from value ' + prev_value +
    ' to value ' + value +
    ' with default ' + default_value +
    ' is default ' + is_default )

    // only allow values to be entered if not equal to default
    // if new values entered, show info about default value
    group = label.closest('.form-group')
    if (!is_default) {
      if (value) {select.val('2');} else {select.val('3');}
      group.addClass('edited');

    } else {
      select.val('1'); // set to "Unknown"
      group.removeClass('edited');
    }

  } else {
    // we don't recognize the placeholder value
    console.log('setting CPI field with no default ' + field  +
      ' to value ' + value )

    // pass changes directly to the select
    if (value) {select.val('2');} else {select.val('3');}
  }
});

$("#tax-submit[type='reset']").click(function(){
  $('.form-group.edited').each(function(){
    $(this).removeClass("edited")
  })
});

//
//  Results page
//

// Select behavior for dropdowns
$(".dropdown-select .dropdown-menu li a").click(function(){
  selection = $(this);
  dropdown_label = $(this).parents('.dropdown-select').find('.dropdown-toggle')
  dropdown_label.html(selection.text() + ' ');
});

// Switch behavior for dropdowns
$(".data-switch .dropdown-menu li a").click(function(){
  switch_key = $(this).text().trim();

  /*
  //Without fade-out-in
  $( ".data-switchable" ).each(function(){
    $this = $(this)
    switch_value = $this.data("switch-options")[switch_key]
    $this.text(switch_value)
  })
  */

  // With fade-out-in
  $('.data-switchable').fadeOut('fast',function(){
    $this = $(this)
    switch_value = $this.data("switch-options")[switch_key]
    $this.text(switch_value).fadeIn('fast');
  });

});

$('input[name="growth_choice"]').click(function () {
  if ($(this).val() === 'factor_target') {
    $('#id_factor_adjustment').val('');
  } else {
    $('#id_factor_target').val('');
  }
});

$('#id_factor_adjustment, #id_factor_target').focus(function() {
  if ($(this).attr('id') === 'id_factor_target') {
    $('input[type="radio"][value="factor_target"]').click();
  } else {
    $('input[type="radio"][value="factor_adjustment"]').click();
  }
});

var currentYear = $('#start-year-select').val();
$('#start-year-select').change(function(e) {
  $('#current-year-link').attr('href', '/taxbrain/?start_year=' + $(this).val());
  $('#current-year-modal').modal('show');
});

$('#current-year-modal').on('hide.bs.modal', function (e) {
  $('#start-year-select option').removeAttr("selected");
  $('#start-year-select option[value="' + currentYear + '"]').attr("selected", "selected");
});

var Data = $('#cps-or-puf').val();
$('#cps-or-puf').change(function(e) {
    $('#cps-or-puf option').removeAttr("selected");
    $('#cps-or-puf option[value="' + Data + '"]').attr("selected", "selected");
});
<|endoftext|>


<commit_before>/**
 * Wheel, copyright (c) 2019 - present by Arno van der Vegt
 * Distributed under an MIT license: https://arnovandervegt.github.io/wheel/license.txt
**/
const sensorModuleConstants = require('../vm/modules/sensorModuleConstants');
const constants             = require('./constants');
const StandardModule        = require('./modules/StandardModule' ).StandardModule;
const ScreenModule          = require('./modules/ScreenModule'   ).ScreenModule;
const MotorModule           = require('./modules/MotorModule'    ).MotorModule;
const SensorModule          = require('./modules/SensorModule'   ).SensorModule;
const MathModule            = require('./modules/MathModule'     ).MathModule;
const LightModule           = require('./modules/LightModule'    ).LightModule;
const ButtonModule          = require('./modules/ButtonModule'   ).ButtonModule;
const SoundModule           = require('./modules/SoundModule'    ).SoundModule;
const SystemModule          = require('./modules/SystemModule'   ).SystemModule;
const FileModule            = require('./modules/FileModule'     ).FileModule;
const BitModule             = require('./modules/BitModule'      ).BitModule;
const StringModule          = require('./modules/StringModule'   ).StringModule;
const DeviceModule          = require('./modules/DeviceModule'   ).DeviceModule;
const PoweredUpModule       = require('./modules/PoweredUpModule').PoweredUpModule;
const PoweredUP             = require('node-poweredup');

const portToIndex = {A: 0, B: 1, C: 2, D: 3};

exports.PoweredUp = class {
    constructor(opts) {
        this._layerCount    = 0;
        this._modules       = [];
        this._scanning      = false;
        this._connectedHubs = [];
        this._hubs          = [];
        this._hubsByUuid    = {};
        this._changed       = 0;
        this._layers        = [this.initLayer(), this.initLayer(), this.initLayer(), this.initLayer()];
        this._poweredUP     = new PoweredUP.PoweredUP();
        this._poweredUP.on('discover', this._addHub.bind(this));
        this.initModules();
    }

    initLayer() {
        return {
            connected:       false,
            buttonLeft:      0,
            buttonRight:     0,
            button:          0,
            hubLed:          null,
            hubButtons:      [],
            tilt:            {x: 0, y: 0, z: 0},
            accel:           {x: 0, y: 0, z: 0},
            ports:           [0, 0, 0, 0],
            portAssignments: [0, 0, 0, 0],
            portDevices:     [null, null, null, null]
        };
    }

    initModules() {
        let modules = this._modules;
        modules[ 0] = new StandardModule ({device: this});
        modules[ 1] = new MathModule     ({device: this});
        modules[ 2] = new ScreenModule   ({device: this});
        modules[ 3] = new LightModule    ({device: this});
        modules[ 4] = new ButtonModule   ({device: this});
        modules[ 5] = new SoundModule    ({device: this});
        modules[ 6] = new MotorModule    ({device: this});
        modules[ 7] = new SensorModule   ({device: this});
        modules[ 8] = new FileModule     ({device: this});
        modules[ 9] = new SystemModule   ({device: this});
        modules[10] = new StringModule   ({device: this});
        modules[11] = new BitModule      ({device: this});
        modules[12] = new DeviceModule   ({device: this});
        modules[13] = new PoweredUpModule({device: this});
    }

    _addHub(hub) {
        let uuid = hub.uuid;
        if (uuid in this._hubsByUuid) {
            return;
        }
        this._hubsByUuid[uuid] = {
            index:      this._hubs.length,
            layer:      null,
            uuid:       uuid,
            type:       hub.type,
            title:      hub.name,
            subTitle:   uuid,
            connecting: false,
            connected:  false
        };
        this._hubs.push(hub);
        this._changed++;
    }

    _attachEvents(index, h, hub) {
        let layer   = this._layers[index];
        let devices = h.getDevices();
        layer.connected = true;
        devices.forEach(this.onAttachDevice.bind(this, layer));
        h.on('disconnect', this.onDisconnect.bind(this, hub));
        h.on('tilt',       this.onTilt.bind(this, layer));
        h.on('accel',      this.onAccel.bind(this, layer));
        h.on('button',     this.onButton.bind(this, layer));
        h.on('rotate',     this.onRotate.bind(this, layer));
        h.on('attach',     this.onAttachDevice.bind(this, layer));
        h.on('detach',     this.onDetachDevice.bind(this, layer));
    }

    onAttachDevice(layer, device) {
        if (device.portName in portToIndex) {
            let port = portToIndex[device.portName];
            layer.portAssignments[port] = device.type;
            layer.portDevices[port]     = device;
            switch (device.type) {
                case 37: // Color and distance
                    device.on('colorAndDistance', this.onColorAndDistance.bind(this, layer, port));
                    break;
            }
        } else {
            switch (device.type) {
                case 23: // Led...
                    layer.hubLed = device;
                    break;
                case 55: // Remote control buttons...
                    let index = layer.hubButtons.length;
                    layer.hubButtons.push(device);
                    device.on('remoteButton', this.onRemoteButton.bind(this, index, layer));
                    break;
            }
        }
    }

    onDetachDevice(layer, device) {
        if (device.portName in portToIndex) {
            let port = portToIndex[device.portName];
            layer.portAssignments[port] = 0;
            layer.portDevices[port]     = null;
        }
    }

    onDisconnect(hub) {
        hub.connected = false;
    }

    onColorAndDistance(layer, port, event) {
        layer.ports[port] = event.distance; // Distance or color depending on mode!
    }

    onRotate(layer, device) {
        if (device.portName in portToIndex) {
            layer.ports[portToIndex[device.portName]] = device.values.rotate.degrees;
        }
    }

    onButton(layer, event) {
        layer.button = event.event ? 0 : 1;
    }

    onTilt(layer, event) {
        let tilt = event.values.tilt;
        layer.tilt.x = tilt.x;
        layer.tilt.y = tilt.y;
        layer.tilt.z = tilt.z;
    }

    onAccel(layer, event) {
        let accel = event.values.accel;
        layer.accel.x = accel.x;
        layer.accel.y = accel.y;
        layer.accel.z = accel.z;
    }

    onRemoteButton(index, layer, event) {
        let value = 0;
        switch (event.event) {
            case 255: // "-"
                value = 1;
                break;
            case 127: // Red
                value = 2;
                break;
            case 1:  // "+"
                value = 4;
                break;
        }
        switch (index) {
            case 0:
                layer.buttonLeft = value;
                break;
            case 1:
                layer.buttonRight = value;
                break;
        }
        layer.button = (layer.buttonLeft << 3) + layer.buttonRight;
    }

    _connectHub(h, hub) {
        h.connect(); // Connect to the Hub
    }

    _updateConnectedHubs() {
        let connectedHubs     = this._connectedHubs;
        let connectedHubUuids = {};
        let hubsByUuid        = this._hubsByUuid;
        connectedHubs.forEach(function(connectedHub) {
            connectedHubUuids[connectedHub.uuid] = true;
        });
        this._hubs.forEach(
            function(hub) {
                if (hub.uuid in connectedHubUuids) {
                    return;
                }
                if (hubsByUuid[hub.uuid].connected) {
                    this._attachEvents(connectedHubs.length, hub, hubsByUuid[hub.uuid]);
                    connectedHubs.push(hub);
                }
            },
            this
        );
    }

    getChanged() {
        return this._changed;
    }

    getDeviceList() {
        if (!this._scanning) {
            this._scanning      = true;
            this._connectedHubs = [];
            this._hubs          = [];
            this._hubsByUuid    = {};
            this._poweredUP.scan();
        }
        let list = [];
        this._hubs.forEach(
            function(hub) {
                list.push(this._hubsByUuid[hub.uuid]);
            },
            this
        );
        return list;
    }

    getDevice(layer, port) {
        const device = this._layers[layer].portDevices[port];
        if (!device || !device.connected) {
            return null;
        }
        return device;
    }

    getPort() {
        return this._port;
    }

    getConnected() {
        return this._connected;
    }

    getLayerCount() {
        return this._layerCount;
    }

    setLayerCount(layerCount) {
        this._layerCount = layerCount;
    }

    getMotorPosition(layer, port) {
        return this._port[port] || 0;
    }

    connect(uuid, callback) {
        if (uuid in this._hubsByUuid) {
            let hub = this._hubsByUuid[uuid];
            if (!hub.connected && !hub.connecting) {
                hub.connecting  = true;
                hub.connectTime = Date.now();
                this._connectHub(this._hubs[hub.index], hub);
            }
            callback(hub);
        } else {
            callback(null);
        }
    }

    disconnect() {
    }

    playtone(frequency, duration, volume, callback) {
    }

    getHHubByLayer(layer) {
        let h = this._connectedHubs[layer];
        if (!h) {
            return null;
        }
        let hub = this._hubsByUuid[h.uuid];
        if (!hub || !hub.connected) {
            return null;
        }
        return {h: h, hub: hub};
    }

    getHubConnected(layer) {
        let hHub = this.getHHubByLayer(layer);
        if (!hHub) {
            return false;
        }
        return hHub.hub.connected;
    }

    getConnectedTypes(layer) {
    }

    getDefaultModeForType(type) {
        return constants.MODE0;
    }

    motorReset(layer, motor) {
        let hHub = this.getHHubByLayer(layer);
        if (!hHub) {
            return;
        }
    }

    motorDegrees(layer, motor, speed, degrees, callback) {
        if (!this.getHubConnected(layer)) {
            return;
        }
        const motorDevice = this.getDevice(layer, motor);
        if (!motorDevice) {
            return;
        }
        if (motorDevice.rotateByDegrees) {
            if (degrees < 0) {
                degrees *= -1;
                speed   *= -1;
            }
            motorDevice.rotateByDegrees(degrees, speed);
        }
        callback && callback();
    }

    motorOn(layer, motor, speed, callback) {
        if (!this.getHubConnected(layer)) {
            return;
        }
        const motorDevice = this.getDevice(layer, motor);
        if (!motorDevice) {
            return;
        }
        if (motorDevice.setPower) {
            motorDevice.setPower(speed);
        }
        if (motorDevice.setBrightness) {
            motorDevice.setBrightness(speed);
        }
        callback && callback();
    }

    motorStop(layer, motor, brake, callback) {
        if (!this.getHubConnected(layer)) {
            return;
        }
        const motorDevice = this.getDevice(layer, motor);
        if (!motorDevice) {
            return;
        }
        if (motorDevice.stop) {
            motorDevice.stop();
        }
        if (motorDevice.setBrightness) {
            motorDevice.setBrightness(0);
        }
        callback && callback();
    }

    readTouchSensor(layer, port) {
    }

    readSensor(layer, port, type, mode) {
    }

    readMotor(layer, port) {
    }

    readBattery(callback) {
    }

    setLed(layer, color) {
        if (!this._hubs[layer]) {
            return;
        }
        let hub = this._hubs[layer];
        let h   = this._hubsByUuid[hub.uuid];
        if (h.connected && ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 255].indexOf(color) !== -1)) {
            if (hub.setLEDColor) {
                hub.setLEDColor(color);
            } else {
                let hubLed = this._layers[layer].hubLed;
                if (hubLed && hubLed.setColor) {
                    hubLed.setColor(color);
                }
            }
        }
    }

    listFiles(path, callback) {
    }

    downloadFile(filename, data, callback) {
    }

    createDir(path, callback) {
    }

    deleteFile(path, callback) {
    }

    module(module, command, data) {
        if (this._modules[module]) {
            this._modules[module].run(command, data);
        }
    }

    getStatus() {
        let time   = Date.now();
        let layers = this._layers;
        this._hubs.forEach(
            function(h) {
                let hub = this._hubsByUuid[h.uuid];
                if (hub.connecting && (time > hub.connectTime + 3000)) {
                    hub.connecting = false;
                    hub.connected  = true;
                    this._updateConnectedHubs();
                }
            },
            this
        );
        this._connectedHubs.forEach(
            function(h, index) {
                let hub = this._hubsByUuid[h.uuid];
                layers[index].uuid         = h.uuid;
                layers[index].type         = h.type;
                layers[index].batteryLevel = h.batteryLevel;
                layers[index].connected    = true;
            },
            this
        );
        const copyLayer = function(layer) {
                    let result = Object.assign({}, layer);
                    delete result.portDevices;
                    delete result.hubLed;
                    delete result.hubButtons;
                    return result;
                };
        return {
            layer0: copyLayer(layers[0]),
            layer1: copyLayer(layers[1]),
            layer2: copyLayer(layers[2]),
            layer3: copyLayer(layers[3])
        };
    }

    setMode(layer, port, mode) {
    }

    stopPolling() {
        this._stopPolling = true;
    }

    resumePolling() {
        this._stopPolling = false;
    }
};
<commit_msg>Fixed Powered Up motor position reset.<commit_after>/**
 * Wheel, copyright (c) 2019 - present by Arno van der Vegt
 * Distributed under an MIT license: https://arnovandervegt.github.io/wheel/license.txt
**/
const sensorModuleConstants = require('../vm/modules/sensorModuleConstants');
const constants             = require('./constants');
const StandardModule        = require('./modules/StandardModule' ).StandardModule;
const ScreenModule          = require('./modules/ScreenModule'   ).ScreenModule;
const MotorModule           = require('./modules/MotorModule'    ).MotorModule;
const SensorModule          = require('./modules/SensorModule'   ).SensorModule;
const MathModule            = require('./modules/MathModule'     ).MathModule;
const LightModule           = require('./modules/LightModule'    ).LightModule;
const ButtonModule          = require('./modules/ButtonModule'   ).ButtonModule;
const SoundModule           = require('./modules/SoundModule'    ).SoundModule;
const SystemModule          = require('./modules/SystemModule'   ).SystemModule;
const FileModule            = require('./modules/FileModule'     ).FileModule;
const BitModule             = require('./modules/BitModule'      ).BitModule;
const StringModule          = require('./modules/StringModule'   ).StringModule;
const DeviceModule          = require('./modules/DeviceModule'   ).DeviceModule;
const PoweredUpModule       = require('./modules/PoweredUpModule').PoweredUpModule;
const PoweredUP             = require('node-poweredup');

const portToIndex = {A: 0, B: 1, C: 2, D: 3};

exports.PoweredUp = class {
    constructor(opts) {
        this._layerCount    = 0;
        this._modules       = [];
        this._scanning      = false;
        this._connectedHubs = [];
        this._hubs          = [];
        this._hubsByUuid    = {};
        this._changed       = 0;
        this._layers        = [this.initLayer(), this.initLayer(), this.initLayer(), this.initLayer()];
        this._poweredUP     = new PoweredUP.PoweredUP();
        this._poweredUP.on('discover', this._addHub.bind(this));
        this.initModules();
    }

    initLayer() {
        return {
            connected:       false,
            buttonLeft:      0,
            buttonRight:     0,
            button:          0,
            hubLed:          null,
            hubButtons:      [],
            tilt:            {x: 0, y: 0, z: 0},
            accel:           {x: 0, y: 0, z: 0},
            ports:           [0, 0, 0, 0],
            resetValues:     [0, 0, 0, 0],
            portAssignments: [0, 0, 0, 0],
            portDevices:     [null, null, null, null]
        };
    }

    initModules() {
        let modules = this._modules;
        modules[ 0] = new StandardModule ({device: this});
        modules[ 1] = new MathModule     ({device: this});
        modules[ 2] = new ScreenModule   ({device: this});
        modules[ 3] = new LightModule    ({device: this});
        modules[ 4] = new ButtonModule   ({device: this});
        modules[ 5] = new SoundModule    ({device: this});
        modules[ 6] = new MotorModule    ({device: this});
        modules[ 7] = new SensorModule   ({device: this});
        modules[ 8] = new FileModule     ({device: this});
        modules[ 9] = new SystemModule   ({device: this});
        modules[10] = new StringModule   ({device: this});
        modules[11] = new BitModule      ({device: this});
        modules[12] = new DeviceModule   ({device: this});
        modules[13] = new PoweredUpModule({device: this});
    }

    _addHub(hub) {
        let uuid = hub.uuid;
        if (uuid in this._hubsByUuid) {
            return;
        }
        this._hubsByUuid[uuid] = {
            index:      this._hubs.length,
            layer:      null,
            uuid:       uuid,
            type:       hub.type,
            title:      hub.name,
            subTitle:   uuid,
            connecting: false,
            connected:  false
        };
        this._hubs.push(hub);
        this._changed++;
    }

    _attachEvents(index, h, hub) {
        let layer   = this._layers[index];
        let devices = h.getDevices();
        layer.connected = true;
        devices.forEach(this.onAttachDevice.bind(this, layer));
        h.on('disconnect', this.onDisconnect.bind(this, hub));
        h.on('tilt',       this.onTilt.bind(this, layer));
        h.on('accel',      this.onAccel.bind(this, layer));
        h.on('button',     this.onButton.bind(this, layer));
        h.on('rotate',     this.onRotate.bind(this, layer));
        h.on('attach',     this.onAttachDevice.bind(this, layer));
        h.on('detach',     this.onDetachDevice.bind(this, layer));
    }

    onAttachDevice(layer, device) {
        if (device.portName in portToIndex) {
            let port = portToIndex[device.portName];
            layer.portAssignments[port] = device.type;
            layer.portDevices[port]     = device;
            switch (device.type) {
                case 37: // Color and distance
                    device.on('colorAndDistance', this.onColorAndDistance.bind(this, layer, port));
                    break;
            }
        } else {
            switch (device.type) {
                case 23: // Led...
                    layer.hubLed = device;
                    break;
                case 55: // Remote control buttons...
                    let index = layer.hubButtons.length;
                    layer.hubButtons.push(device);
                    device.on('remoteButton', this.onRemoteButton.bind(this, index, layer));
                    break;
            }
        }
    }

    onDetachDevice(layer, device) {
        if (device.portName in portToIndex) {
            let port = portToIndex[device.portName];
            layer.portAssignments[port] = 0;
            layer.portDevices[port]     = null;
        }
    }

    onDisconnect(hub) {
        hub.connected = false;
    }

    onColorAndDistance(layer, port, event) {
        layer.ports[port] = event.distance; // Distance or color depending on mode!
    }

    onRotate(layer, device) {
        if (device.portName in portToIndex) {
            let port = portToIndex[device.portName];
            layer.ports[port] = device.values.rotate.degrees - layer.resetValues[port];
        }
    }

    onButton(layer, event) {
        layer.button = event.event ? 0 : 1;
    }

    onTilt(layer, event) {
        let tilt = event.values.tilt;
        layer.tilt.x = tilt.x;
        layer.tilt.y = tilt.y;
        layer.tilt.z = tilt.z;
    }

    onAccel(layer, event) {
        let accel = event.values.accel;
        layer.accel.x = accel.x;
        layer.accel.y = accel.y;
        layer.accel.z = accel.z;
    }

    onRemoteButton(index, layer, event) {
        let value = 0;
        switch (event.event) {
            case 255: // "-"
                value = 1;
                break;
            case 127: // Red
                value = 2;
                break;
            case 1:  // "+"
                value = 4;
                break;
        }
        switch (index) {
            case 0:
                layer.buttonLeft = value;
                break;
            case 1:
                layer.buttonRight = value;
                break;
        }
        layer.button = (layer.buttonLeft << 3) + layer.buttonRight;
    }

    _connectHub(h, hub) {
        h.connect(); // Connect to the Hub
    }

    _updateConnectedHubs() {
        let connectedHubs     = this._connectedHubs;
        let connectedHubUuids = {};
        let hubsByUuid        = this._hubsByUuid;
        connectedHubs.forEach(function(connectedHub) {
            connectedHubUuids[connectedHub.uuid] = true;
        });
        this._hubs.forEach(
            function(hub) {
                if (hub.uuid in connectedHubUuids) {
                    return;
                }
                if (hubsByUuid[hub.uuid].connected) {
                    this._attachEvents(connectedHubs.length, hub, hubsByUuid[hub.uuid]);
                    connectedHubs.push(hub);
                }
            },
            this
        );
    }

    getChanged() {
        return this._changed;
    }

    getDeviceList() {
        if (!this._scanning) {
            this._scanning      = true;
            this._connectedHubs = [];
            this._hubs          = [];
            this._hubsByUuid    = {};
            this._poweredUP.scan();
        }
        let list = [];
        this._hubs.forEach(
            function(hub) {
                list.push(this._hubsByUuid[hub.uuid]);
            },
            this
        );
        return list;
    }

    getDevice(layer, port) {
        const device = this._layers[layer].portDevices[port];
        if (!device || !device.connected) {
            return null;
        }
        return device;
    }

    getPort() {
        return this._port;
    }

    getConnected() {
        return this._connected;
    }

    getLayerCount() {
        return this._layerCount;
    }

    setLayerCount(layerCount) {
        this._layerCount = layerCount;
    }

    getMotorPosition(layer, port) {
        return this._port[port] || 0;
    }

    connect(uuid, callback) {
        if (uuid in this._hubsByUuid) {
            let hub = this._hubsByUuid[uuid];
            if (!hub.connected && !hub.connecting) {
                hub.connecting  = true;
                hub.connectTime = Date.now();
                this._connectHub(this._hubs[hub.index], hub);
            }
            callback(hub);
        } else {
            callback(null);
        }
    }

    disconnect() {
    }

    playtone(frequency, duration, volume, callback) {
    }

    getHHubByLayer(layer) {
        let h = this._connectedHubs[layer];
        if (!h) {
            return null;
        }
        let hub = this._hubsByUuid[h.uuid];
        if (!hub || !hub.connected) {
            return null;
        }
        return {h: h, hub: hub};
    }

    getHubConnected(layer) {
        let hHub = this.getHHubByLayer(layer);
        if (!hHub) {
            return false;
        }
        return hHub.hub.connected;
    }

    getConnectedTypes(layer) {
    }

    getDefaultModeForType(type) {
        return constants.MODE0;
    }

    motorReset(layer, motor) {
        let hHub = this.getHHubByLayer(layer);
        if (!hHub) {
            return;
        }
        let layers = this._layers;
        if (!layers[layer] || !(motor in layers[layer].resetValues)) {
            return;
        }
        layer = layers[layer];
        layer.resetValues[motor] = layer.ports[motor];
        layer.ports[motor]       = 0;
    }

    motorDegrees(layer, motor, speed, degrees, callback) {
        if (!this.getHubConnected(layer)) {
            return;
        }
        const motorDevice = this.getDevice(layer, motor);
        if (!motorDevice) {
            return;
        }
        if (motorDevice.rotateByDegrees) {
            if (degrees < 0) {
                degrees *= -1;
                speed   *= -1;
            }
            motorDevice.rotateByDegrees(degrees, speed);
        }
        callback && callback();
    }

    motorOn(layer, motor, speed, callback) {
        if (!this.getHubConnected(layer)) {
            return;
        }
        const motorDevice = this.getDevice(layer, motor);
        if (!motorDevice) {
            return;
        }
        if (motorDevice.setPower) {
            motorDevice.setPower(speed);
        }
        if (motorDevice.setBrightness) {
            motorDevice.setBrightness(speed);
        }
        callback && callback();
    }

    motorStop(layer, motor, brake, callback) {
        if (!this.getHubConnected(layer)) {
            return;
        }
        const motorDevice = this.getDevice(layer, motor);
        if (!motorDevice) {
            return;
        }
        if (motorDevice.stop) {
            motorDevice.stop();
        }
        if (motorDevice.setBrightness) {
            motorDevice.setBrightness(0);
        }
        callback && callback();
    }

    readTouchSensor(layer, port) {
    }

    readSensor(layer, port, type, mode) {
    }

    readMotor(layer, port) {
    }

    readBattery(callback) {
    }

    setLed(layer, color) {
        if (!this._hubs[layer]) {
            return;
        }
        let hub = this._hubs[layer];
        let h   = this._hubsByUuid[hub.uuid];
        if (h.connected && ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 255].indexOf(color) !== -1)) {
            if (hub.setLEDColor) {
                hub.setLEDColor(color);
            } else {
                let hubLed = this._layers[layer].hubLed;
                if (hubLed && hubLed.setColor) {
                    hubLed.setColor(color);
                }
            }
        }
    }

    listFiles(path, callback) {
    }

    downloadFile(filename, data, callback) {
    }

    createDir(path, callback) {
    }

    deleteFile(path, callback) {
    }

    module(module, command, data) {
        if (this._modules[module]) {
            this._modules[module].run(command, data);
        }
    }

    getStatus() {
        let time   = Date.now();
        let layers = this._layers;
        this._hubs.forEach(
            function(h) {
                let hub = this._hubsByUuid[h.uuid];
                if (hub.connecting && (time > hub.connectTime + 3000)) {
                    hub.connecting = false;
                    hub.connected  = true;
                    this._updateConnectedHubs();
                }
            },
            this
        );
        this._connectedHubs.forEach(
            function(h, index) {
                let hub = this._hubsByUuid[h.uuid];
                layers[index].uuid         = h.uuid;
                layers[index].type         = h.type;
                layers[index].batteryLevel = h.batteryLevel;
                layers[index].connected    = true;
            },
            this
        );
        const copyLayer = function(layer) {
                    let result = Object.assign({}, layer);
                    delete result.portDevices;
                    delete result.hubLed;
                    delete result.hubButtons;
                    return result;
                };
        return {
            layer0: copyLayer(layers[0]),
            layer1: copyLayer(layers[1]),
            layer2: copyLayer(layers[2]),
            layer3: copyLayer(layers[3])
        };
    }

    setMode(layer, port, mode) {
    }

    stopPolling() {
        this._stopPolling = true;
    }

    resumePolling() {
        this._stopPolling = false;
    }
};
<|endoftext|>


<commit_before>'use strict';
var fs = require('fs');
var assert = require('assert');
var test = require('selenium-webdriver/testing');
var webdriver = require('selenium-webdriver');
var chrome = require('chromedriver');

var BASE_URL = process.env.SELENIUM_URL || 'http://localhost:8080';

function writeScreenshot(data, name) {
  name = name || 'ss.png';
  var screenshotPath = '';
  fs.writeFileSync(screenshotPath + name, data, 'base64');
}

test.describe('Title assertion', function () {
  test.it('Title is Palles Gavebod', function () {
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.phantomjs())
      .build();

    driver.get(BASE_URL);

    driver.getTitle().then(function (title) {
      assert.equal(title, 'Palles Gavebod', 'Title is Palles Gavebod');
    });

    driver.takeScreenshot().then(function(data) {
      writeScreenshot(data, 'output_phantom.png');
    });

    driver.quit();
  });
});

test.describe('Title assertion', function () {
  test.it('Title is Palles Gavebod', function () {
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

    driver.get(BASE_URL);

    driver.getTitle().then(function (title) {
      assert.equal(title, 'Palles Gavebod', 'Title is Palles Gavebod');
    });

    driver.takeScreenshot().then(function(data) {
      writeScreenshot(data, 'output_chrome.png');
    });

    driver.quit();
  });
});

/* test.describe('Express endpoint', function () {
  test.it('/profile/login can be reached', function () {
    // chrome.start();
    var endpoint = '/profile/login';
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

    driver.get(BASE_URL + endpoint);
    driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'body'})), 12000);
    var body = driver.findElement({tagName: 'body'});
    var header = body.findElement({id: 'header'});

    header.getId()
      .then(function(id) {
        assert.notEqual(typeof id, 'undefined');
      });

    driver.quit();
    // chrome.stop();

  });

  test.it('/profile/signup can be reached', function () {
    chrome.start();
    var endpoint = '/profile/signup';
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

    driver.get(BASE_URL + endpoint);
    driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'body'})), 12000);
    var body = driver.findElement({tagName: 'body'});
    var header = body.findElement({id: 'header'});

    header.getId()
      .then(function(id) {
        assert.notEqual(typeof id, 'undefined');
      });

    driver.quit();
    // chrome.stop();
  });
});

test.describe('Login page', function () {
  test.it('is rendered', function () {
    chrome.start();
    var endpoint = '/profile/login';
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

    driver.get(BASE_URL + endpoint);
    driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'input', name: 'username'})), 5000);
    var emailInput = driver.findElement({tagName: 'input', name: 'username'});
    emailInput.sendKeys('rasmussen.matias@gmail.com');
    driver.quit();
    // chrome.stop();
  });
});

test.describe('Signup page', function () {
  test.it('is rendered', function () {
    chrome.start();
    var endpoint = '/profile/signup';
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

    driver.get(BASE_URL + endpoint);
    driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'input', name: 'username'})), 5000);

    driver.quit();
    // chrome.stop();

  });
}); */

<commit_msg>Accumulated commit of the following from branch 'origin/ready/mra':<commit_after>'use strict';
var fs = require('fs');
var assert = require('assert');
var test = require('selenium-webdriver/testing');
var webdriver = require('selenium-webdriver');
var chrome = require('chromedriver');

var BASE_URL = process.env.SELENIUM_URL || 'http://localhost:8080';

function writeScreenshot(data, name) {
  name = name || 'ss.png';
  var screenshotPath = '';
  fs.writeFileSync(screenshotPath + name, data, 'base64');
}

test.describe('Title assertion', function () {
  test.it('Title is Palles Gavebod', function () {
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.phantomjs())
      .build();

    driver.get(BASE_URL);

    driver.getTitle().then(function (title) {
      assert.equal(title, 'Palles Gavebod', 'Title is Palles Gavebod');
    });

    driver.quit();
  });
});

test.describe('Title assertion', function () {
  test.it('Title is Palles Gavebod', function () {
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

    driver.get(BASE_URL);

    driver.getTitle().then(function (title) {
      assert.equal(title, 'Palles Gavebod', 'Title is Palles Gavebod');
    });

    driver.quit();
  });
});

 test.describe('Express endpoint', function () {
  test.it('/profile/login can be reached', function () {
    // chrome.start();
    var endpoint = '/profile/login';
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

    driver.get(BASE_URL + endpoint);
    driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'body'})), 12000);
    var body = driver.findElement({tagName: 'body'});
    var header = body.findElement({id: 'header'});

    header.getId()
      .then(function(id) {
        assert.notEqual(typeof id, 'undefined');
      });

    driver.quit();
    // chrome.stop();

  });

  test.it('/profile/signup can be reached', function () {
    chrome.start();
    var endpoint = '/profile/signup';
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

    driver.get(BASE_URL + endpoint);
    driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'body'})), 12000);
    var body = driver.findElement({tagName: 'body'});
    var header = body.findElement({id: 'header'});

    header.getId()
      .then(function(id) {
        assert.notEqual(typeof id, 'undefined');
      });

    driver.quit();
    // chrome.stop();
  });
});

test.describe('Login page', function () {
  test.it('is rendered', function () {
    chrome.start();
    var endpoint = '/profile/login';
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

    driver.get(BASE_URL + endpoint);
    driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'input', name: 'username'})), 5000);
    var emailInput = driver.findElement({tagName: 'input', name: 'username'});
    emailInput.sendKeys('rasmussen.matias@gmail.com');
    driver.quit();
    // chrome.stop();
  });
});

test.describe('Signup page', function () {
  test.it('is rendered', function () {
    chrome.start();
    var endpoint = '/profile/signup';
    var driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();

    driver.get(BASE_URL + endpoint);
    driver.wait(webdriver.until.elementIsVisible(driver.findElement({tagName: 'input', name: 'username'})), 5000);

    driver.quit();
    // chrome.stop();

  });
});
<|endoftext|>


<commit_before>/** @jsx React.DOM */
/**
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */
var React = require('react');
var LoginNav = require('../loginnav');

var TermsOverlay = React.createClass({
  propTypes: {
    onSubmit: React.PropTypes.func.isRequired,
    trackMetric: React.PropTypes.func.isRequired,
    ages: React.PropTypes.object.isRequired,
    messages: React.PropTypes.object.isRequired
  },
  getDefaultProps: function(){
    return {
      ages: {
        OF_AGE : { value: '>=18', label: ' I am 18 years old or older.'},
        WITH_CONSENT : { value: '13-17', label: ' I am between 13 and 17 years old. You\'ll need to have a parent or guardian agree to the terms on the next screen.' },
        NOT_OF_AGE : { value: '<=12', label: ' I am 12 years old or younger.'}
      },
      messages: {
        ACCEPT_OF_AGE : 'I am 18 or older and I accept the terms of the Tidepool Applications Terms of Use and Privacy Policy',
        ACCEPT_ON_BEHALF: 'I agree that my child aged 13 through 17 can use Tidepool Applications and agree that they are also bound to the terms of the Tidepool Applications Terms of Use and Privacy Policy',
        SORRY_NOT_OF_AGE : 'We are really sorry, but you need to be 13 or older in order to create an account and use Tidepool\'s Applications.'
      }
    };
  },
  getInitialState: function() {
    return {
      agreed: false,
      agreedOnBehalf: false,
      ageConfirmed: false,
      ageSelected: this.props.ages.OF_AGE.value //default
    };
  },
  renderAgeConsentStep:function(){
    return (
      <form ref='confirmAgeStep' className='terms-overlay-age-form'>

            <input type='radio' name='age'
              key={this.props.ages.OF_AGE.value}
              value={this.props.ages.OF_AGE.value}
              onChange={this.handleAgeChange}
              defaultChecked={true} />
            {this.props.ages.OF_AGE.label}

            <input type='radio' name='age'
              key={this.props.ages.WITH_CONSENT.value}
              value={this.props.ages.WITH_CONSENT.value}
              onChange={this.handleAgeChange} />
            {this.props.ages.WITH_CONSENT.label}

            <input type='radio' name='age'
              key={this.props.ages.NOT_OF_AGE.value}
              value={this.props.ages.NOT_OF_AGE.value}
              onChange={this.handleAgeChange} />
            {this.props.ages.NOT_OF_AGE.label}

        <button
          className='btn btn-primary js-terms-submit'
          onClick={this.handleAgeSubmit}>Continue</button>
      </form>
    );
  },
  getTermsAndPrivacyButtonState:function(){
    var isDisabled = !this.state.agreed;

    if (this.state.ageSelected === this.props.ages.WITH_CONSENT.value) {
      if (this.state.agreed && this.state.agreedOnBehalf){
        isDisabled = false;
      } else {
        isDisabled = true;
      }
    }
    return isDisabled;
  },
  renderTermsAndPrivacyStep:function(){
    var terms = this.websiteTerms();
    var privacy = this.websitePrivacy();
    var continueBtnDisabled = this.getTermsAndPrivacyButtonState();
    var agreeConfirmation = this.renderAgreeCheckboxes();
    var backBtn = this.renderBackBtn();

    return (

TERMS OF USE

        {terms}

PRIVACY POLICY

        {privacy}
        <form className='terms-overlay-form'>
          {agreeConfirmation}
          {backBtn}
          <button
            className='terms-button terms-button-submit'
            onClick={this.handleTermsAndPrivacySubmit}
            disabled={continueBtnDisabled}>Continue</button>
        </form>

    );
  },
  renderBackBtn:function(){
    return (
      <button
        className='terms-button terms-button-back'
        onClick={this.handleBack}>Back</button>
    );
  },
  renderAgreeCheckboxes:function(){

    var onBehalf;
    if (this.state.ageSelected === this.props.ages.WITH_CONSENT.value) {
      onBehalf = (

          <input
            id='agreedOnBehalf'
            type='checkbox'
            className='js-terms-checkbox'
            checked={this.state.agreedOnBehalf}
            onChange={this.handleOnBehalfAgreementChange} />
          {this.props.messages.ACCEPT_ON_BEHALF}

      );
    }

    return (

          <input
            id='agreed'
            type='checkbox'
            className='js-terms-checkbox'
            checked={this.state.agreed}
            onChange={this.handleAgreementChange} />
          {this.props.messages.ACCEPT_OF_AGE}

        {onBehalf}

    );
  },
  renderSorryMessage:function(){
    var backBtn = this.renderBackBtn();
    return (

{this.props.messages.SORRY_NOT_OF_AGE}

        {backBtn}

    );
  },
  render: function() {

    var content = this.renderAgeConsentStep();

    if( this.state.ageConfirmed ){
      //assume we are good to go
      content = this.renderTermsAndPrivacyStep();

      if( this.state.ageSelected === this.props.ages.NOT_OF_AGE.value ){
        //unless they are NOT_OF_AGE
        content = this.renderSorryMessage();
      }
    }

    return (

        <LoginNav hideLinks={true} trackMetric={this.props.trackMetric} />

          {content}

    );

  },
  websiteTerms: function() {
    return React.DOM.iframe({
      className         : 'terms-overlay-iframe',
      src               : 'https://tidepool.org/terms-of-use/',
      scrolling         : 'yes',
      frameBorder       : '0',
      allowTransparency : 'true'
    });
  },
  websitePrivacy: function() {
    return React.DOM.iframe({
      className         : 'terms-overlay-iframe',
      src               : 'https://tidepool.org/privacy-policy/',
      scrolling         : 'yes',
      frameBorder       : '0',
      allowTransparency : 'true'
    });
  },
  handleBack: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.setState(this.getInitialState());
    this.props.trackMetric('Back');
  },
  handleAgeSubmit: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.setState({ageConfirmed: true });
    this.props.trackMetric('Confirmed age');
  },
  handleAgeChange:function(e){
    this.setState({ ageSelected: e.target.value});
  },
  handleAgreementChange: function() {
    this.setState({agreed: !this.state.agreed});
  },
  handleOnBehalfAgreementChange: function() {
    this.setState({agreedOnBehalf: !this.state.agreedOnBehalf});
  },
  handleTermsAndPrivacySubmit: function(e) {
    if (e) {
      e.preventDefault();
    }

    this.props.trackMetric('Agreed To Terms Of Use');
    this.props.onSubmit(this.state.ageSelected);
  }
});

module.exports = TermsOverlay;<commit_msg>consistency in whitespace<commit_after>/** @jsx React.DOM */
/**
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */
var React = require('react');
var LoginNav = require('../loginnav');

var TermsOverlay = React.createClass({
  propTypes: {
    onSubmit: React.PropTypes.func.isRequired,
    trackMetric: React.PropTypes.func.isRequired,
    ages: React.PropTypes.object.isRequired,
    messages: React.PropTypes.object.isRequired
  },
  getDefaultProps: function() {
    return {
      ages: {
        OF_AGE: {value: '>=18', label: ' I am 18 years old or older.'},
        WITH_CONSENT: {value: '13-17', label: ' I am between 13 and 17 years old. You\'ll need to have a parent or guardian agree to the terms on the next screen.' },
        NOT_OF_AGE: {value: '<=12', label: ' I am 12 years old or younger.'}
      },
      messages: {
        ACCEPT_OF_AGE: 'I am 18 or older and I accept the terms of the Tidepool Applications Terms of Use and Privacy Policy',
        ACCEPT_ON_BEHALF: 'I agree that my child aged 13 through 17 can use Tidepool Applications and agree that they are also bound to the terms of the Tidepool Applications Terms of Use and Privacy Policy',
        SORRY_NOT_OF_AGE: 'We are really sorry, but you need to be 13 or older in order to create an account and use Tidepool\'s Applications.'
      }
    };
  },
  getInitialState: function() {
    return {
      agreed: false,
      agreedOnBehalf: false,
      ageConfirmed: false,
      ageSelected: this.props.ages.OF_AGE.value //default
    };
  },
  renderAgeConsentStep: function() {
    return (
      <form ref='confirmAgeStep' className='terms-overlay-age-form'>

            <input type='radio' name='age'
              key={this.props.ages.OF_AGE.value}
              value={this.props.ages.OF_AGE.value}
              onChange={this.handleAgeChange}
              defaultChecked={true} />
            {this.props.ages.OF_AGE.label}

            <input type='radio' name='age'
              key={this.props.ages.WITH_CONSENT.value}
              value={this.props.ages.WITH_CONSENT.value}
              onChange={this.handleAgeChange} />
            {this.props.ages.WITH_CONSENT.label}

            <input type='radio' name='age'
              key={this.props.ages.NOT_OF_AGE.value}
              value={this.props.ages.NOT_OF_AGE.value}
              onChange={this.handleAgeChange} />
            {this.props.ages.NOT_OF_AGE.label}

        <button
          className='btn btn-primary js-terms-submit'
          onClick={this.handleAgeSubmit}>Continue</button>
      </form>
    );
  },
  getTermsAndPrivacyButtonState: function() {
    var isDisabled = !this.state.agreed;

    if (this.state.ageSelected === this.props.ages.WITH_CONSENT.value) {
      if (this.state.agreed && this.state.agreedOnBehalf) {
        isDisabled = false;
      }
      else {
        isDisabled = true;
      }
    }
    return isDisabled;
  },
  renderTermsAndPrivacyStep: function() {
    var terms = this.websiteTerms();
    var privacy = this.websitePrivacy();
    var continueBtnDisabled = this.getTermsAndPrivacyButtonState();
    var agreeConfirmation = this.renderAgreeCheckboxes();
    var backBtn = this.renderBackBtn();

    return (

TERMS OF USE

        {terms}

PRIVACY POLICY

        {privacy}
        <form className='terms-overlay-form'>
          {agreeConfirmation}
          {backBtn}
          <button
            className='terms-button terms-button-submit'
            onClick={this.handleTermsAndPrivacySubmit}
            disabled={continueBtnDisabled}>Continue</button>
        </form>

    );
  },
  renderBackBtn: function() {
    return (
      <button
        className='terms-button terms-button-back'
        onClick={this.handleBack}>Back</button>
    );
  },
  renderAgreeCheckboxes: function() {

    var onBehalf;
    if (this.state.ageSelected === this.props.ages.WITH_CONSENT.value) {
      onBehalf = (

          <input
            id='agreedOnBehalf'
            type='checkbox'
            className='js-terms-checkbox'
            checked={this.state.agreedOnBehalf}
            onChange={this.handleOnBehalfAgreementChange} />
          {this.props.messages.ACCEPT_ON_BEHALF}

      );
    }

    return (

          <input
            id='agreed'
            type='checkbox'
            className='js-terms-checkbox'
            checked={this.state.agreed}
            onChange={this.handleAgreementChange} />
          {this.props.messages.ACCEPT_OF_AGE}

        {onBehalf}

    );
  },
  renderSorryMessage: function() {
    var backBtn = this.renderBackBtn();
    return (

{this.props.messages.SORRY_NOT_OF_AGE}

        {backBtn}

    );
  },
  render: function() {

    var content = this.renderAgeConsentStep();

    if (this.state.ageConfirmed) {
      //assume we are good to go
      content = this.renderTermsAndPrivacyStep();

      if (this.state.ageSelected === this.props.ages.NOT_OF_AGE.value) {
        //unless they are NOT_OF_AGE
        content = this.renderSorryMessage();
      }
    }

    return (

        <LoginNav hideLinks={true} trackMetric={this.props.trackMetric} />

          {content}

    );

  },
  websiteTerms: function() {
    return React.DOM.iframe({
      className         : 'terms-overlay-iframe',
      src               : 'https://tidepool.org/terms-of-use/',
      scrolling         : 'yes',
      frameBorder       : '0',
      allowTransparency : 'true'
    });
  },
  websitePrivacy: function() {
    return React.DOM.iframe({
      className         : 'terms-overlay-iframe',
      src               : 'https://tidepool.org/privacy-policy/',
      scrolling         : 'yes',
      frameBorder       : '0',
      allowTransparency : 'true'
    });
  },
  handleBack: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.setState(this.getInitialState());
    this.props.trackMetric('Back');
  },
  handleAgeSubmit: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.setState({ageConfirmed: true });
    this.props.trackMetric('Confirmed age');
  },
  handleAgeChange: function(e) {
    this.setState({ ageSelected: e.target.value});
  },
  handleAgreementChange: function() {
    this.setState({agreed: !this.state.agreed});
  },
  handleOnBehalfAgreementChange: function() {
    this.setState({agreedOnBehalf: !this.state.agreedOnBehalf});
  },
  handleTermsAndPrivacySubmit: function(e) {
    if (e) {
      e.preventDefault();
    }

    this.props.trackMetric('Agreed To Terms Of Use');
    this.props.onSubmit(this.state.ageSelected);
  }
});

module.exports = TermsOverlay;<|endoftext|>