Merge pull request #2687 from khassel/weather-e2e

This commit is contained in:
Michael Teeuw 2021-10-16 03:15:16 +02:00 committed by GitHub
commit 4576754de2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 2255 additions and 2226 deletions

View File

@ -15,9 +15,10 @@ _This release is scheduled to be released on 2022-01-01._
- ESLint version supports now ECMAScript 2018 - ESLint version supports now ECMAScript 2018
- Cleaned up `updatenotification` module and switched to nunjuck template. - Cleaned up `updatenotification` module and switched to nunjuck template.
- Move calendar tests from category `electron` to `e2e`. - Moved calendar tests from category `electron` to `e2e`.
- Update missed translations for Korean language (ko.json) - Update missed translations for Korean language (ko.json)
- Cleaned up `alert` module and switched to nunjuck template. - Cleaned up `alert` module and switched to nunjuck template.
- Moved weather tests from category `electron` to `e2e`.
### Fixed ### Fixed

View File

@ -113,20 +113,30 @@ const WeatherProvider = Class.extend({
// A convenience function to make requests. It returns a promise. // A convenience function to make requests. It returns a promise.
fetchData: function (url, method = "GET", data = null) { fetchData: function (url, method = "GET", data = null) {
return new Promise(function (resolve, reject) { const getData = function (mockData) {
const request = new XMLHttpRequest(); return new Promise(function (resolve, reject) {
request.open(method, url, true); if (mockData) {
request.onreadystatechange = function () { let data = mockData;
if (this.readyState === 4) { data = data.substring(1, data.length - 1);
if (this.status === 200) { resolve(JSON.parse(data));
resolve(JSON.parse(this.response)); } else {
} else { const request = new XMLHttpRequest();
reject(request); request.open(method, url, true);
} request.onreadystatechange = function () {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(JSON.parse(this.response));
} else {
reject(request);
}
}
};
request.send();
} }
}; });
request.send(); };
});
return getData(this.config.mockData);
} }
}); });

3776
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -47,13 +47,13 @@
"homepage": "https://magicmirror.builders", "homepage": "https://magicmirror.builders",
"devDependencies": { "devDependencies": {
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-jest": "^24.5.2", "eslint-plugin-jest": "^25.2.1",
"eslint-plugin-jsdoc": "^36.1.0", "eslint-plugin-jsdoc": "^36.1.1",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^4.0.0",
"express-basic-auth": "^1.2.0", "express-basic-auth": "^1.2.0",
"husky": "^7.0.2", "husky": "^7.0.2",
"jest": "^27.2.4", "jest": "^27.2.5",
"jsdom": "^17.0.0", "jsdom": "^18.0.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"nyc": "^15.1.0", "nyc": "^15.1.0",
"prettier": "^2.4.1", "prettier": "^2.4.1",
@ -61,13 +61,13 @@
"sinon": "^11.1.2", "sinon": "^11.1.2",
"spectron": "^15.0.0", "spectron": "^15.0.0",
"stylelint": "^13.13.1", "stylelint": "^13.13.1",
"stylelint-config-prettier": "^8.0.2", "stylelint-config-prettier": "^9.0.3",
"stylelint-config-standard": "^22.0.0", "stylelint-config-standard": "^22.0.0",
"stylelint-prettier": "^1.2.0", "stylelint-prettier": "^1.2.0",
"suncalc": "^1.8.0" "suncalc": "^1.8.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"electron": "^13.5.1" "electron": "^13.5.2"
}, },
"dependencies": { "dependencies": {
"colors": "^1.4.0", "colors": "^1.4.0",
@ -83,7 +83,7 @@
"moment": "^2.29.1", "moment": "^2.29.1",
"node-fetch": "^2.6.5", "node-fetch": "^2.6.5",
"node-ical": "^0.13.0", "node-ical": "^0.13.0",
"socket.io": "^4.2.0" "socket.io": "^4.3.0"
}, },
"_moduleAliases": { "_moduleAliases": {
"node_helper": "js/node_helper.js", "node_helper": "js/node_helper.js",
@ -113,7 +113,6 @@
"**/tests/electron/**/*.[jt]s?(x)" "**/tests/electron/**/*.[jt]s?(x)"
], ],
"testPathIgnorePatterns": [ "testPathIgnorePatterns": [
"<rootDir>/tests/electron/modules/mocks",
"<rootDir>/tests/electron/global-setup.js" "<rootDir>/tests/electron/global-setup.js"
] ]
}, },
@ -129,9 +128,10 @@
"<rootDir>/js/" "<rootDir>/js/"
], ],
"testPathIgnorePatterns": [ "testPathIgnorePatterns": [
"<rootDir>/tests/e2e/modules/mocks",
"<rootDir>/tests/e2e/modules/basic-auth.js",
"<rootDir>/tests/e2e/global-setup.js", "<rootDir>/tests/e2e/global-setup.js",
"<rootDir>/tests/e2e/mock-console.js", "<rootDir>/tests/e2e/mock-console.js"
"<rootDir>/tests/e2e/modules/basic-auth.js"
] ]
} }
] ]

