MagicMirror/tests/e2e/modules/calendar_spec.js
Karsten Hassel 94c3c699e8
Release 2.29.0 (#3568)
## [2.29.0] - 2024-10-01

Thanks to: @bugsounet, @dkallen78, @jargordon, @khassel,
@KristjanESPERANTO, @MarcLandis, @rejas, @ryan-d-williams, @sdetweil,
@skpanagiotis.

> ⚠️ This release needs nodejs version `v20` or `v22`, minimum version
is `v20.9.0`

### Added

- [compliments] Added support for cron type date/time format entries mm
hh DD MM dow (minutes/hours/days/months and day of week) see
https://crontab.cronhub.io for construction (#3481)
- [core] Check config at every start of MagicMirror² (#3450)
- [core] Add spelling check (cspell): `npm run test:spelling` and handle
spelling issues (#3544)
- [core] removed `config.paths.vendor` (could not work because `vendor`
is hardcoded in `index.html`), renamed `config.paths.modules` to
`config.foreignModulesDir`, added variable `MM_CUSTOMCSS_FILE` which -
if set - overrides `config.customCss`, added variable `MM_MODULES_DIR`
which - if set - overrides `config.foreignModulesDir`, added test for
`MM_MODULES_DIR` (#3530)
- [core] elements are now removed from `index.html` when loading script
or stylesheet files fails
- [core] Added `MODULE_DOM_UPDATED` notification each time the DOM is
re-rendered via `updateDom` (#3534)
- [tests] added minimal needed node version to tests (currently v20.9.0)
to avoid releases with wrong node version info
- [tests] Added `node-libgpiod` library to electron-rebuild tests
(#3563)

### Removed

- [core] removed installer only files (#3492)
- [core] removed raspberry object from systeminformation (#3505)
- [linter] removed `eslint-plugin-import`, because it doesn't support
ESLint v9. We will reenter it later when it does.
- [tests] removed `onoff` library from electron-rebuild tests (#3563)

### Updated

- [weather] Updated `apiVersion` default from 2.5 to 3.0 (#3424)
- [core] Updated dependencies including stylistic-eslint
- [core] nail down `node-ical` version to `0.18.0` with exception
`allow-ghsas: GHSA-8hc4-vh64-cxmj` in `dep-review.yaml` (which should
removed after next `node-ical` update)
- [core] Updated SocketIO catch all to new API
- [core] Allow custom modules positions by scanning index.html for the
defined regions, instead of hard coded (PR #3518 fixes issue #3504)
- [core] Detail optimizations in `config_check.js`
- [core] Updated minimal needed node version in `package.json`
(currently v20.9.0) (#3559) and except for v21 (no security updates)
(#3561)
- [linter] Switch to ESLint v9 and flat config and replace
`eslint-plugin-unicorn` by `@eslint/js`
- [core] fix discovering module positions twice after #3450

### Fixed

- Fixed `checks` badge in README.md
- [weather] Fixed issue with the UK Met Office provider following a
change in their API paths and header info.
- [core] add check for node_helper loading for multiple instances of
same module (#3502)
- [weather] Fixed issue for respecting unit config on broadcasted
notifications
- [tests] Fixes calendar test by moving it from e2e to electron with
fixed date (#3532)
- [calendar] fixed sliceMultiDayEvents getting wrong count and
displaying incorrect entries, Europe/Berlin (#3542)
- [tests] ignore `js/positions.js` when linting (this file is created at
runtime)
- [calendar] fixed sliceMultiDayEvents showing previous day without
config enabled

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Michael Teeuw <michael@xonaymedia.nl>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ross Younger <crazyscot@gmail.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: jkriegshauser <joshuakr@nvidia.com>
Co-authored-by: illimarkangur <116028111+illimarkangur@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: vppencilsharpener <tim.pray@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: Brian O'Connor <btoconnor@users.noreply.github.com>
Co-authored-by: WallysWellies <59727507+WallysWellies@users.noreply.github.com>
Co-authored-by: Jason Stieber <jrstieber@gmail.com>
Co-authored-by: jargordon <50050429+jargordon@users.noreply.github.com>
Co-authored-by: Daniel <32464403+dkallen78@users.noreply.github.com>
Co-authored-by: Ryan Williams <65094007+ryan-d-williams@users.noreply.github.com>
Co-authored-by: Panagiotis Skias <panagiotis.skias@gmail.com>
Co-authored-by: Marc Landis <dirk.rettschlag@gmail.com>
2024-10-01 00:02:17 +02:00

203 lines
6.7 KiB
JavaScript

const helpers = require("../helpers/global-setup");
const serverBasicAuth = require("../helpers/basic-auth");
describe("Calendar module", () => {
/**
* @param {string} element css selector
* @param {string} result expected number
* @param {string} not reverse result
* @returns {boolean} result
*/
const testElementLength = async (element, result, not) => {
const elem = await helpers.waitForAllElements(element);
expect(elem).not.toBeNull();
if (not === "not") {
expect(elem).not.toHaveLength(result);
} else {
expect(elem).toHaveLength(result);
}
return true;
};
const testTextContain = async (element, text) => {
const elem = await helpers.waitForElement(element, "undefinedLoading");
expect(elem).not.toBeNull();
expect(elem.textContent).toContain(text);
return true;
};
afterAll(async () => {
await helpers.stopApplication();
});
describe("Default configuration", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/calendar/default.js");
await helpers.getDocument();
});
it("should show the default maximumEntries of 10", async () => {
await expect(testElementLength(".calendar .event", 10)).resolves.toBe(true);
});
it("should show the default calendar symbol in each event", async () => {
await expect(testElementLength(".calendar .event .fa-calendar-alt", 0, "not")).resolves.toBe(true);
});
});
describe("Custom configuration", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/calendar/custom.js");
await helpers.getDocument();
});
it("should show the custom maximumEntries of 5", async () => {
await expect(testElementLength(".calendar .event", 5)).resolves.toBe(true);
});
it("should show the custom calendar symbol in four events", async () => {
await expect(testElementLength(".calendar .event .fa-birthday-cake", 4)).resolves.toBe(true);
});
it("should show a customEvent calendar symbol in one event", async () => {
await expect(testElementLength(".calendar .event .fa-dice", 1)).resolves.toBe(true);
});
it("should show a customEvent calendar eventClass in one event", async () => {
await expect(testElementLength(".calendar .event.undo", 1)).resolves.toBe(true);
});
it("should show two custom icons for repeating events", async () => {
await expect(testElementLength(".calendar .event .fa-undo", 2)).resolves.toBe(true);
});
it("should show two custom icons for day events", async () => {
await expect(testElementLength(".calendar .event .fa-calendar-day", 2)).resolves.toBe(true);
});
});
describe("Recurring event", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/calendar/recurring.js");
await helpers.getDocument();
});
it("should show the recurring birthday event 6 times", async () => {
await expect(testElementLength(".calendar .event", 6)).resolves.toBe(true);
});
});
//Will contain everyday an fullDayEvent that starts today and ends tomorrow, and one starting tomorrow and ending the day after tomorrow
describe("FullDayEvent over several days should show how many days are left from the from the starting date on", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/calendar/long-fullday-event.js");
await helpers.getDocument();
});
it("should contain text 'Ends in' with the left days", async () => {
await expect(testTextContain(".calendar .today .time", "Ends in")).resolves.toBe(true);
await expect(testTextContain(".calendar .yesterday .time", "Today")).resolves.toBe(true);
await expect(testTextContain(".calendar .tomorrow .time", "Tomorrow")).resolves.toBe(true);
});
it("should contain in total three events", async () => {
await expect(testElementLength(".calendar .event", 3)).resolves.toBe(true);
});
});
describe("FullDayEvent Single day, should show Today", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/calendar/single-fullday-event.js");
await helpers.getDocument();
});
it("should contain text 'Today'", async () => {
await expect(testTextContain(".calendar .time", "Today")).resolves.toBe(true);
});
it("should contain in total two events", async () => {
await expect(testElementLength(".calendar .event", 2)).resolves.toBe(true);
});
});
process.setMaxListeners(0);
for (let i = -12; i < 12; i++) {
describe("Recurring event per timezone", () => {
beforeAll(async () => {
Date.prototype.getTimezoneOffset = () => {
return i * 60;
};
await helpers.startApplication("tests/configs/modules/calendar/recurring.js");
await helpers.getDocument();
});
it(`should contain text "Mar 25th" in timezone UTC ${-i}`, async () => {
await expect(testTextContain(".calendar", "Mar 25th")).resolves.toBe(true);
});
});
}
describe("Changed port", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/calendar/changed-port.js");
serverBasicAuth.listen(8010);
await helpers.getDocument();
});
afterAll(async () => {
await serverBasicAuth.close();
});
it("should return TestEvents", async () => {
await expect(testElementLength(".calendar .event", 0, "not")).resolves.toBe(true);
});
});
describe("Basic auth", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/calendar/basic-auth.js");
await helpers.getDocument();
});
it("should return TestEvents", async () => {
await expect(testElementLength(".calendar .event", 0, "not")).resolves.toBe(true);
});
});
describe("Basic auth by default", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/calendar/auth-default.js");
await helpers.getDocument();
});
it("should return TestEvents", async () => {
await expect(testElementLength(".calendar .event", 0, "not")).resolves.toBe(true);
});
});
describe("Basic auth backward compatibility configuration: DEPRECATED", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/calendar/old-basic-auth.js");
await helpers.getDocument();
});
it("should return TestEvents", async () => {
await expect(testElementLength(".calendar .event", 0, "not")).resolves.toBe(true);
});
});
describe("Fail Basic auth", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/calendar/fail-basic-auth.js");
serverBasicAuth.listen(8020);
await helpers.getDocument();
});
afterAll(async () => {
await serverBasicAuth.close();
});
it("should show Unauthorized error", async () => {
await expect(testTextContain(".calendar", "Error in the calendar module. Authorization failed")).resolves.toBe(true);
});
});
});