summaryrefslogtreecommitdiffstats
path: root/comm/calendar/test/browser/views/browser_viewSwitch.js
blob: e730f3d7976d938b64338b17b9e49786cb0ca51a (plain)
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
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 * Tests that the time indicator is restarted and scroll position is restored
 * when switching tabs or views.
 */

/**
 * Wait until the view's timebar shows the given number of visible hours.
 *
 * @param {CalendarMultidayBaseView} view - The calendar view.
 * @param {number} numHours - The expected number of visible hours.
 *
 * @returns {Promise} - Promise that resolves when the timebar has numHours
 *   visible hours.
 */
function waitForVisibleHours(view, numHours) {
  // The timebar is the only scrollable child in its column (the others are
  // sticky), so the difference between the scroll area's scrollTopMax and the
  // timebar's clientHeight should give us the visible height.
  return TestUtils.waitForCondition(() => {
    let timebarHeight = view.timebar.clientHeight;
    let visiblePx = timebarHeight - view.grid.scrollTopMax;
    let expectPx = (numHours / 24) * timebarHeight;
    // Allow up to 3px difference to accommodate accumulated integer rounding
    // errors (e.g. clientHeight is a rounded integer, whilst client rectangles
    // and expectPx are floating).
    return Math.abs(visiblePx - expectPx) < 3;
  }, `${view.id} should have ${numHours} hours visible`);
}

/**
 * Wait until the view's timebar's first visible hour is the given hour.
 *
 * @param {CalendarMultidayBaseView} view - The calendar view.
 * @param {number} hour - The expected first visible hour.
 *
 * @returns {Promise} - Promise that resolves when the timebar has the given
 *   first visible hour.
 */
function waitForFirstVisibleHour(view, hour) {
  return TestUtils.waitForCondition(() => {
    let expectPx = (hour / 24) * view.timebar.clientHeight;
    let actualPx = view.grid.scrollTop;
    return Math.abs(actualPx - expectPx) < 3;
  }, `${view.id} first visible hour should be ${hour}`);
}

/**
 * Perform a scroll on the view by one hour.
 *
 * @param {CalendarMultidayBaseView} view - The calendar view to scroll.
 * @param {boolean} scrollDown - Whether to scroll down, otherwise scrolls up.
 */
async function doScroll(view, scrollDown) {
  let scrollPromise = BrowserTestUtils.waitForEvent(view.grid, "scroll");
  let viewRect = view.getBoundingClientRect();
  EventUtils.synthesizeWheel(
    view.grid,
    viewRect.width / 2,
    viewRect.height / 2,
    { deltaY: scrollDown ? 1 : -1, deltaMode: WheelEvent.DOM_DELTA_LINE },
    window
  );
  await scrollPromise;
}

add_task(async function () {
  let expectedVisibleHours = 3;
  let expectedStartHour = 3;

  let tabmail = document.getElementById("tabmail");
  Assert.equal(tabmail.tabInfo.length, 1);

  Assert.equal(Services.prefs.getIntPref("calendar.view.daystarthour"), expectedStartHour);
  Assert.equal(Services.prefs.getIntPref("calendar.view.dayendhour"), 12);
  Assert.equal(Services.prefs.getIntPref("calendar.view.visiblehours"), expectedVisibleHours);

  // Open the day view, check the display matches the prefs.

  await CalendarTestUtils.setCalendarView(window, "day");

  let dayView = document.getElementById("day-view");

  await waitForFirstVisibleHour(dayView, expectedStartHour);
  await waitForVisibleHours(dayView, expectedVisibleHours);

  // Scroll down 3 hours. We'll check this scroll position later.
  await doScroll(dayView, true);
  await waitForFirstVisibleHour(dayView, expectedStartHour + 1);

  await doScroll(dayView, true);
  await doScroll(dayView, true);
  await waitForFirstVisibleHour(dayView, expectedStartHour + 3);
  await waitForVisibleHours(dayView, expectedVisibleHours);

  // Open the week view, check the display matches the prefs.

  await CalendarTestUtils.setCalendarView(window, "week");

  let weekView = document.getElementById("week-view");

  await waitForFirstVisibleHour(weekView, expectedStartHour);
  await waitForVisibleHours(weekView, expectedVisibleHours);

  // Scroll up 1 hour.
  await doScroll(weekView, false);
  await waitForFirstVisibleHour(weekView, expectedStartHour - 1);
  await waitForVisibleHours(weekView, expectedVisibleHours);

  // Go back to the day view, check the timer and scroll position.

  await CalendarTestUtils.setCalendarView(window, "day");

  await waitForFirstVisibleHour(dayView, expectedStartHour + 3);
  await waitForVisibleHours(dayView, expectedVisibleHours);

  // Switch away from the calendar tab.

  tabmail.switchToTab(0);

  // Switch back to the calendar tab. Check scroll position.

  tabmail.switchToTab(1);
  Assert.equal(window.currentView().id, "day-view");

  await waitForFirstVisibleHour(dayView, expectedStartHour + 3);
  await waitForVisibleHours(dayView, expectedVisibleHours);

  // Go back to the week view. Check scroll position.

  await CalendarTestUtils.setCalendarView(window, "week");

  await waitForFirstVisibleHour(weekView, expectedStartHour - 1);
  await waitForVisibleHours(weekView, expectedVisibleHours);
});