View File

@ -3,7 +3,7 @@
* By rejas https://github.com/rejas * By rejas https://github.com/rejas
* MIT Licensed. * MIT Licensed.
*/ */
let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ let config = {
modules: [ modules: [
{ {
module: "compliments", module: "compliments",
@ -12,7 +12,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory(
compliments: { compliments: {
snow: ["snow"] snow: ["snow"]
}, },
updateInterval: 4000 updateInterval: 3000
} }
}, },
{ {
@ -20,12 +20,11 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory(
position: "bottom_bar", position: "bottom_bar",
config: { config: {
location: "Munich", location: "Munich",
apiKey: "fake key", mockData: '"#####WEATHERDATA#####"'
initialLoadDelay: 3000
} }
} }
] ]
}); };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") { if (typeof module !== "undefined") {

View File

@ -3,7 +3,7 @@
* By fewieden https://github.com/fewieden * By fewieden https://github.com/fewieden
* MIT Licensed. * MIT Licensed.
*/ */
let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ let config = {
timeFormat: 12, timeFormat: 12,
modules: [ modules: [
@ -12,12 +12,11 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory(
position: "bottom_bar", position: "bottom_bar",
config: { config: {
location: "Munich", location: "Munich",
apiKey: "fake key", mockData: '"#####WEATHERDATA#####"'
initialLoadDelay: 3000
} }
} }
] ]
}); };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") { if (typeof module !== "undefined") {

View File

@ -3,15 +3,14 @@
* By fewieden https://github.com/fewieden * By fewieden https://github.com/fewieden
* MIT Licensed. * MIT Licensed.
*/ */
let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ let config = {
modules: [ modules: [
{ {
module: "weather", module: "weather",
position: "bottom_bar", position: "bottom_bar",
config: { config: {
location: "Munich", location: "Munich",
apiKey: "fake key", mockData: '"#####WEATHERDATA#####"',
initialLoadDelay: 3000,
useBeaufort: false, useBeaufort: false,
showWindDirectionAsArrow: true, showWindDirectionAsArrow: true,
showSun: false, showSun: false,
@ -21,7 +20,7 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory(
} }
} }
] ]
}); };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") { if (typeof module !== "undefined") {

View File

@ -3,7 +3,7 @@
* By fewieden https://github.com/fewieden * By fewieden https://github.com/fewieden
* MIT Licensed. * MIT Licensed.
*/ */
let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ let config = {
units: "imperial", units: "imperial",
modules: [ modules: [
@ -12,14 +12,13 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory(
position: "bottom_bar", position: "bottom_bar",
config: { config: {
location: "Munich", location: "Munich",
apiKey: "fake key", mockData: '"#####WEATHERDATA#####"',
initialLoadDelay: 3000,
decimalSymbol: ",", decimalSymbol: ",",
showHumidity: true showHumidity: true
} }
} }
] ]
}); };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") { if (typeof module !== "undefined") {

View File

@ -3,7 +3,7 @@
* By fewieden https://github.com/fewieden * By fewieden https://github.com/fewieden
* MIT Licensed. * MIT Licensed.
*/ */
let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ let config = {
timeFormat: 12, timeFormat: 12,
modules: [ modules: [
@ -13,13 +13,12 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory(
config: { config: {
type: "forecast", type: "forecast",
location: "Munich", location: "Munich",
apiKey: "fake key", mockData: '"#####WEATHERDATA#####"',
weatherEndpoint: "/forecast/daily", weatherEndpoint: "/forecast/daily"
initialLoadDelay: 3000
} }
} }
] ]
}); };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") { if (typeof module !== "undefined") {

View File

