forked from MagicMirrorOrg/MagicMirror
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcalendar_spec.js
More file actions
430 lines (383 loc) · 20.3 KB
/
Copy pathcalendar_spec.js
File metadata and controls
430 lines (383 loc) · 20.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
const helpers = require("../helpers/global-setup");
describe("Calendar module", () => {
/**
* move similar tests in function doTest
* @param {string} cssClass css selector
* @returns {boolean} result
*/
const doTest = async (cssClass) => {
const elem = await helpers.getElement(`.calendar .module-content .event${cssClass}`);
await expect(elem.isVisible()).resolves.toBe(true);
return true;
};
const doTestCount = async (locator = ".calendar .event") => {
expect(global.page).not.toBeNull();
const loc = await global.page.locator(locator);
const elem = loc.first();
await elem.waitFor();
expect(elem).not.toBeNull();
return await loc.count();
};
const first = 0;
const second = 1;
const third = 2;
const last = -1;
// get results of table row and column, can select specific row of results,
// row is 0 based index -1 is last, 0 is first... need 10th(human count), use 9 as row
// uses playwright nth locator syntax
const doTestTableContent = async (table_row, table_column, content, row = first) => {
const elem = await global.page.locator(table_row);
const column = await elem.locator(table_column).locator(`nth=${row}`);
await expect(column.textContent()).resolves.toContain(content);
return true;
};
const defaultCalendarNow = "08 Oct 2024 12:30:00 GMT-07:00";
const defaultCalendarTimeZone = "America/Chicago";
const showEndConfigPath = "tests/configs/modules/calendar/calendarShowEndConfigs.js";
const startCalendarShowEndScenario = async (scenario, now = defaultCalendarNow, timeZone = defaultCalendarTimeZone) => {
process.env.MM_CALENDAR_SHOWEND_SCENARIO = scenario;
await helpers.startApplication(showEndConfigPath, now, [], timeZone);
};
const expectFirstEventTimeCell = async ({ scenario, expectedTime, now = defaultCalendarNow, timeZone = defaultCalendarTimeZone }) => {
await startCalendarShowEndScenario(scenario, now, timeZone);
await expect(doTestTableContent(".calendar .event", ".time", expectedTime, first)).resolves.toBe(true);
};
const getFirstEventTimeText = async () => {
const timeCell = global.page.locator(".calendar .event .time").locator(`nth=${first}`);
await timeCell.waitFor({ state: "visible" });
return (await timeCell.textContent()) || "";
};
afterEach(async () => {
await helpers.stopApplication();
delete process.env.MM_CALENDAR_SHOWEND_SCENARIO;
});
describe("Test css classes", () => {
it("has css class dayBeforeYesterday", async () => {
await helpers.startApplication("tests/configs/modules/calendar/custom.js", "03 Jan 2030 12:30:00 GMT");
await expect(doTest(".dayBeforeYesterday")).resolves.toBe(true);
});
it("has css class yesterday", async () => {
await helpers.startApplication("tests/configs/modules/calendar/custom.js", "02 Jan 2030 12:30:00 GMT");
await expect(doTest(".yesterday")).resolves.toBe(true);
});
it("has css class today", async () => {
await helpers.startApplication("tests/configs/modules/calendar/custom.js", "01 Jan 2030 12:30:00 GMT");
await expect(doTest(".today")).resolves.toBe(true);
});
it("has css class tomorrow", async () => {
await helpers.startApplication("tests/configs/modules/calendar/custom.js", "31 Dec 2029 12:30:00 GMT");
await expect(doTest(".tomorrow")).resolves.toBe(true);
});
it("has css class dayAfterTomorrow", async () => {
await helpers.startApplication("tests/configs/modules/calendar/custom.js", "30 Dec 2029 12:30:00 GMT");
await expect(doTest(".dayAfterTomorrow")).resolves.toBe(true);
});
});
describe("Events from multiple calendars", () => {
it("should show multiple events with the same title and start time from different calendars", async () => {
await helpers.startApplication("tests/configs/modules/calendar/show-duplicates-in-calendar.js", "15 Sep 2024 12:30:00 GMT");
await expect(doTestCount()).resolves.toBe(20);
});
});
/*
* RRULE TESTS:
* Add any tests that check rrule functionality here.
*/
describe("rrule", () => {
it("Issue #3393 recurrence dates past rrule until date", async () => {
await helpers.startApplication("tests/configs/modules/calendar/rrule_until.js", "07 Mar 2024 10:38:00 GMT-07:00", [], "America/Los_Angeles");
await expect(doTestCount()).resolves.toBe(1);
});
it("Issue #3781 recurrence rrule until with date only uses timezone offset incorrectly", async () => {
await helpers.startApplication("tests/configs/modules/calendar/fullday_until.js", "01 May 2025", [], "America/Los_Angeles");
await expect(doTestCount()).resolves.toBe(1);
});
});
/*
* LOS ANGELES TESTS:
* In 2023, DST (GMT-7) was until 5 Nov, after which is standard (STD) (GMT-8) time.
* Test takes place on Thu 19 Oct, recurring event on a Wednesday. maximumNumberOfDays=28, so there should be
* 4 events (25 Oct, 1 Nov, (switch to STD), 8 Nov, Nov 15), but 1 Nov and 8 Nov are excluded.
* There are three separate tests:
* * before midnight GMT (3pm local time)
* * at midnight GMT in STD time (4pm local time)
* * at midnight GMT in DST time (5pm local time)
*/
describe("Exdate: LA crossover DST before midnight GMT", () => {
it("LA crossover DST before midnight GMT should have 2 events", async () => {
await helpers.startApplication("tests/configs/modules/calendar/exdate_la_before_midnight.js", "19 Oct 2023 12:30:00 GMT-07:00", [], "America/Los_Angeles");
await expect(doTestCount()).resolves.toBe(2);
});
});
describe("Exdate: LA crossover DST at midnight GMT local STD", () => {
it("LA crossover DST before midnight GMT should have 2 events", async () => {
await helpers.startApplication("tests/configs/modules/calendar/exdate_la_at_midnight_std.js", "19 Oct 2023 12:30:00 GMT-07:00", [], "America/Los_Angeles");
await expect(doTestCount()).resolves.toBe(2);
});
});
describe("Exdate: LA crossover DST at midnight GMT local DST", () => {
it("LA crossover DST before midnight GMT should have 2 events", async () => {
await helpers.startApplication("tests/configs/modules/calendar/exdate_la_at_midnight_dst.js", "19 Oct 2023 12:30:00 GMT-07:00", [], "America/Los_Angeles");
await expect(doTestCount()).resolves.toBe(2);
});
});
/*
* SYDNEY TESTS:
* In 2023, standard time (STD) (GMT+10) was until 1 Oct, after which is DST (GMT+11).
* Test takes place on Thu 14 Sep, recurring event on a Wednesday. maximumNumberOfDays=28, so there should be
* 4 events (20 Sep, 27 Sep, (switch to DST), 4 Oct, 11 Oct), but 27 Sep and 4 Oct are excluded.
* There are three separate tests:
* * before midnight GMT (9am local time)
* * at midnight GMT in STD time (10am local time)
* * at midnight GMT in DST time (11am local time)
*/
describe("Exdate: SYD crossover DST before midnight GMT", () => {
it("LA crossover DST before midnight GMT should have 2 events", async () => {
await helpers.startApplication("tests/configs/modules/calendar/exdate_syd_before_midnight.js", "14 Sep 2023 12:30:00 GMT+10:00", [], "Australia/Sydney");
await expect(doTestCount()).resolves.toBe(2);
});
});
describe("Exdate: SYD crossover DST at midnight GMT local STD", () => {
it("LA crossover DST before midnight GMT should have 2 events", async () => {
await helpers.startApplication("tests/configs/modules/calendar/exdate_syd_at_midnight_std.js", "14 Sep 2023 12:30:00 GMT+10:00", [], "Australia/Sydney");
await expect(doTestCount()).resolves.toBe(2);
});
});
describe("Exdate: SYD crossover DST at midnight GMT local DST", () => {
it("SYD crossover DST at midnight GMT local DST should have 2 events", async () => {
await helpers.startApplication("tests/configs/modules/calendar/exdate_syd_at_midnight_dst.js", "14 Sep 2023 12:30:00 GMT+10:00", [], "Australia/Sydney");
await expect(doTestCount()).resolves.toBe(2);
});
});
/*
* RRULE TESTS:
* Add any tests that check rrule functionality here.
*/
describe("sliceMultiDayEvents direct count", () => {
it("Issue #3452 split multiday in Europe", async () => {
await helpers.startApplication("tests/configs/modules/calendar/sliceMultiDayEvents.js", "01 Sept 2024 10:38:00 GMT+02:00", [], "Europe/Berlin");
await expect(doTestCount()).resolves.toBe(6);
});
});
describe("sliceMultiDayEvents slice start time", () => {
it("sliced sub-events start at 00:00, not 23:59", async () => {
// Timed event Fri 25 Oct 12:00 -> Mon 28 Oct 08:00 (UTC) is sliced across
// several midnights. Every slice after the first must start at 00:00 of its
// day. Regression for the bug where they started at 23:59 instead.
await startCalendarShowEndScenario("slice_multiday_timed_start_midnight", "25 Oct 2024 06:00:00 GMT", "GMT");
const firstTimeCell = global.page.locator(".calendar .event .time").locator(`nth=${first}`);
await firstTimeCell.waitFor({ state: "visible" });
const times = await global.page.locator(".calendar .event .time").allTextContents();
expect(times.some((time) => time.includes("00:00"))).toBe(true);
expect(times.every((time) => !time.includes("23:59"))).toBe(true);
});
});
describe("germany timezone", () => {
it("Issue #unknown fullday timezone East of UTC edge", async () => {
await helpers.startApplication("tests/configs/modules/calendar/germany_at_end_of_day_repeating.js", "01 Oct 2024 10:38:00 GMT+02:00", [], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "Oct 22nd, 23:00", first)).resolves.toBe(true);
});
});
describe("germany all day repeating moved (recurrence and exdate)", () => {
it("Issue #unknown fullday timezone East of UTC event moved", async () => {
await helpers.startApplication("tests/configs/modules/calendar/3_move_first_allday_repeating_event.js", "01 Oct 2024 10:38:00 GMT+02:00", [], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "12th.Oct")).resolves.toBe(true);
});
});
describe("chicago late in timezone", () => {
it("Issue #unknown rrule US close to timezone edge", async () => {
await helpers.startApplication("tests/configs/modules/calendar/chicago_late_in_timezone.js", "01 Sept 2024 10:38:00 GMT-5:00", [], "America/Chicago");
await expect(doTestTableContent(".calendar .event", ".time", "10th.Sep, 20:15")).resolves.toBe(true);
});
});
describe("berlin late in day event moved, viewed from berlin", () => {
it("Issue #unknown rrule ETC+2 close to timezone edge", async () => {
await helpers.startApplication("tests/configs/modules/calendar/end_of_day_berlin_moved.js", "08 Oct 2024 12:30:00 GMT+02:00", [], "Europe/Berlin");
await expect(doTestCount()).resolves.toBe(3);
await expect(doTestTableContent(".calendar .event", ".time", "22nd.Oct, 23:00-00:00", first)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "23rd.Oct, 23:00-00:00", second)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "24th.Oct, 23:00-00:00", third)).resolves.toBe(true);
});
});
describe("berlin late in day event moved, viewed from sydney", () => {
it("Issue #unknown rrule ETC+2 close to timezone edge", async () => {
await helpers.startApplication("tests/configs/modules/calendar/end_of_day_berlin_moved.js", "08 Oct 2024 12:30:00 GMT+02:00", [], "Australia/Sydney");
await expect(doTestCount()).resolves.toBe(3);
await expect(doTestTableContent(".calendar .event", ".time", "23rd.Oct, 08:00-09:00", first)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "24th.Oct, 08:00-09:00", second)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "25th.Oct, 08:00-09:00", third)).resolves.toBe(true);
});
});
describe("berlin late in day event moved, viewed from chicago", () => {
it("Issue #unknown rrule ETC+2 close to timezone edge", async () => {
await helpers.startApplication("tests/configs/modules/calendar/end_of_day_berlin_moved.js", "08 Oct 2024 12:30:00 GMT+02:00", [], "America/Chicago");
await expect(doTestCount()).resolves.toBe(3);
await expect(doTestTableContent(".calendar .event", ".time", "22nd.Oct, 16:00-17:00", first)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "23rd.Oct, 16:00-17:00", second)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "24th.Oct, 16:00-17:00", third)).resolves.toBe(true);
});
});
describe("berlin multi-events inside offset", () => {
it("some events before DST. some after midnight", async () => {
await helpers.startApplication("tests/configs/modules/calendar/berlin_multi.js", "08 Oct 2024 12:30:00 GMT+02:00", [], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "30th.Oct, 00:00-01:00", last)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "21st.Oct, 00:00-01:00", first)).resolves.toBe(true);
});
});
describe("berlin whole day repeating, start moved after end", () => {
it("some events before DST. some after", async () => {
await helpers.startApplication("tests/configs/modules/calendar/berlin_whole_day_event_moved_over_dst_change.js", "08 Oct 2024 12:30:00 GMT+02:00", [], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "30th.Oct", last)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "27th.Oct", first)).resolves.toBe(true);
});
});
describe("berlin 11pm-midnight", () => {
it("right inside the offset, before midnight", async () => {
await helpers.startApplication("tests/configs/modules/calendar/berlin_end_of_day_repeating.js", "08 Oct 2024 12:30:00 GMT+02:00", [], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "24th.Oct, 23:00-00:00", last)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "22nd.Oct, 23:00-00:00", first)).resolves.toBe(true);
});
});
describe("both moved and delete events in recurring list", () => {
it("with moved before and after original", async () => {
await helpers.startApplication("tests/configs/modules/calendar/exdate_and_recurrence_together.js", "08 Oct 2024 12:30:00 GMT-07:00", [], "America/Los_Angeles");
// moved after end at oct 26
await expect(doTestTableContent(".calendar .event", ".time", "27th.Oct, 14:30-15:30", last)).resolves.toBe(true);
// moved before start at oct 23
await expect(doTestTableContent(".calendar .event", ".time", "22nd.Oct, 14:30-15:30", first)).resolves.toBe(true);
// remaining original 4th, now 3rd
await expect(doTestTableContent(".calendar .event", ".time", "26th.Oct, 14:30-15:30", second)).resolves.toBe(true);
});
});
describe("one event diff tz", () => {
it("start/end in diff timezones", async () => {
await helpers.startApplication("tests/configs/modules/calendar/diff_tz_start_end.js", "08 Oct 2024 12:30:00 GMT-07:00", [], "America/Chicago");
// just
await expect(doTestTableContent(".calendar .event", ".time", "29th.Oct, 05:00-30th.Oct, 18:00", first)).resolves.toBe(true);
});
it("viewing from further west in diff timezones", async () => {
await helpers.startApplication("tests/configs/modules/calendar/chicago-looking-at-ny-recurring.js", "22 Jan 2025 14:30:00 GMT-06:00", [], "America/Chicago");
// just
await expect(doTestTableContent(".calendar .event", ".time", "22nd.Jan, 17:30-19:30", first)).resolves.toBe(true);
});
});
describe("one event non repeating", () => {
it("fullday non-repeating", async () => {
await helpers.startApplication("tests/configs/modules/calendar/fullday_event_over_multiple_days_nonrepeating.js", "08 Oct 2024 12:30:00 GMT-07:00", [], "America/Chicago");
// just
await expect(doTestTableContent(".calendar .event", ".time", "25th.Oct-30th.Oct", first)).resolves.toBe(true);
});
});
describe("one event no end display", () => {
it("don't display end", async () => {
await startCalendarShowEndScenario("event_with_time_over_multiple_days_non_repeating_no_display_end");
// just
await expect(doTestTableContent(".calendar .event", ".time", "25th.Oct, 20:00", first)).resolves.toBe(true);
});
});
describe("display end display end", () => {
it("display end", async () => {
await startCalendarShowEndScenario("event_with_time_over_multiple_days_non_repeating_display_end");
// just
await expect(doTestTableContent(".calendar .event", ".time", "25th.Oct, 20:00-26th.Oct, 06:00", first)).resolves.toBe(true);
});
});
describe("showEnd for timed multi-day events", () => {
const timedMultiDayCases = [
{
name: "relative timeFormat shows start and end for timed multi-day events",
scenario: "event_with_time_over_multiple_days_non_repeating_display_end_relative",
expectedTime: "25th.Oct, 20:00-26th.Oct, 06:00"
},
{
name: "dateheaders timeFormat shows end for timed multi-day events",
scenario: "event_with_time_over_multiple_days_non_repeating_display_end_dateheaders",
expectedTime: "20:00-06:00"
}
];
it.each(timedMultiDayCases)("$name", async (testCase) => {
expect.hasAssertions();
await expectFirstEventTimeCell(testCase);
});
});
describe("showEnd for timed same-day events", () => {
const timedSameDaySimpleCases = [
{
name: "absolute timeFormat shows start and end time without repeating date",
scenario: "event_with_time_same_day_yearly_display_end_absolute",
expectedTime: "25th.Oct, 20:00-22:00"
},
{
name: "absolute timeFormat with time in dateFormat does not duplicate start time",
scenario: "event_with_time_same_day_yearly_display_end_absolute_dateformat_with_time",
expectedTime: "25th.Oct, 20:00-22:00"
},
{
name: "relative timeFormat shows start and end time without repeating date",
scenario: "event_with_time_same_day_yearly_display_end_relative",
expectedTime: "25th.Oct, 20:00-22:00"
},
{
name: "dateheaders timeFormat shows start and end time only",
scenario: "event_with_time_same_day_yearly_display_end_dateheaders",
expectedTime: "20:00-22:00"
}
];
it.each(timedSameDaySimpleCases)("$name", async (testCase) => {
expect.hasAssertions();
await expectFirstEventTimeCell(testCase);
});
it("absolute timeFormat with dateFormat LLL does not duplicate start time", async () => {
await startCalendarShowEndScenario("event_with_time_same_day_yearly_display_end_absolute_dateformat_lll");
const timeText = await getFirstEventTimeText();
const timeTokens = timeText.match(/\d{1,2}:\d{2}(?:\s?[AP]M)?/gi) || [];
expect(timeTokens).toHaveLength(2);
expect(timeText).toContain("-");
});
it("relative timeFormat with hideTime does not show start or end times", async () => {
await startCalendarShowEndScenario("event_with_time_same_day_yearly_display_end_relative_hide_time");
const timeText = await getFirstEventTimeText();
expect(timeText).toContain("25th.Oct");
expect(timeText.match(/\d{1,2}:\d{2}(?:\s?[AP]M)?/gi) || []).toHaveLength(0);
});
});
describe("count and check symbols", () => {
it("in array", async () => {
await helpers.startApplication("tests/configs/modules/calendar/symboltest.js", "08 Oct 2024 12:30:00 GMT-07:00", [], "America/Chicago");
// just
await expect(doTestCount(".calendar .event .symbol .fa-fw")).resolves.toBe(2);
await expect(doTestCount(".calendar .event .symbol .fa-calendar-check")).resolves.toBe(1);
await expect(doTestCount(".calendar .event .symbol .fa-google")).resolves.toBe(1);
});
});
describe("count events broadcast", () => {
it("get 12 with maxentries set to 1", async () => {
await helpers.startApplication("tests/configs/modules/calendar/countCalendarEvents.js", "01 Jan 2024 12:30:00 GMT-076:00", [], "America/Chicago");
await expect(doTestTableContent(".testNotification", ".elementCount", "12", first)).resolves.toBe(true);
});
});
describe("showEnd for multi-day full-day events", () => {
const fullDayShowEndCases = [
{
name: "relative timeFormat shows start and end date",
scenario: "fullday_multiday_showend_relative",
expectedTime: "25th.Oct-30th.Oct"
},
{
name: "dateheaders timeFormat shows end date in time cell",
scenario: "fullday_multiday_showend_dateheaders",
expectedTime: "-30th.Oct"
},
{
name: "absolute timeFormat with nextDaysRelative shows relative label and end date",
scenario: "fullday_multiday_showend_nextdaysrelative",
expectedTime: "Tomorrow-30th.Oct",
now: "24 Oct 2024 12:30:00 GMT-07:00"
}
];
it.each(fullDayShowEndCases)("$name", async (testCase) => {
expect.hasAssertions();
await expectFirstEventTimeCell(testCase);
});
});
});