Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/automated-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ jobs:
timeout-minutes: 15
steps:
- name: "Checkout code"
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: "Use Node.js"
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: lts/*
cache: "npm"
Expand All @@ -38,16 +38,16 @@ jobs:
timeout-minutes: 30
strategy:
matrix:
node-version: [22.14.0, 22.x, 24.x]
node-version: [22.18.0, 22.x, 24.x]
steps:
- name: Install electron dependencies and labwc
run: |
sudo apt-get update
sudo apt-get install -y libnss3 libasound2t64 labwc
- name: "Checkout code"
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: "Use Node.js ${{ matrix.node-version }}"
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node-version }}
check-latest: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dep-review.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: "Checkout code"
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: "Dependency Review"
uses: actions/dependency-review-action@v4
6 changes: 3 additions & 3 deletions .github/workflows/electron-rebuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [22.14.0, 22.x, 24.x]
node-version: [22.18.0, 22.x, 24.x]
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: "Use Node.js ${{ matrix.node-version }}"
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node-version }}
check-latest: true
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/spellcheck.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: develop
- name: Set up Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: lts/*
check-latest: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/stale.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
stale-issue-message: "This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions."
days-before-issue-stale: 60
Expand Down
64 changes: 59 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/#donate) With your help we can continue to improve the MagicMirror².

## [2.33.0] - 2025-10-01

Thanks to: @Crazylegstoo, @dathbe, @m-idler, @plebcity, @khassel, @KristjanESPERANTO, @rejas and @sdetweil!

> ⚠️ This release needs nodejs version `v22.18.0 or higher`

### Added

- Add configuration option for `User-Agent`, used by calendar & news module (#3255)
- [linter] Add prettier plugin for nunjuck templates (#3887)
- [core] Add clear log for occupied port at startup (#3890)

### Changed

- [clock] Add CSS to prevent line breaking of sunset/sunrise time display (#3816)
- [core] Enhance system information logging format and include additional env and RAM details (#3839, #3843)
- [refactor] Add new file `js/module_functions.js` to move code used in several modules to one place (#3837)
- [refactor] Use global.root_path where possible and add tests for config:check (#3883, #3885, #3886, #3889)
- [tests] refactor: simplify jest config file (#3844)
- [tests] refactor: extract constants for weather electron tests (#3845)
- [tests] refactor: add `setupDOMEnvironment` helper function to eliminate repetitive JSDOM setup code (#3860)
- [tests] replace `console` with `Log` in calendar `debug.js` to avoid exception in eslint config (#3846)
- [tests] speed up e2e tests, cleanup and stabilize weather e2e tests, update snapshot url (#3847, #3848, #3861)
- [tests] refactor translation tests (#3866)
- Remove `sinon` dependency in favor of Jest native mocking
- Unify test helper functions across translation test suites
- Rename `setupDOMEnvironment` to `createTranslationTestEnvironment` for consistency
- Simplify DOM setup by removing unnecessary Promise/async patterns
- Avoid potential port conflicts by using port 3001 for translator unit tests
- Improve test reliability and maintainability
- [tests] add alert module tests for different welcome_message configurations (#3867)
- [lint-staged] use `prettier --write --ignore-unknown` in `lint-staged` to avoid errors on unsupported files (#3888)

### Updated

- [calendar] Update defaultSymbol name and also the link to the icon search site (#3879)
- [core] Update dependencies including electron to v38 as well as github actions (#3831, #3849, #3857, #3858, #3872, #3876, #3882, #3891, #3896)
- [weather] Update feels_like temperature calculation formula (#3869)
- [weather] Update null value handling for weather type (#3892)
- [layout] Update styles for weather and calendar (#3894)

### Fixed

- [calendar] Fixed broken unittest that only broke on the 1st of July and 1st of january (#3830)
- [clock] Fixed missing icons when no other modules with icons is loaded (#3834)
- [weather] Fixed handling of empty values in weathergov providers handling of precipitationAmount (#3859)
- [calendar] Fix regression handling of limit days (#3840)
- [calendar] Fixed regression of calendarfetcherutils.shouldEventBeExcluded (#3841)
- [core] Fixed socket.io timeout when server is slow to send notification, notification lost at client (#3380)
- [tests] refactor AnimateCSS tests after jsdom 27 upgrade (#3891)
- [weather] Use `apparent_temperature` data from openmeteo's hourly weather for current feelsLikeTemp (#3868).
- [weather] Updated envcanada Provider to use new database/URL schema for accessing weather data (#3878).

## [2.32.0] - 2025-07-01

Thanks to: @bughaver, @bugsounet, @khassel, @KristjanESPERANTO, @plebcity, @rejas, @sdetweil.
Expand Down Expand Up @@ -260,7 +313,7 @@ For more info, please read the following post: [A New Chapter for MagicMirror: T
### Added

- Output of system information to the console for troubleshooting (#3328 and #3337), ignore errors under aarch64 (#3349)
- [core] Add `eslint-plugin-package-json` to lint the `package.json` files (#3368)
- [linter] Add `eslint-plugin-package-json` to lint the `package.json` files (#3368)
- [weather] `showHumidity` config is now a string describing where to show this element. Supported values: "wind", "temp", "feelslike", "below", "none". (#3330)
- electron-rebuild test suite for electron and 3rd party modules compatibility (#3392)
- Create MM² icon and attach it to electron process (#3407)
Expand All @@ -277,7 +330,7 @@ For more info, please read the following post: [A New Chapter for MagicMirror: T
- Update translations for estonian (#3371)
- Update electron to v29 and update other dependencies
- [calendar] fullDay events over several days now show the left days from the first day on and 'today' on the last day
- Update layout of current weather indoor values
- [weather] Update layout of current weather indoor values

### Fixed

Expand Down Expand Up @@ -422,7 +475,7 @@ Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not al
- Added UV Index to hourly and current Weather, with support for Openmeteo
- Added tests for serveronly
- Set Timezone `Europe/Berlin` in unit tests (needed for new formatTime tests)
- Added no-param-reassign eslint rule and fix warnings
- [linter] Added no-param-reassign eslint rule and fix warnings
- [updatenotification] Added `sendUpdatesNotifications` feature. Broadcast update with `UPDATES` notification to other modules
- [updatenotification] Allow force scanning with `SCAN_UPDATES` notification from other modules
- Added per-calendar fetchInterval
Expand Down Expand Up @@ -687,7 +740,7 @@ Special thanks to the following contributors: @AmpioRosso, @eouia, @fewieden, @j
### Fixed

- Fixed wrong file `kr.json` to `ko.json`. Use language code 'ko' instead of 'kr' for Korean language.
- Fixed `feels_like` data from openweathermap's current weather being ignored (#2678).
- [weather] Fixed `feels_like` data from openweathermap's current weather being ignored (#2678).
- Fixed chaotic newsfeed display after network connection loss thanks to @jalibu (#2638).
- Fixed incorrect time zone correction of recurring full day events (#2632 and #2634).
- Fixed e2e tests by increasing testTimeout.
Expand Down Expand Up @@ -725,7 +778,7 @@ Special thanks to the following contributors: @apiontek, @eouia, @jupadin, @khas
- Actually test all js and css files when lint script is run.
- Updated jsdocs and print warnings during testing too.
- Updated weathergov provider to try fetching not just current, but also forecast, when API URLs available.
- Refactored clock layout.
- [clock] Refactored clock layout.
- Refactored methods from weather-providers into weatherobject (isDaytime, updateSunTime).
- Use of `logger.js` in jest tests.
- Run prettier over all relevant files.
Expand Down Expand Up @@ -1771,6 +1824,7 @@ It includes (but is not limited to) the following features:

This was part of the blogpost: [https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the](https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the)

[2.33.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.32.0...v2.33.0
[2.32.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.31.0...v2.32.0
[2.31.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.30.0...v2.31.0
[2.30.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.29.0...v2.30.0
Expand Down
2 changes: 1 addition & 1 deletion Collaboration.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Are done by
- [ ] test `prep-release` branch
- [ ] update `CHANGELOG.md`
- [ ] add all contributor names: `...`
- [ ] add min. node version: > ⚠️ This release needs nodejs version `v22.14.0` or higher
- [ ] add min. node version: > ⚠️ This release needs nodejs version `v22.18.0` or higher
- [ ] check release link at the bottom of the file
- [ ] commit and push all changes
- [ ] create pull request from `prep-release` to `develop` branch with title `Prepare Release 2.xx.0`
Expand Down
4 changes: 4 additions & 0 deletions cspell.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"browserwindow",
"bryanzzhu",
"btoconnor",
"bughaver",
"bugsounet",
"buxxi",
"byday",
Expand All @@ -44,6 +45,7 @@
"darksky",
"dateheader",
"dateheaders",
"dathbe",
"davide",
"DAYAFTERTOMORROW",
"DAYBEFOREYESTERDAY",
Expand Down Expand Up @@ -175,6 +177,7 @@
"oraclesean",
"oscarb",
"philnagel",
"plebcity",
"Português",
"PRECIP",
"Problema",
Expand Down Expand Up @@ -233,6 +236,7 @@
"Weatherflow",
"weatherforecast",
"weathergov",
"weathericon",
"weathericons",
"weatherobject",
"weatherutils",
Expand Down
12 changes: 12 additions & 0 deletions css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,15 @@ sup {
.region .container.hidden {
display: none;
}

.region.left .flex {
justify-content: flex-start;
}

.region.center .flex {
justify-content: center;
}

.region.right .flex {
justify-content: flex-end;
}
7 changes: 3 additions & 4 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import globals from "globals";
import {flatConfigs as importX} from "eslint-plugin-import-x";
import jest from "eslint-plugin-jest";
import js from "@eslint/js";
import jsdoc from "eslint-plugin-jsdoc";
import jsdocPlugin from "eslint-plugin-jsdoc";
import packageJson from "eslint-plugin-package-json";
import stylistic from "@stylistic/eslint-plugin";

Expand All @@ -23,8 +23,8 @@ export default defineConfig([
moment: "readonly"
}
},
plugins: {js, jsdoc, stylistic},
extends: [importX.recommended, jest.configs["flat/recommended"], "js/recommended", jsdoc.configs["flat/recommended"], "stylistic/all"],
plugins: {js, stylistic},
extends: [importX.recommended, jest.configs["flat/recommended"], "js/recommended", jsdocPlugin.configs["flat/recommended"], "stylistic/all"],
rules: {
"@stylistic/array-element-newline": ["error", "consistent"],
"@stylistic/arrow-parens": ["error", "always"],
Expand Down Expand Up @@ -88,7 +88,6 @@ export default defineConfig([
files: ["**/*.js"],
ignores: [
"clientonly/index.js",
"modules/default/calendar/debug.js",
"js/logger.js",
"tests/**/*.js"
],
Expand Down
65 changes: 35 additions & 30 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
module.exports = async () => {
return {
verbose: true,
testTimeout: 20000,
testSequencer: "<rootDir>/tests/utils/test_sequencer.js",
projects: [
{
displayName: "unit",
globalSetup: "<rootDir>/tests/unit/helpers/global-setup.js",
moduleNameMapper: {
logger: "<rootDir>/js/logger.js"
},
testMatch: ["**/tests/unit/**/*.[jt]s?(x)"],
testPathIgnorePatterns: ["<rootDir>/tests/unit/mocks", "<rootDir>/tests/unit/helpers"]
const config = {
verbose: true,
testTimeout: 20000,
testSequencer: "<rootDir>/tests/utils/test_sequencer.js",
projects: [
{
displayName: "unit",
globalSetup: "<rootDir>/tests/unit/helpers/global-setup.js",
moduleNameMapper: {
logger: "<rootDir>/js/logger.js"
},
{
displayName: "electron",
testMatch: ["**/tests/electron/**/*.[jt]s?(x)"],
testPathIgnorePatterns: ["<rootDir>/tests/electron/helpers"]
},
{
displayName: "e2e",
testMatch: ["**/tests/e2e/**/*.[jt]s?(x)"],
modulePaths: ["<rootDir>/js/"],
testPathIgnorePatterns: ["<rootDir>/tests/e2e/helpers", "<rootDir>/tests/e2e/mocks"]
}
],
collectCoverageFrom: ["./clientonly/**/*.js", "./js/**/*.js", "./modules/default/**/*.js", "./serveronly/**/*.js"],
coverageReporters: ["lcov", "text"],
coverageProvider: "v8"
};
testMatch: ["**/tests/unit/**/*.[jt]s?(x)"],
testPathIgnorePatterns: ["<rootDir>/tests/unit/mocks", "<rootDir>/tests/unit/helpers"]
},
{
displayName: "electron",
testMatch: ["**/tests/electron/**/*.[jt]s?(x)"],
testPathIgnorePatterns: ["<rootDir>/tests/electron/helpers"]
},
{
displayName: "e2e",
testMatch: ["**/tests/e2e/**/*.[jt]s?(x)"],
modulePaths: ["<rootDir>/js/"],
testPathIgnorePatterns: ["<rootDir>/tests/e2e/helpers", "<rootDir>/tests/e2e/mocks"]
}
],
collectCoverageFrom: [
"<rootDir>/clientonly/**/*.js",
"<rootDir>/js/**/*.js",
"<rootDir>/modules/default/**/*.js",
"<rootDir>/serveronly/**/*.js"
],
coverageReporters: ["lcov", "text"],
coverageProvider: "v8"
};

module.exports = config;
18 changes: 9 additions & 9 deletions js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ const path = require("node:path");
const envsub = require("envsub");
const Log = require("logger");

// global absolute root path
global.root_path = path.resolve(`${__dirname}/../`);

const Server = require(`${__dirname}/server`);
const Utils = require(`${__dirname}/utils`);
const defaultModules = require(`${__dirname}/../modules/default/defaultmodules`);
const { getEnvVarsAsObj } = require(`${__dirname}/server_functions`);

const defaultModules = require(`${global.root_path}/modules/default/defaultmodules`);
// used to control fetch timeout for node_helpers
const { setGlobalDispatcher, Agent } = require("undici");
const { getEnvVarsAsObj } = require("#server_functions");
// common timeout value, provide environment override in case
const fetch_timeout = process.env.mmFetchTimeout !== undefined ? process.env.mmFetchTimeout : 30000;

// Get version number.
global.version = require(`${__dirname}/../package.json`).version;
global.version = require(`${global.root_path}/package.json`).version;
global.mmTestMode = process.env.mmTestMode === "true";
Log.log(`Starting MagicMirror: v${global.version}`);

// Log system information.
Utils.logSystemInformation();

// global absolute root path
global.root_path = path.resolve(`${__dirname}/../`);
Utils.logSystemInformation(global.version);

if (process.env.MM_CONFIG_FILE) {
global.configuration_file = process.env.MM_CONFIG_FILE.replace(`${global.root_path}/`, "");
Expand Down Expand Up @@ -181,10 +181,10 @@ function App () {
const elements = module.split("/");
const moduleName = elements[elements.length - 1];
const env = getEnvVarsAsObj();
let moduleFolder = path.resolve(`${__dirname}/../${env.modulesDir}`, module);
let moduleFolder = path.resolve(`${global.root_path}/${env.modulesDir}`, module);

if (defaultModules.includes(moduleName)) {
const defaultModuleFolder = path.resolve(`${__dirname}/../modules/default/`, module);
const defaultModuleFolder = path.resolve(`${global.root_path}/modules/default/`, module);
if (process.env.JEST_WORKER_ID === undefined) {
moduleFolder = defaultModuleFolder;
} else {
Expand Down
Loading
Loading