@ -3,7 +3,7 @@
* By fewieden https://github.com/fewieden * By fewieden https://github.com/fewieden
* MIT Licensed. * MIT Licensed.
*/ */
let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ let config = {
timeFormat: 12, timeFormat: 12,
modules: [ modules: [
@ -13,16 +13,15 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory(
config: { config: {
type: "forecast", type: "forecast",
location: "Munich", location: "Munich",
apiKey: "fake key", mockData: '"#####WEATHERDATA#####"',
weatherEndpoint: "/forecast/daily", weatherEndpoint: "/forecast/daily",
initialLoadDelay: 3000,
showPrecipitationAmount: true, showPrecipitationAmount: true,
colored: true, colored: true,
tableClass: "myTableClass" tableClass: "myTableClass"
} }
} }
] ]
}); };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") { if (typeof module !== "undefined") {

View File

@ -3,7 +3,7 @@
* By rejas * By rejas
* MIT Licensed. * MIT Licensed.
*/ */
let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ let config = {
units: "imperial", units: "imperial",
modules: [ modules: [
@ -13,14 +13,13 @@ let config = require(process.cwd() + "/tests/configs/default.js").configFactory(
config: { config: {
type: "forecast", type: "forecast",
location: "Munich", location: "Munich",
apiKey: "fake key", mockData: '"#####WEATHERDATA#####"',
weatherEndpoint: "/forecast/daily", weatherEndpoint: "/forecast/daily",
initialLoadDelay: 3000,
decimalSymbol: "_" decimalSymbol: "_"
} }
} }
] ]
}); };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") { if (typeof module !== "undefined") {

View File

@ -6,7 +6,11 @@ exports.startApplication = function (configFilename, exec) {
global.app.stop(); global.app.stop();
} }
// Set config sample for use in test // Set config sample for use in test
process.env.MM_CONFIG_FILE = configFilename; if (configFilename === "") {
process.env.MM_CONFIG_FILE = "config/config.js";
} else {
process.env.MM_CONFIG_FILE = configFilename;
}
if (exec) exec; if (exec) exec;
global.app = require("app.js"); global.app = require("app.js");
global.app.start(); global.app.start();

View File

