diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..3b406630 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,72 @@ +# Various Node ignoramuses. + +logs +*.log +npm-debug.log* +pids +*.pid +*.seed +lib-cov +coverage +.grunt +.lock-wscript +build/Release +node_modules +jspm_modules +.npm +.node_repl_history + +# Various Windows ignoramuses. +Thumbs.db +ehthumbs.db +Desktop.ini +$RECYCLE.BIN/ +*.cab +*.msi +*.msm +*.msp +*.lnk + +# Various OSX ignoramuses. +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Various Linux ignoramuses. + +.fuse_hidden* +.directory +.Trash-* + +# Various Magic Mirror ignoramuses and anti-ignoramuses. + +# Don't ignore the node_helper core module. +!/modules/node_helper +!/modules/node_helper/** + +# Ignore all modules except the default modules. +/modules/** +!/modules/default/** + +# Ignore changes to the custom css files. +/css/custom.css + +# Ignore unnecessary files for docker +CHANGELOG.md +LICENSE.md +README.md +Gruntfile.js +.* diff --git a/.gitignore b/.gitignore index 1e17ef8b..e130a22e 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,7 @@ Temporary Items # Various Magic Mirror ignoramuses and anti-ignoramuses. -# Don't ignore the node_helper nore module. +# Don't ignore the node_helper core module. !/modules/node_helper !/modules/node_helper/** diff --git a/.travis.yml b/.travis.yml index da3fb099..0727182b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,9 @@ node_js: - "5.1" before_script: - npm install grunt-cli -g + - "export DISPLAY=:99.0" + - "sh -e /etc/init.d/xvfb start" + - sleep 5 script: - grunt - npm test diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fdbafa7..6c6e31e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). + ## [2.1.1] - Unreleased **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` @@ -16,8 +17,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Run `npm test` on Travis automatically - Show the splash screen image even when is reboot or halted. - Added some missing translaton strings in the sv.json file. +- Run task jsonlint to check translation files. +- Restructured Test Suite ### Added +- Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673)) - Calendar-specific support for `maximumEntries`, and ` maximumNumberOfDays` - Add loaded function to modules, providing an async callback. - Made default newsfeed module aware of gesture events from [MMM-Gestures](https://github.com/thobach/MMM-Gestures) @@ -35,6 +39,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Option for colored min-temp and max-temp - Add test e2e helloworld - Add test e2e enviroment +- Add `chai-as-promised` npm module to devDependencies +- Basic set of tests for clock module +- Run e2e test in Travis ### Fixed - Update .gitignore to not ignore default modules folder. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..d845bac0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM node:latest + +WORKDIR /opt/magic_mirror +COPY . . +COPY /modules unmount_modules +COPY /config unmount_config + +ENV NODE_ENV production +ENV MM_PORT 8080 + +RUN npm install +RUN ["chmod", "+x", "docker-entrypoint.sh"] + +EXPOSE $MM_PORT +ENTRYPOINT ["/opt/magic_mirror/docker-entrypoint.sh"] diff --git a/Gruntfile.js b/Gruntfile.js index a3edb053..5aa68811 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -10,6 +10,8 @@ module.exports = function(grunt) { "serveronly/*.js", "*.js", "tests/*/*.js", "!modules/default/alert/notificationFx.js", "!modules/default/alert/modernizr.custom.js", "!modules/default/alert/classie.js", "config/*", + "translations/translations.js" + ] }, stylelint: { @@ -22,7 +24,7 @@ module.exports = function(grunt) { }, jsonlint: { main: { - src: ["package.json", ".eslintrc.json", ".stylelint"], + src: ["package.json", ".eslintrc.json", ".stylelintrc", "translations/*.json", "modules/default/*/translations/*.json"], options: { reporter: "jshint" } diff --git a/README.md b/README.md index b13b5f54..a94a7db5 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,41 @@ curl -sL https://raw.githubusercontent.com/MichMich/MagicMirror/master/installer **Note:** if you want to debug on Raspberry Pi you can use `npm start dev` which will start the MagicMirror app with Dev Tools enabled. ### Server Only +In some cases, you want to start the application without an actual app window. In this case, you can start MagicMirror² in server only mode by manually running `node serveronly` or using Docker. This will start the server, after which you can open the application in your browser of choice. Detailed description below. -In some cases, you want to start the application without an actual app window. In this case, execute the following command from the MagicMirror folder: `node serveronly`. This will start the server, after which you can open the application in your browser of choice. +#### Docker + +MagicMirror² in server only mode can be deployed using [Docker](https://docker.com). After a successful [Docker installation](https://docs.docker.com/engine/installation/) you just need to execute the following command in the shell: + +```bash +docker run -d \ + --publish 80:8080 \ + --restart always \ + --volume ~/magic_mirror/config:/opt/magic_mirror/config \ + --volume ~/magic_mirror/modules:/opt/magic_mirror/modules \ + --name magic_mirror \ + MichMich/MagicMirror +``` + +| **Volumes** | **Description** | +| --- | --- | +| `/opt/magic_mirror/config` | Mount this volume to insert your own config into the docker container. | +| `/opt/magic_mirror/modules` | Mount this volume to add your own custom modules into the docker container. | + +You may need to add your Docker Host IP to your `ipWhitelist` option. If you have some issues setting up this configuration, check [this forum post](https://forum.magicmirror.builders/topic/1326/ipwhitelist-howto). + +```javascript +var config = { + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:172.17.0.1"] +}; +``` + +#### Manual + +1. Download and install the latest Node.js version. +2. Clone the repository and check out the master branch: `git clone https://github.com/MichMich/MagicMirror` +3. Enter the repository: `cd ~/MagicMirror` +4. Install and run the app: `npm install && node serveronly` ### Raspberry Configuration & Auto Start. diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 00000000..9d91492f --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [ ! -f /opt/magic_mirror/modules ]; then + cp -R /opt/magic_mirror/unmount_modules/. /opt/magic_mirror/modules +fi + +if [ ! -f /opt/magic_mirror/config ]; then + cp -R /opt/magic_mirror/unmount_config/. /opt/magic_mirror/config +fi + +node serveronly diff --git a/js/app.js b/js/app.js index 6466fe3f..57035541 100644 --- a/js/app.js +++ b/js/app.js @@ -21,6 +21,11 @@ if (process.env.MM_CONFIG_FILE) { global.configuration_file = process.env.MM_CONFIG_FILE; } +//Hotfix PullRequest #673 +if (process.env.MM_PORT) { + global.mmPort = process.env.MM_PORT; +} + // The next part is here to prevent a major exception when there // is no internet connection. This could probable be solved better. process.on("uncaughtException", function (err) { diff --git a/js/defaults.js b/js/defaults.js index 4639e2b3..66926de7 100644 --- a/js/defaults.js +++ b/js/defaults.js @@ -7,8 +7,12 @@ * MIT Licensed. */ +var port = 8080; +if (typeof(mmPort) !== "undefined") { + port = mmPort; +} var defaults = { - port: 8080, + port: port, kioskmode: false, electronOptions: {}, ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], diff --git a/js/server.js b/js/server.js index e7050021..36cfe8d2 100644 --- a/js/server.js +++ b/js/server.js @@ -37,7 +37,7 @@ var Server = function(config, callback) { app.use("/modules", express.static(path.resolve(global.root_path + "/modules"))); app.use("/vendor", express.static(path.resolve(global.root_path + "/vendor"))); app.use("/translations", express.static(path.resolve(global.root_path + "/translations"))); - app.use("/tests/confs", express.static(path.resolve(global.root_path + "/tests/confs"))); + app.use("/tests/configs", express.static(path.resolve(global.root_path + "/tests/configs"))); app.get("/version", function(req,res) { res.send(global.version); diff --git a/modules/default/alert/translations/ru.json b/modules/default/alert/translations/ru.json index ef7ee708..60ddf3d8 100644 --- a/modules/default/alert/translations/ru.json +++ b/modules/default/alert/translations/ru.json @@ -1,4 +1,4 @@ { "sysTitle": "MagicMirror Уведомление", - "welcome": "Добро пожаловать, старт был успешным!"" + "welcome": "Добро пожаловать, старт был успешным!" } diff --git a/package.json b/package.json index 92202936..d8c10032 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "start": "sh run-start.sh", "postinstall": "sh installers/postinstall/postinstall.sh", - "test": "./node_modules/mocha/bin/mocha $(find tests -path '*js*' ! -ipath '*e2e*')", + "test": "./node_modules/mocha/bin/mocha tests --recursive", + "test:unit": "./node_modules/mocha/bin/mocha tests/unit --recursive", "test:e2e": "./node_modules/mocha/bin/mocha tests/e2e --recursive" }, "repository": { @@ -30,6 +31,7 @@ "homepage": "https://github.com/MichMich/MagicMirror#readme", "devDependencies": { "chai": "^3.5.0", + "chai-as-promised": "^6.0.0", "grunt": "latest", "grunt-eslint": "latest", "grunt-jsonlint": "latest", diff --git a/tests/confs/env.js b/tests/configs/env.js similarity index 100% rename from tests/confs/env.js rename to tests/configs/env.js diff --git a/tests/configs/modules/clock/clock_12hr.js b/tests/configs/modules/clock/clock_12hr.js new file mode 100644 index 00000000..31f9e4ea --- /dev/null +++ b/tests/configs/modules/clock/clock_12hr.js @@ -0,0 +1,29 @@ +/* Magic Mirror Test config for default clock module + * + * By Sergey Morozov + * MIT Licensed. + */ + +var config = { + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + + language: "en", + timeFormat: 12, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, + + modules: [ + { + module: "clock", + position: "middle_center" + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} diff --git a/tests/configs/modules/clock/clock_24hr.js b/tests/configs/modules/clock/clock_24hr.js new file mode 100644 index 00000000..e5dd89f6 --- /dev/null +++ b/tests/configs/modules/clock/clock_24hr.js @@ -0,0 +1,29 @@ +/* Magic Mirror Test config for default clock module + * + * By Sergey Morozov + * MIT Licensed. + */ + +var config = { + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + + language: "en", + timeFormat: 24, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, + + modules: [ + { + module: "clock", + position: "middle_center" + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} diff --git a/tests/configs/modules/clock/clock_displaySeconds_false.js b/tests/configs/modules/clock/clock_displaySeconds_false.js new file mode 100644 index 00000000..91bbebba --- /dev/null +++ b/tests/configs/modules/clock/clock_displaySeconds_false.js @@ -0,0 +1,32 @@ +/* Magic Mirror Test config for default clock module + * + * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com + * MIT Licensed. + */ + +var config = { + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + + language: "en", + timeFormat: 12, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, + + modules: [ + { + module: "clock", + position: "middle_center", + config: { + displaySeconds: false + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} diff --git a/tests/configs/modules/clock/clock_showPeriodUpper.js b/tests/configs/modules/clock/clock_showPeriodUpper.js new file mode 100644 index 00000000..e7ee7d0a --- /dev/null +++ b/tests/configs/modules/clock/clock_showPeriodUpper.js @@ -0,0 +1,32 @@ +/* Magic Mirror Test config for default clock module + * + * By Sergey Morozov + * MIT Licensed. + */ + +var config = { + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + + language: "en", + timeFormat: 12, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, + + modules: [ + { + module: "clock", + position: "middle_center", + config: { + showPeriodUpper: true + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} diff --git a/tests/configs/modules/clock/es/clock_12hr.js b/tests/configs/modules/clock/es/clock_12hr.js new file mode 100644 index 00000000..d546e608 --- /dev/null +++ b/tests/configs/modules/clock/es/clock_12hr.js @@ -0,0 +1,29 @@ +/* Magic Mirror Test config for default clock module + * + * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com + * MIT Licensed. + */ + +var config = { + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + + language: "es", + timeFormat: 12, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, + + modules: [ + { + module: "clock", + position: "middle_center" + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} diff --git a/tests/configs/modules/clock/es/clock_24hr.js b/tests/configs/modules/clock/es/clock_24hr.js new file mode 100644 index 00000000..abdf7a44 --- /dev/null +++ b/tests/configs/modules/clock/es/clock_24hr.js @@ -0,0 +1,29 @@ +/* Magic Mirror Test config for default clock module + * + * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com + * MIT Licensed. + */ + +var config = { + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + + language: "es", + timeFormat: 24, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, + + modules: [ + { + module: "clock", + position: "middle_center" + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} diff --git a/tests/configs/modules/clock/es/clock_showPeriodUpper.js b/tests/configs/modules/clock/es/clock_showPeriodUpper.js new file mode 100644 index 00000000..6bb396db --- /dev/null +++ b/tests/configs/modules/clock/es/clock_showPeriodUpper.js @@ -0,0 +1,32 @@ +/* Magic Mirror Test config for default clock module + * + * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com + * MIT Licensed. + */ + +var config = { + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + + language: "es", + timeFormat: 12, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, + + modules: [ + { + module: "clock", + position: "middle_center", + config: { + showPeriodUpper: true + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} diff --git a/tests/confs/helloworld.js b/tests/configs/modules/helloworld/helloworld.js similarity index 100% rename from tests/confs/helloworld.js rename to tests/configs/modules/helloworld/helloworld.js diff --git a/tests/e2e/env.js b/tests/e2e/env_spec.js similarity index 77% rename from tests/e2e/env.js rename to tests/e2e/env_spec.js index 41386499..77cd418b 100644 --- a/tests/e2e/env.js +++ b/tests/e2e/env_spec.js @@ -3,9 +3,6 @@ const path = require("path"); const chai = require("chai"); const chaiAsPromised = require("chai-as-promised"); -// Set config sample for use in test -process.env.MM_CONFIG_FILE = "tests/confs/env.js"; - var electronPath = path.join(__dirname, "../../", "node_modules", ".bin", "electron"); if (process.platform === "win32") { @@ -24,9 +21,14 @@ global.before(function () { chai.use(chaiAsPromised); }); -describe("Test enviroment app electron", function () { +describe("Electron app environment", function () { this.timeout(10000); + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/env.js"; + }); + beforeEach(function (done) { app.start().then(function() { done(); } ); }); @@ -36,12 +38,12 @@ describe("Test enviroment app electron", function () { }); - it("open a window app and test if is open", function () { + it("is set to open new app window", function () { return app.client.waitUntilWindowLoaded() .getWindowCount().should.eventually.equal(1); }); - it("tests the title", function () { + it("sets correct window title", function () { return app.client.waitUntilWindowLoaded() .getTitle().should.eventually.equal("Magic Mirror"); }); diff --git a/tests/e2e/modules/clock_es_spec.js b/tests/e2e/modules/clock_es_spec.js new file mode 100644 index 00000000..72aee74c --- /dev/null +++ b/tests/e2e/modules/clock_es_spec.js @@ -0,0 +1,101 @@ +const Application = require("spectron").Application; +const path = require("path"); +const chai = require("chai"); +const chaiAsPromised = require("chai-as-promised"); + +var electronPath = path.join(__dirname, "../../../", "node_modules", ".bin", "electron"); + +if (process.platform === "win32") { + electronPath += ".cmd"; +} + +var appPath = path.join(__dirname, "../../../js/electron.js"); + +var app = new Application({ + path: electronPath, + args: [appPath] +}); + +global.before(function () { + chai.should(); + chai.use(chaiAsPromised); +}); + +describe("Clock set to spanish language module", function () { + this.timeout(10000); + + describe("with default 24hr clock config", function() { + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_24hr.js"; + }); + + beforeEach(function (done) { + app.start().then(function() { done(); } ); + }); + + afterEach(function (done) { + app.stop().then(function() { done(); }); + }); + + it("shows date with correct format", function () { + const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sabado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/; + return app.client.waitUntilWindowLoaded() + .getText(".clock .date").should.eventually.match(dateRegex); + }); + + it("shows time in 24hr format", function() { + const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/ + return app.client.waitUntilWindowLoaded() + .getText(".clock .time").should.eventually.match(timeRegex); + }); + }); + + describe("with default 12hr clock config", function() { + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_12hr.js"; + }); + + beforeEach(function (done) { + app.start().then(function() { done(); } ); + }); + + afterEach(function (done) { + app.stop().then(function() { done(); }); + }); + + it("shows date with correct format", function () { + const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sabado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/; + return app.client.waitUntilWindowLoaded() + .getText(".clock .date").should.eventually.match(dateRegex); + }); + + it("shows time in 12hr format", function() { + const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; + return app.client.waitUntilWindowLoaded() + .getText(".clock .time").should.eventually.match(timeRegex); + }); + }); + + describe("with showPeriodUpper config enabled", function() { + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_showPeriodUpper.js"; + }); + + beforeEach(function (done) { + app.start().then(function() { done(); } ); + }); + + afterEach(function (done) { + app.stop().then(function() { done(); }); + }); + + it("shows 12hr time with upper case AM/PM", function() { + const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/; + return app.client.waitUntilWindowLoaded() + .getText(".clock .time").should.eventually.match(timeRegex); + }); + }); +}); diff --git a/tests/e2e/modules/clock_spec.js b/tests/e2e/modules/clock_spec.js new file mode 100644 index 00000000..f93d9a9d --- /dev/null +++ b/tests/e2e/modules/clock_spec.js @@ -0,0 +1,123 @@ +const Application = require("spectron").Application; +const path = require("path"); +const chai = require("chai"); +const chaiAsPromised = require("chai-as-promised"); + +var electronPath = path.join(__dirname, "../../../", "node_modules", ".bin", "electron"); + +if (process.platform === "win32") { + electronPath += ".cmd"; +} + +var appPath = path.join(__dirname, "../../../js/electron.js"); + +var app = new Application({ + path: electronPath, + args: [appPath] +}); + +global.before(function () { + chai.should(); + chai.use(chaiAsPromised); +}); + +describe("Clock module", function () { + this.timeout(10000); + + describe("with default 24hr clock config", function() { + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_24hr.js"; + }); + + beforeEach(function (done) { + app.start().then(function() { done(); } ); + }); + + afterEach(function (done) { + app.stop().then(function() { done(); }); + }); + + it("shows date with correct format", function () { + const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/; + return app.client.waitUntilWindowLoaded() + .getText(".clock .date").should.eventually.match(dateRegex); + }); + + it("shows time in 24hr format", function() { + const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/ + return app.client.waitUntilWindowLoaded() + .getText(".clock .time").should.eventually.match(timeRegex); + }); + }); + + describe("with default 12hr clock config", function() { + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_12hr.js"; + }); + + beforeEach(function (done) { + app.start().then(function() { done(); } ); + }); + + afterEach(function (done) { + app.stop().then(function() { done(); }); + }); + + it("shows date with correct format", function () { + const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/; + return app.client.waitUntilWindowLoaded() + .getText(".clock .date").should.eventually.match(dateRegex); + }); + + it("shows time in 12hr format", function() { + const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; + return app.client.waitUntilWindowLoaded() + .getText(".clock .time").should.eventually.match(timeRegex); + }); + }); + + describe("with showPeriodUpper config enabled", function() { + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showPeriodUpper.js"; + }); + + beforeEach(function (done) { + app.start().then(function() { done(); } ); + }); + + afterEach(function (done) { + app.stop().then(function() { done(); }); + }); + + it("shows 12hr time with upper case AM/PM", function() { + const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/; + return app.client.waitUntilWindowLoaded() + .getText(".clock .time").should.eventually.match(timeRegex); + }); + }); + + describe("with displaySeconds config disabled", function() { + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_displaySeconds_false.js"; + }); + + beforeEach(function (done) { + app.start().then(function() { done(); } ); + }); + + afterEach(function (done) { + app.stop().then(function() { done(); }); + }); + + it("shows 12hr time without seconds am/pm", function() { + const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[ap]m$/; + return app.client.waitUntilWindowLoaded() + .getText(".clock .time").should.eventually.match(timeRegex); + }); + }); + +}); diff --git a/tests/e2e/modules/helloworld.js b/tests/e2e/modules/helloworld_spec.js similarity index 86% rename from tests/e2e/modules/helloworld.js rename to tests/e2e/modules/helloworld_spec.js index ebf8a8d1..fc3b3291 100644 --- a/tests/e2e/modules/helloworld.js +++ b/tests/e2e/modules/helloworld_spec.js @@ -3,9 +3,6 @@ const path = require("path"); const chai = require("chai"); const chaiAsPromised = require("chai-as-promised"); -// Set config sample for use in test -process.env.MM_CONFIG_FILE = "tests/confs/helloworld.js"; - var electronPath = path.join(__dirname, "../../../", "node_modules", ".bin", "electron"); if (process.platform === "win32") { @@ -27,6 +24,11 @@ global.before(function () { describe("Test helloworld module", function () { this.timeout(10000); + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld.js"; + }); + beforeEach(function (done) { app.start().then(function() { done(); } ); }); diff --git a/tests/functions/compare-version.js b/tests/unit/functions/cmp_versions_spec.js similarity index 80% rename from tests/functions/compare-version.js rename to tests/unit/functions/cmp_versions_spec.js index 8cc22101..9f3793c0 100644 --- a/tests/functions/compare-version.js +++ b/tests/unit/functions/cmp_versions_spec.js @@ -1,7 +1,7 @@ var chai = require("chai"); var expect = chai.expect; -var classMM = require("../../js/class.js"); // require for load module.js -var moduleMM = require("../../js/module.js") +var classMM = require("../../../js/class.js"); // require for load module.js +var moduleMM = require("../../../js/module.js") describe("Test function cmpVersions in js/module.js", function() { diff --git a/tests/global_vars/root_path.js b/tests/unit/global_vars/root_path_spec.js similarity index 68% rename from tests/global_vars/root_path.js rename to tests/unit/global_vars/root_path_spec.js index 04edc03f..f21d3e44 100644 --- a/tests/global_vars/root_path.js +++ b/tests/unit/global_vars/root_path_spec.js @@ -3,8 +3,8 @@ var path = require("path"); var chai = require("chai"); var expect = chai.expect; -describe("Test global.root_path, set in js/app.js", function() { - var appMM = require("../../js/app.js") +describe("'global.root_path' set in js/app.js", function() { + var appMM = require("../../../js/app.js") var expectedSubPaths = [ "modules", @@ -17,7 +17,7 @@ describe("Test global.root_path, set in js/app.js", function() { ]; expectedSubPaths.forEach(subpath => { - it(`should contain a file/folder "${subpath}"`, function() { + it(`contains a file/folder "${subpath}"`, function() { expect(fs.existsSync(path.join(global.root_path, subpath))).to.equal(true); }); }); diff --git a/translations/af.json b/translations/af.json index 894b14ea..0995bdf0 100644 --- a/translations/af.json +++ b/translations/af.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Besig om te laai …", - /* CALENDAR */ "TODAY": "Vandag", "TOMORROW": "Môre", "DAYAFTERTOMORROW": "Oormôre", "RUNNING": "Eindig in", "EMPTY": "Geen komende gebeurtenisse.", - /* WEATHER */ "N": "N", "NNE": "NNO", "NE": "NO", @@ -27,7 +24,6 @@ "NW": "NW", "NNW": "NNW", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "MagicMirror² update beskikbaar.", "UPDATE_NOTIFICATION_MODULE": "Update beskikbaar vir MODULE_NAME module.", "UPDATE_INFO": "Die huidige installasie is COMMIT_COUNT agter op die BRANCH_NAME branch." diff --git a/translations/da.json b/translations/da.json index 5ad271fe..68c544a6 100644 --- a/translations/da.json +++ b/translations/da.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Indlæser …", - /* CALENDAR */ "TODAY": "I dag", "TOMORROW": "I morgen", "DAYAFTERTOMORROW": "I overmorgen", "RUNNING": "Slutter om", "EMPTY": "Ingen kommende begivenheder.", - /* WEATHER */ "N": "N", "NNE": "NNØ", "NE": "NØ", @@ -28,7 +25,6 @@ "NNW": "NNV", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "MagicMirror² opdatering tilgængelig.", "UPDATE_NOTIFICATION_MODULE": "Opdatering tilgængelig for MODULE_NAME modulet.", "UPDATE_INFO": "Den nuværende installation er COMMIT_COUNT bagud på BRANCH_NAME branch'en." diff --git a/translations/de.json b/translations/de.json index 54ac5015..eb67d41a 100644 --- a/translations/de.json +++ b/translations/de.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Lade …", - /* CALENDAR */ "TODAY": "Heute", "TOMORROW": "Morgen", "DAYAFTERTOMORROW": "Übermorgen", "RUNNING": "noch", "EMPTY": "Keine Termine.", - /* WEATHER */ "N": "N", "NNE": "NNO", "NE": "NO", @@ -27,7 +24,6 @@ "NW": "NW", "NNW": "NNW", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "Aktualisierung für MagicMirror² verfügbar.", "UPDATE_NOTIFICATION_MODULE": "Aktualisierung für das MODULE_NAME Modul verfügbar.", "UPDATE_INFO": "Die aktuelle Installation ist COMMIT_COUNT hinter dem BRANCH_NAME branch." diff --git a/translations/en.json b/translations/en.json index 45609f61..46061738 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Loading …", - /* CALENDAR */ "TODAY": "Today", "TOMORROW": "Tomorrow", "DAYAFTERTOMORROW": "The day after tomorrow", "RUNNING": "Ends in", "EMPTY": "No upcoming events.", - /* WEATHER */ "N": "N", "NNE": "NNE", "NE": "NE", @@ -27,7 +24,6 @@ "NW": "NW", "NNW": "NNW", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "MagicMirror² update available.", "UPDATE_NOTIFICATION_MODULE": "Update available for MODULE_NAME module.", "UPDATE_INFO": "The current installation is COMMIT_COUNT behind on the BRANCH_NAME branch." diff --git a/translations/es.json b/translations/es.json index 9b80b45a..914a72ce 100644 --- a/translations/es.json +++ b/translations/es.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Cargando …", - /* CALENDAR */ "TODAY": "Hoy", "TOMORROW": "Mañana", "DAYAFTERTOMORROW": "Pasado mañana", "RUNNING": "Termina en", "EMPTY": "No hay eventos programados.", - /* WEATHER */ "N": "N", "NNE": "NNE", "NE": "NE", @@ -27,7 +24,6 @@ "NW": "NO", "NNW": "NNO", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "MagicMirror² actualización disponible.", "UPDATE_NOTIFICATION_MODULE": "Disponible una actualización para el módulo MODULE_NAME.", "UPDATE_INFO": "Tu actual instalación está COMMIT_COUNT cambios detrás de la rama BRANCH_NAME." diff --git a/translations/fi.json b/translations/fi.json index 59fa0180..08bc4060 100644 --- a/translations/fi.json +++ b/translations/fi.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Lataa …", - /* CALENDAR */ "TODAY": "Tänään", "TOMORROW": "Huomenna", "DAYAFTERTOMORROW": "Ylihuomenna", "RUNNING": "Meneillään", "EMPTY": "Ei tulevia tapahtumia.", - /* WEATHER */ "N": "P", "NNE": "PPI", "NE": "PI", @@ -27,7 +24,6 @@ "NW": "PL", "NNW": "PPL", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "MagicMirror² päivitys saatavilla.", "UPDATE_NOTIFICATION_MODULE": "Päivitys saatavilla moduulille MODULE_NAME." } diff --git a/translations/fr.json b/translations/fr.json index 2701eb08..d27bc7e6 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "Chargement …", - /* CALENDAR */ "TODAY": "Aujourd'hui", "TOMORROW": "Demain", "RUNNING": "Se termine dans", "EMPTY": "Aucun RDV.", - /* WEATHER */ "N": "N", "NNE": "NNE", "NE": "NE", diff --git a/translations/fy.json b/translations/fy.json index 44f1b476..f1735382 100644 --- a/translations/fy.json +++ b/translations/fy.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Bezich mei laden …", - /* CALENDAR */ "TODAY": "Hjoed", "TOMORROW": "Moarn", "DAYAFTERTOMORROW": "Oaremoarn", "RUNNING": "Einigest oer", "EMPTY": "Gjin plande ôfspraken.", - /* WEATHER */ "N": "N", "NNE": "NNE", "NE": "NE", diff --git a/translations/gr.json b/translations/gr.json index 6b9c92ac..a8f5ccbd 100644 --- a/translations/gr.json +++ b/translations/gr.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "Φόρτωση …", - /* CALENDAR */ "TODAY": "Σήμερα", "TOMORROW": "Αύριο", "RUNNING": "Λήγει σε", "EMPTY": "Δεν υπάρχουν προσεχείς εκδηλώσεις.", - /* WEATHER */ "N": "B", "NNE": "BBA", "NE": "BA", diff --git a/translations/hu.json b/translations/hu.json index 069ad1ad..de18d82e 100644 --- a/translations/hu.json +++ b/translations/hu.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Betöltés …", - /* CALENDAR */ "TODAY": "Ma", "TOMORROW": "Holnap", "DAYAFTERTOMORROW": "Holnapután", "RUNNING": "Vége lesz", "EMPTY": "Nincs közelgő esemény.", - /* WEATHER */ "N": "É", "NNE": "ÉÉK", "NE": "ÉK", @@ -27,8 +24,7 @@ "NW": "ÉNy", "NNW": "ÉÉNy", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "MagicMirror² elérhető egy frissítés!", "UPDATE_NOTIFICATION_MODULE": "A frissítés MODULE_NAME modul néven érhető el.", "UPDATE_INFO": "A jelenlegi telepítés COMMIT_COUNT mögött BRANCH_NAME ágon található." -} \ No newline at end of file +} diff --git a/translations/is.json b/translations/is.json index d3e6d6cb..aabc3997 100644 --- a/translations/is.json +++ b/translations/is.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Hleð upp …", - /* CALENDAR */ "TODAY": "Í dag", "TOMORROW": "Á morgun", "DAYAFTERTOMORROW": "Ekki á morgun, heldur hinn", "RUNNING": "Endar eftir", "EMPTY": "Ekkert framundan.", - /* WEATHER */ "N": "N", "NNE": "NNA", "NE": "NA", @@ -27,7 +24,6 @@ "NW": "NV", "NNW": "NNV", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "MagicMirror² uppfærsla í boði.", "UPDATE_NOTIFICATION_MODULE": "Uppfærsla í boði fyrir MODULE_NAME module.", "UPDATE_INFO": "Núverandi kerfi er COMMIT_COUNT á eftir BRANCH_NAME branchinu." diff --git a/translations/it.json b/translations/it.json index bde608b4..4e3041da 100644 --- a/translations/it.json +++ b/translations/it.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "Caricamento in corso …", - /* CALENDAR */ "TODAY": "Oggi", "TOMORROW": "Domani", "RUNNING": "Termina entro", "EMPTY": "Nessun evento in arrivo.", - /* WEATHER */ "N": "N", "NNE": "NNE", "NE": "NE", diff --git a/translations/ja.json b/translations/ja.json index 72849559..ff15687b 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -1,14 +1,11 @@ { - /* GENERAL */ - "LOADING": "ローディング …", + "LOADING": "ローディング …", - /* CALENDAR */ "TODAY": "今日", "TOMORROW": "明日", "RUNNING": "で終わります", "EMPTY": "直近のイベントはありません", - /* WEATHER */ "N": "北", "NNE": "北北東", "NE": "北東", diff --git a/translations/nb.json b/translations/nb.json index 48f0ac6f..1b57a5fa 100644 --- a/translations/nb.json +++ b/translations/nb.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "Laster …", - /* CALENDAR */ "TODAY": "I dag", "TOMORROW": "I morgen", "RUNNING": "Slutter om", "EMPTY": "Ingen kommende arrangementer.", - /* WEATHER */ "N": "N", "NNE": "NNØ", "NE": "NØ", diff --git a/translations/nl.json b/translations/nl.json index 803db06c..c615903b 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Bezig met laden …", - /* CALENDAR */ "TODAY": "Vandaag", "TOMORROW": "Morgen", "DAYAFTERTOMORROW": "Overmorgen", "RUNNING": "Eindigt over", "EMPTY": "Geen geplande afspraken.", - /* WEATHER */ "N": "N", "NNE": "NNO", "NE": "NO", @@ -27,7 +24,6 @@ "NW": "NW", "NNW": "NNW", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "MagicMirror² update beschikbaar.", "UPDATE_NOTIFICATION_MODULE": "Update beschikbaar voor MODULE_NAME module.", "UPDATE_INFO": "De huidige installatie loopt COMMIT_COUNT achter op de BRANCH_NAME branch." diff --git a/translations/nn.json b/translations/nn.json index b7dbe3ea..107bec9d 100644 --- a/translations/nn.json +++ b/translations/nn.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "Lastar …", - /* CALENDAR */ "TODAY": "I dag", "TOMORROW": "I morgon", "RUNNING": "Sluttar om", "EMPTY": "Ingen komande hendingar.", - /* WEATHER */ "N": "N", "NNE": "NNA", "NE": "NA", diff --git a/translations/pl.json b/translations/pl.json index 06bf3b5c..0c79835f 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "Ładowanie …", - /* CALENDAR */ "TODAY": "Dziś", "TOMORROW": "Jutro", "RUNNING": "Koniec za", "EMPTY": "Brak wydarzeń.", - /* WEATHER */ "N": "N", "NNE": "NNE", "NE": "NE", @@ -26,7 +23,6 @@ "NW": "NW", "NNW": "NNW", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "Dostępna jest aktualizacja MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Dostępna jest aktualizacja modułu MODULE_NAME.", "UPDATE_INFO": "Zainstalowana wersja odbiega o COMMIT_COUNT commitów od gałęzi BRANCH_NAME." diff --git a/translations/pt.json b/translations/pt.json index f8797f0f..35de1326 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "A carregar …", - /* CALENDAR */ "TODAY": "Hoje", "TOMORROW": "Amanhã", "RUNNING": "Termina em", "EMPTY": "Sem eventos a chegar.", - /* WEATHER */ "N": "N", "NNE": "NNE", "NE": "NE", diff --git a/translations/pt_br.json b/translations/pt_br.json index 17d3e636..92002b54 100644 --- a/translations/pt_br.json +++ b/translations/pt_br.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "Carregando …", - /* CALENDAR */ "TODAY": "Hoje", "TOMORROW": "Amanhã", "RUNNING": "Acaba em", "EMPTY": "Nenhum evento novo.", - /* WEATHER */ "N": "N", "NNE": "NNE", "NE": "NE", diff --git a/translations/ru.json b/translations/ru.json index 053385ee..48c49fd9 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Загрузка …", - /* CALENDAR */ "TODAY": "Сегодня", "TOMORROW": "Завтра", "DAYAFTERTOMORROW": "Послезавтра", "RUNNING": "Заканчивается через", "EMPTY": "Нет предстоящих событий", - /* WEATHER */ "N": "С", "NNE": "ССВ", "NE": "СВ", @@ -27,7 +24,6 @@ "NW": "СЗ", "NNW": "ССЗ", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "Есть обновление для MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Есть обновление для MODULE_NAME модуля.", "UPDATE_INFO": "Данная инсталляция позади BRANCH_NAME ветки на COMMIT_COUNT коммитов." diff --git a/translations/sv.json b/translations/sv.json index 8a1440f0..1fe3d48d 100644 --- a/translations/sv.json +++ b/translations/sv.json @@ -1,15 +1,12 @@ { - /* GENERAL */ "LOADING": "Laddar …", - /* CALENDAR */ "TODAY": "Idag", "TOMORROW": "Imorgon", "DAYAFTERTOMORROW": "Iövermorgon", "RUNNING": "Slutar", "EMPTY": "Inga kommande händelser.", - /* WEATHER */ "N": "N", "NNE": "NNO", "NE": "NO", @@ -27,7 +24,6 @@ "NW": "NV", "NNW": "NNV", - /* UPDATE INFO */ "UPDATE_NOTIFICATION": "MagicMirror² uppdatering finns tillgänglig.", "UPDATE_NOTIFICATION_MODULE": "Uppdatering finns tillgänglig av MODULE_NAME modulen.", "UPDATE_INFO": "Denna installation ligger COMMIT_COUNT steg bakom BRANCH_NAME grenen." diff --git a/translations/tr.json b/translations/tr.json index a0d61ac7..c79956b8 100644 --- a/translations/tr.json +++ b/translations/tr.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "Yükleniyor …", - /* CALENDAR */ "TODAY": "Bugün", "TOMORROW": "Yarın", "RUNNING": "Biten", "EMPTY": "Yakında etkinlik yok.", - /* WEATHER */ "N": "K", "NNE": "KKD", "NE": "KD", diff --git a/translations/zh_cn.json b/translations/zh_cn.json index a8c32d70..e7f69616 100644 --- a/translations/zh_cn.json +++ b/translations/zh_cn.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "正在加载 …", - /* CALENDAR */ "TODAY": "今天", "TOMORROW": "明天", "RUNNING": "结束日期", "EMPTY": "没有更多的活动。", - /* WEATHER */ "N": "北风", "NNE": "北偏东风", "NE": "东北风", diff --git a/translations/zh_tw.json b/translations/zh_tw.json index 1a5827be..550de453 100644 --- a/translations/zh_tw.json +++ b/translations/zh_tw.json @@ -1,14 +1,11 @@ { - /* GENERAL */ "LOADING": "正在加載 …", - /* CALENDAR */ "TODAY": "今天", "TOMORROW": "明天", "RUNNING": "結束日期", "EMPTY": "沒有更多的活動。", - /* WEATHER */ "N": "北風", "NNE": "北偏東風", "NE": "東北風",