@ -3,7 +3,7 @@ const helpers = require("../global-setup");
describe("Alert module", function () { describe("Alert module", function () {
beforeAll(function (done) { beforeAll(function (done) {
helpers.startApplication("tests/configs/modules/alert/default.js"); helpers.startApplication("tests/configs/modules/alert/default.js");
helpers.getDocument(done, 1000); helpers.getDocument(done, 3000);
}); });
afterAll(function () { afterAll(function () {
helpers.stopApplication(); helpers.stopApplication();

View File

@ -0,0 +1,243 @@
const moment = require("moment");
const helpers = require("../global-setup");
const path = require("path");
const fs = require("fs");
const { generateWeather, generateWeatherForecast } = require("./mocks");
describe("Weather module", function () {
/**
*
* @param {string} element css selector
* @returns {Promise<Element>} Promise with the element once it is rendered
*/
function getElement(element) {
const elem = document.querySelector(element);
expect(elem).not.toBe(null);
return elem;
}
/**
* @param {string} element css selector
* @param {string} result Expected text in given selector
*/
function getText(element, result) {
const elem = getElement(element);
expect(
elem.textContent
.trim()
.replace(/(\r\n|\n|\r)/gm, "")
.replace(/[ ]+/g, " ")
).toBe(result);
}
/**
* @param {string} configFile path to configuration file
* @param {string} additionalMockData special data for mocking
* @param {string} callback callback
*/
function startApp(configFile, additionalMockData, callback) {
let mockWeather;
if (configFile.includes("forecast")) {
mockWeather = generateWeatherForecast(additionalMockData);
} else {
mockWeather = generateWeather(additionalMockData);
}
let content = fs.readFileSync(path.resolve(__dirname + "../../../../" + configFile)).toString();
content = content.replace("#####WEATHERDATA#####", mockWeather);
fs.writeFileSync(path.resolve(__dirname + "../../../../config/config.js"), content);
helpers.startApplication("");
helpers.getDocument(callback, 3000);
}
afterAll(function () {
helpers.stopApplication();
});
describe("Current weather", function () {
describe("Default configuration", function () {
beforeAll(function (done) {
startApp("tests/configs/modules/weather/currentweather_default.js", {}, done);
});
it("should render wind speed and wind direction", function () {
getText(".weather .normal.medium span:nth-child(2)", "6 WSW");
});
it("should render temperature with icon", function () {
getText(".weather .large.light span.bright", "1.5°");
});
it("should render feels like temperature", function () {
getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -5.6°");
});
});
describe("Default configuration with sunrise", function () {
beforeAll(function (done) {
const sunrise = moment().startOf("day").unix();
const sunset = moment().startOf("day").unix();
startApp("tests/configs/modules/weather/currentweather_default.js", { sys: { sunrise, sunset } }, done);
});
it("should render sunrise", function () {
getText(".weather .normal.medium span:nth-child(4)", "12:00 am");
});
});
describe("Default configuration with sunset", function () {
beforeAll(function (done) {
const sunrise = moment().startOf("day").unix();
const sunset = moment().endOf("day").unix();
startApp("tests/configs/modules/weather/currentweather_default.js", { sys: { sunrise, sunset } }, done);
});
it("should render sunset", function () {
getText(".weather .normal.medium span:nth-child(4)", "11:59 pm");
});
});
});
describe("Compliments Integration", function () {
beforeAll(function (done) {
startApp("tests/configs/modules/weather/currentweather_compliments.js", {}, done);
});
it("should render a compliment based on the current weather", function () {
getText(".compliments .module-content span", "snow");
});
});
describe("Configuration Options", function () {
beforeAll(function (done) {
startApp("tests/configs/modules/weather/currentweather_options.js", {}, done);
});
it("should render useBeaufort = false", function () {
getText(".weather .normal.medium span:nth-child(2)", "12");
});
it("should render showWindDirectionAsArrow = true", function () {
const elem = getElement(".weather .normal.medium sup i.fa-long-arrow-up");
expect(elem.outerHTML).toContain("transform:rotate(250deg);");
});
it("should render showHumidity = true", function () {
getText(".weather .normal.medium span:nth-child(3)", "93.7");
});
it("should render degreeLabel = true", function () {
getText(".weather .large.light span.bright", "1°C");
getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -6°C");
});
});
describe("Current weather units", function () {
beforeAll(function (done) {
startApp(
"tests/configs/modules/weather/currentweather_units.js",
{
main: {
temp: (1.49 * 9) / 5 + 32,
temp_min: (1 * 9) / 5 + 32,
temp_max: (2 * 9) / 5 + 32
},
wind: {
speed: 11.8 * 2.23694
}
},
done
);
});
it("should render imperial units", function () {
getText(".weather .normal.medium span:nth-child(2)", "6 WSW");
getText(".weather .large.light span.bright", "34,7°");
getText(".weather .normal.medium.feelslike span.dimmed", "Feels like 22,0°");
});
it("should render custom decimalSymbol = ','", function () {
getText(".weather .normal.medium span:nth-child(3)", "93,7");
getText(".weather .large.light span.bright", "34,7°");
getText(".weather .normal.medium.feelslike span.dimmed", "Feels like 22,0°");
});
});
describe("Weather Forecast", function () {
describe("Default configuration", function () {
beforeAll(function (done) {
startApp("tests/configs/modules/weather/forecastweather_default.js", {}, done);
});
it("should render days", function () {
const days = ["Today", "Tomorrow", "Sun", "Mon", "Tue"];
for (const [index, day] of days.entries()) {
getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day);
}
});
it("should render icons", function () {
const icons = ["day-cloudy", "rain", "day-sunny", "day-sunny", "day-sunny"];
for (const [index, icon] of icons.entries()) {
getElement(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(2) span.wi-${icon}`);
}
});
it("should render max temperatures", function () {
const temperatures = ["24.4°", "21.0°", "22.9°", "23.4°", "20.6°"];
for (const [index, temp] of temperatures.entries()) {
getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp);
}
});
it("should render min temperatures", function () {
const temperatures = ["15.3°", "13.6°", "13.8°", "13.9°", "10.9°"];
for (const [index, temp] of temperatures.entries()) {
getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(4)`, temp);
}
});
it("should render fading of rows", function () {
const opacities = [1, 1, 0.8, 0.5333333333333333, 0.2666666666666667];
for (const [index, opacity] of opacities.entries()) {
const elem = getElement(`.weather table.small tr:nth-child(${index + 1})`);
expect(elem.outerHTML).toContain(`<tr style="opacity: ${opacity};">`);
}
});
});
describe("Configuration Options", function () {
beforeAll(function (done) {
startApp("tests/configs/modules/weather/forecastweather_options.js", {}, done);
});
it("should render custom table class", function () {
getElement(".weather table.myTableClass");
});
it("should render colored rows", function () {
const table = getElement(".weather table.myTableClass");
expect(table.rows).not.toBe(null);
expect(table.rows.length).toBe(5);
});
});
describe("Forecast weather units", function () {
beforeAll(function (done) {
startApp("tests/configs/modules/weather/forecastweather_units.js", {}, done);
});
it("should render custom decimalSymbol = '_'", function () {
const temperatures = ["24_4°", "21_0°", "22_9°", "23_4°", "20_6°"];
for (const [index, temp] of temperatures.entries()) {
getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp);
}
});
});
});
});

View File

@ -1,309 +0,0 @@
const fs = require("fs");
const moment = require("moment");
const path = require("path");
const wdajaxstub = require("webdriverajaxstub");
const helpers = require("../global-setup");
const { generateWeather, generateWeatherForecast } = require("./mocks");
describe("Weather module", function () {
let app;
helpers.setupTimeout(this);
/**
*
* @param {object} responses mocked data to be returned
* @returns {Promise} Resolved once the electron app is started
*/
async function setup(responses) {
app = await helpers.startApplication({
args: ["js/electron.js"],
waitTimeout: 100000
});
wdajaxstub.init(app.client, responses);
app.client.setupStub();
}
/**
*
* @param {string} element css selector
* @returns {Promise<Element>} Promise with the element once it is rendered
*/
async function getElement(element) {
return await app.client.$(element);
}
/**
* @param {string} element css selector
* @param {string} result Expected text in given selector
* @returns {Promise<boolean>} Promise with True if the text matches
*/
async function getText(element, result) {
const elem = await getElement(element);
return await elem.getText(element).then(function (text) {
expect(text.trim()).toBe(result);
});
}
afterEach(function () {
return helpers.stopApplication(app);
});
describe("Current weather", function () {
let template;
beforeAll(function () {
template = fs.readFileSync(path.join(__dirname, "..", "..", "..", "modules", "default", "weather", "current.njk"), "utf8");
});
describe("Default configuration", function () {
beforeAll(function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/currentweather_default.js";
});
it("should render wind speed and wind direction", async function () {
const weather = generateWeather();
await setup({ template, data: weather });
return getText(".weather .normal.medium span:nth-child(2)", "6 WSW");
});
it("should render sunrise", async function () {
const sunrise = moment().startOf("day").unix();
const sunset = moment().startOf("day").unix();
const weather = generateWeather({ sys: { sunrise, sunset } });
await setup({ template, data: weather });
return getText(".weather .normal.medium span:nth-child(4)", "12:00 am");
});
it("should render sunset", async function () {
const sunrise = moment().startOf("day").unix();
const sunset = moment().endOf("day").unix();
const weather = generateWeather({ sys: { sunrise, sunset } });
await setup({ template, data: weather });
return getText(".weather .normal.medium span:nth-child(4)", "11:59 pm");
});
it("should render temperature with icon", async function () {
const weather = generateWeather();
await setup({ template, data: weather });
return getText(".weather .large.light span.bright", "1.5°");
});
it("should render feels like temperature", async function () {
const weather = generateWeather();
await setup({ template, data: weather });
return getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -5.6°");
});
});
describe("Compliments Integration", function () {
beforeAll(function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/currentweather_compliments.js";
});
it("should render a compliment based on the current weather", async function () {
const weather = generateWeather();
await setup({ template, data: weather });
return app.client.waitUntilTextExists(".compliments .module-content span", "snow");
});
});
describe("Configuration Options", function () {
beforeAll(function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/currentweather_options.js";
});
it("should render useBeaufort = false", async function () {
const weather = generateWeather();
await setup({ template, data: weather });
return getText(".weather .normal.medium span:nth-child(2)", "12");
});
it("should render showWindDirectionAsArrow = true", async function () {
const weather = generateWeather();
await setup({ template, data: weather });
const elem = await getElement(".weather .normal.medium sup i.fa-long-arrow-up");
return elem.getHTML(".weather .normal.medium sup i.fa-long-arrow-up").then(function (text) {
expect(text).toContain("transform:rotate(250deg);");
});
});
it("should render showHumidity = true", async function () {
const weather = generateWeather();
await setup({ template, data: weather });
return getText(".weather .normal.medium span:nth-child(3)", "93.7");
});
it("should render degreeLabel = true", async function () {
const weather = generateWeather();
await setup({ template, data: weather });
return (await getText(".weather .large.light span.bright", "1°C")) && (await getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -6°C"));
});
});
describe("Current weather units", function () {
beforeAll(function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/currentweather_units.js";
});
it("should render imperial units", async function () {
const weather = generateWeather({
main: {
temp: (1.49 * 9) / 5 + 32,
temp_min: (1 * 9) / 5 + 32,
temp_max: (2 * 9) / 5 + 32
},
wind: {
speed: 11.8 * 2.23694
}
});
await setup({ template, data: weather });
return (await getText(".weather .normal.medium span:nth-child(2)", "6 WSW")) && (await getText(".weather .large.light span.bright", "34,7°")) && getText(".weather .normal.medium.feelslike span.dimmed", "Feels like 22,0°");
});
it("should render custom decimalSymbol = ','", async function () {
const weather = generateWeather({
main: {
temp: (1.49 * 9) / 5 + 32,
temp_min: (1 * 9) / 5 + 32,
temp_max: (2 * 9) / 5 + 32
},
wind: {
speed: 11.8 * 2.23694
}
});
await setup({ template, data: weather });
return (await getText(".weather .normal.medium span:nth-child(3)", "93,7")) && (await getText(".weather .large.light span.bright", "34,7°")) && getText(".weather .normal.medium.feelslike span.dimmed", "Feels like 22,0°");
});
});
});
describe("Weather Forecast", function () {
let template;
beforeAll(function () {
template = fs.readFileSync(path.join(__dirname, "..", "..", "..", "modules", "default", "weather", "forecast.njk"), "utf8");
});
describe("Default configuration", function () {
beforeAll(function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/forecastweather_default.js";
});
it("should render days", async function () {
const weather = generateWeatherForecast();
await setup({ template, data: weather });
const days = ["Today", "Tomorrow", "Sun", "Mon", "Tue"];
for (const [index, day] of days.entries()) {
await getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day);
}
});
it("should render icons", async function () {
const weather = generateWeatherForecast();
await setup({ template, data: weather });
const icons = ["day-cloudy", "rain", "day-sunny", "day-sunny", "day-sunny"];
for (const [index, icon] of icons.entries()) {
await getElement(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(2) span.wi-${icon}`);
}
});
it("should render max temperatures", async function () {
const weather = generateWeatherForecast();
await setup({ template, data: weather });
const temperatures = ["24.4°", "21.0°", "22.9°", "23.4°", "20.6°"];
for (const [index, temp] of temperatures.entries()) {
await getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp);
}
});
it("should render min temperatures", async function () {
const weather = generateWeatherForecast();
await setup({ template, data: weather });
const temperatures = ["15.3°", "13.6°", "13.8°", "13.9°", "10.9°"];
for (const [index, temp] of temperatures.entries()) {
await getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(4)`, temp);
}
});
it("should render fading of rows", async function () {
const weather = generateWeatherForecast();
await setup({ template, data: weather });
const opacities = [1, 1, 0.8, 0.5333333333333333, 0.2666666666666667];
const elem = await getElement(".weather table.small");
for (const [index, opacity] of opacities.entries()) {
const html = await elem.getHTML(`.weather table.small tr:nth-child(${index + 1})`);
expect(html).toContain(`<tr style="opacity: ${opacity};">`);
}
});
});
describe("Configuration Options", function () {
beforeAll(function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/forecastweather_options.js";
});
it("should render custom table class", async function () {
const weather = generateWeatherForecast();
await setup({ template, data: weather });
await getElement(".weather table.myTableClass");
});
it("should render colored rows", async function () {
const weather = generateWeatherForecast();
await setup({ template, data: weather });
const rows = await app.client.$$(".weather table.myTableClass tr.colored");
expect(rows.length).toBe(5);
});
});
describe("Forecast weather units", function () {
beforeAll(function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/forecastweather_units.js";
});
it("should render custom decimalSymbol = '_'", async function () {
const weather = generateWeatherForecast();
await setup({ template, data: weather });
const temperatures = ["24_4°", "21_0°", "22_9°", "23_4°", "20_6°"];
for (const [index, temp] of temperatures.entries()) {
await getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp);
}
});
});
});
});

View File

@ -1,33 +0,0 @@
function plugin (wdInstance, requests) {
if (typeof wdInstance.addCommand !== "function") {
throw new Error("You can't use WebdriverAjaxStub with this version of WebdriverIO");
}
function stub({template, data}, done) {
window.XMLHttpRequest = function () {
this.open = function (method, url) {
this.method = method;
this.url = url;
};
this.send = function () {
this.status = 200;
this.readyState = 4;
const response = this.url.includes(".njk") ? template : data;
this.response = response;
this.responseText = response;
this.onreadystatechange();
};
return this;
};
done();
}
wdInstance.addCommand("setupStub", function() {
return wdInstance.executeAsync(stub, requests);
});
}
module.exports.init = plugin;