summaryrefslogtreecommitdiffstats
path: root/toolkit/content/tests/chrome/test_datepicker.xul
blob: e7a61f43bce7ccc6bb5723521bf23534f8be5716 (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
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
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<!--
  XUL Widget Test for datepicker
  -->
<window title="datepicker" width="500" height="600"
        onload="setTimeout(testtag_datepickers, 0);"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>

<hbox onpopupshown="testtag_datepicker_UI_popup()"
      onpopuphidden="testtag_finish()">
<datepicker id="datepicker"/>
<datepicker id="datepicker-popup" type="popup"/>
<hbox onDOMMouseScroll="mouseScrolled = event.defaultPrevented;">
  <datepicker id="datepicker-grid" type="grid" value="2007-04-21"/>
</hbox>
</hbox>

<!-- Test-only key bindings, but must not conflict with the application. -->
<keyset id="mainKeyset">
  <key id="key_alt_z" key="Z" oncommand="return" modifiers="alt"/>
  <key id="key_ctrl_q" key="Q" oncommand="return" modifiers="control"/>
  <key id="key_meta_e" key="E" oncommand="return" modifiers="meta"/>
</keyset>

<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>

<script>
<![CDATA[

var mouseScrolled = false;

SimpleTest.waitForExplicitFinish();

function testtag_datepickers()
{
  var dppopup = document.getElementById("datepicker-popup");
  testtag_datepicker(document.getElementById("datepicker"), "", "datepicker");
  testtag_datepicker(dppopup, "popup", "datepicker popup");

  var gridpicker = document.getElementById("datepicker-grid");
  is(gridpicker.monthField.selectedIndex, "3", "datepicker grid correct month is initially selected");
  testtag_datepicker(gridpicker, "grid", "datepicker grid");
  dppopup.open = true;
}

function testtag_finish()
{
  ok(!document.getElementById("datepicker-popup").open, "datepicker popup open false again");

  var dpgrid = document.getElementById("datepicker-grid");
  synthesizeWheel(dpgrid, 5, 5, { deltaY: 10.0,
                                  deltaMode: WheelEvent.DOM_DELTA_LINE });
  is(mouseScrolled, true, "mouse scrolled");
  is(dpgrid.displayedMonth, 2, "mouse scroll changed month");

  SimpleTest.finish();
}

function testtag_datepicker(dp, type, testid)
{
  testid += " ";

  var today = new Date();
  var tyear = today.getFullYear();
  var tmonth = today.getMonth();
  var tdate = today.getDate();

  // testtag_comparedate(dp, testid + "initial", tyear, tmonth, tdate);

  // check that setting the value property works
  dp.value = testtag_getdatestring(tyear, tmonth, tdate);
  testtag_comparedate(dp, testid + "set value", tyear, tmonth, tdate);

  // check that setting the dateValue property works
  dp.dateValue = today;
  testtag_comparedate(dp, testid + "set dateValue", tyear, tmonth, tdate);
  ok(dp.value !== today, testid + " set dateValue different date");

  ok(!dp.readOnly, testid + "readOnly");
  dp.readOnly = true;
  ok(dp.readOnly, testid + "set readOnly");
  dp.readOnly = false;
  ok(!dp.readOnly, testid + "clear readOnly");

  var setDateField = function(field, value, expectException,
                              expectedYear, expectedMonth, expectedDate)
  {
    var exh = false;
    try {
      dp[field] = value;
    } catch (ex) { exh = true; }
    is(exh, expectException, testid + "set " + field + " " + value);
    testtag_comparedate(dp, testid + "set " + field + " " + value,
                        expectedYear, expectedMonth, expectedDate);
  }

  // check the value property
  setDateField("value", "2003-1-27", false, 2003, 0, 27);
  setDateField("value", "2002-11-8", false, 2002, 10, 8);
  setDateField("value", "2001-07-02", false, 2001, 6, 2);
  setDateField("value", "2002-10-25", false, 2002, 9, 25);

  // check that the year, month and date fields can be set properly
  setDateField("year", 2002, false, 2002, 9, 25);
  setDateField("year", 0, true, 2002, 9, 25);

  setDateField("month", 6, false, 2002, 6, 25);
  setDateField("month", 9, false, 2002, 9, 25);
  setDateField("month", 10, false, 2002, 10, 25);
  setDateField("month", -1, true, 2002, 10, 25);
  setDateField("month", 12, true, 2002, 10, 25);

  setDateField("date", 9, false, 2002, 10, 9);
  setDateField("date", 10, false, 2002, 10, 10);
  setDateField("date", 15, false, 2002, 10, 15);
  setDateField("date", 0, true, 2002, 10, 15);
  setDateField("date", 32, true, 2002, 10, 15);

  // check leap year handling
  setDateField("value", "1600-2-29", false, 1600, 1, 29);
  setDateField("value", "2000-2-29", false, 2000, 1, 29);
  setDateField("value", "2003-2-29", false, 2003, 2, 1);
  setDateField("value", "2004-2-29", false, 2004, 1, 29);
  setDateField("value", "2100-2-29", false, 2100, 2, 1);

  // check invalid values for the value and dateValue properties
  dp.value = "2002-07-15";
  setDateField("value", "", true, 2002, 6, 15);
  setDateField("value", "2-2", true, 2002, 6, 15);
  setDateField("value", "2000-5-6-6", true, 2002, 6, 15);
  setDateField("value", "2000-a-19", true, 2002, 6, 15);
  setDateField("dateValue", "none", true, 2002, 6, 15);

  // grid and popup types can display a different month than the current one
  var isGridOrPopup = (type == "grid" || type == "popup");
  dp.displayedMonth = 3;
  testtag_comparedate(dp, testid + "set displayedMonth",
                      2002, isGridOrPopup ? 6 : 3, 15, 3);

  dp.displayedYear = 2009;
  testtag_comparedate(dp, testid + "set displayedYear",
                      isGridOrPopup ? 2002 : 2009, isGridOrPopup ? 6 : 3, 15, 3, 2009);

  if (isGridOrPopup) {
    dp.value = "2008-02-29";
    dp.displayedYear = 2009;
    is(dp.displayedMonth, 1, "set displayedYear during leap year");
  }

  is(dp.open, false, testid + "open false");
  if (type != "popup") {
    dp.open = true;
    ok(!dp.open, testid + "open still false");
  }

  // check the fields
  if (type != "grid") {
    ok(dp.yearField instanceof HTMLInputElement, testid + "yearField");
    ok(dp.monthField instanceof HTMLInputElement, testid + "monthField");
    ok(dp.dateField instanceof HTMLInputElement, testid + "dateField");

    testtag_datepicker_UI_fields(dp, testid);

    dp.readOnly = true;

    // check that keyboard usage doesn't change the value when the datepicker
    // is read only
    testtag_datepicker_UI_key(dp, testid + "readonly ", "2003-01-29",
                              dp.yearField, 2003, 0, 29, 2003, 0, 29);
    testtag_datepicker_UI_key(dp, testid + "readonly ", "2003-04-29",
                              dp.monthField, 2003, 3, 29, 2003, 3, 29);
    testtag_datepicker_UI_key(dp, testid + "readonly ", "2003-06-15",
                              dp.dateField, 2003, 5, 15, 2003, 5, 15);

    dp.readOnly = false;
  }
  else {
    testtag_datepicker_UI_grid(dp, "grid", testid);
  }
}

function testtag_datepicker_UI_fields(dp, testid)
{
  testid += "UI";
  dp.focus();

  // test adjusting the date with the up and down keys
  testtag_datepicker_UI_key(dp, testid, "2003-01-29", dp.yearField, 2004, 0, 29, 2003, 0, 29);
  testtag_datepicker_UI_key(dp, testid, "1600-02-29", dp.yearField, 1601, 1, 28, 1600, 1, 28);
  testtag_datepicker_UI_key(dp, testid, "2000-02-29", dp.yearField, 2001, 1, 28, 2000, 1, 28);
  testtag_datepicker_UI_key(dp, testid, "2004-02-29", dp.yearField, 2005, 1, 28, 2004, 1, 28);

  testtag_datepicker_UI_key(dp, testid, "2003-04-29", dp.monthField, 2003, 4, 29, 2003, 3, 29);
  testtag_datepicker_UI_key(dp, testid, "2003-01-15", dp.monthField, 2003, 1, 15, 2003, 0, 15);
  testtag_datepicker_UI_key(dp, testid, "2003-12-29", dp.monthField, 2003, 0, 29, 2003, 11, 29);
  testtag_datepicker_UI_key(dp, testid, "2003-03-31", dp.monthField, 2003, 3, 30, 2003, 2, 30);

  testtag_datepicker_UI_key(dp, testid, "2003-06-15", dp.dateField, 2003, 5, 16, 2003, 5, 15);
  testtag_datepicker_UI_key(dp, testid, "2003-06-01", dp.dateField, 2003, 5, 2, 2003, 5, 1);
  testtag_datepicker_UI_key(dp, testid, "2003-06-30", dp.dateField, 2003, 5, 1, 2003, 5, 30);
  testtag_datepicker_UI_key(dp, testid, "1600-02-28", dp.dateField, 1600, 1, 29, 1600, 1, 28);
  testtag_datepicker_UI_key(dp, testid, "2000-02-28", dp.dateField, 2000, 1, 29, 2000, 1, 28);
  testtag_datepicker_UI_key(dp, testid, "2003-02-28", dp.dateField, 2003, 1, 1, 2003, 1, 28);
  testtag_datepicker_UI_key(dp, testid, "2004-02-28", dp.dateField, 2004, 1, 29, 2004, 1, 28);
  testtag_datepicker_UI_key(dp, testid, "2100-02-28", dp.dateField, 2100, 1, 1, 2100, 1, 28);

  synthesizeKeyExpectEvent('Z', { altKey: true }, $("key_alt_z"), "command", testid + " alt shortcut");
  synthesizeKeyExpectEvent('Q', { ctrlKey: true }, $("key_ctrl_q"), "command", testid + " ctrl shortcut");
  synthesizeKeyExpectEvent('E', { metaKey: true }, $("key_meta_e"), "command", testid + " meta shortcut");
}

function testtag_datepicker_UI_grid(dp, type, testid)
{
  testid += "UI ";

  // check that pressing the cursor keys moves the date properly. For grid
  // types, focus the grid first. For popup types, the grid should be focused
  // automatically when opening the popup.
  var ktarget = dp;
  if (type == "grid")
    dp.focus();
  else
    ktarget = dp.attachedControl;

  dp.value = "2003-02-22";

  synthesizeKeyExpectEvent("VK_LEFT", { }, ktarget, "change", testid + "key left");
  is(dp.value, "2003-02-21", testid + "key left");

  synthesizeKeyExpectEvent("VK_RIGHT", { }, ktarget, "change", testid + "key right");
  is(dp.value, "2003-02-22", testid + "key right");
  synthesizeKeyExpectEvent("VK_RIGHT", { }, ktarget, "change", testid + "key right next week");
  is(dp.value, "2003-02-23", testid + "key right next week");
  synthesizeKeyExpectEvent("VK_LEFT", { }, ktarget, "change", testid + "key left previous week");
  is(dp.value, "2003-02-22", testid + "key left previous week");

  synthesizeKeyExpectEvent("VK_UP", { }, ktarget, "change", testid + "key up");
  is(dp.value, "2003-02-15", testid + "key up");
  synthesizeKeyExpectEvent("VK_DOWN", { }, ktarget, "change", testid + "key down");
  is(dp.value, "2003-02-22", testid + "key down");
  synthesizeKeyExpectEvent("VK_DOWN", { }, ktarget, "change");
  is(dp.value, "2003-03-01", testid + "key down next month", testid + "key down next month");
  synthesizeKeyExpectEvent("VK_UP", { }, ktarget, "change");
  is(dp.value, "2003-02-22", testid + "key up previous month", testid + "key up previous month");

  // the displayed month may be changed with the page up and page down keys,
  // however this only changes the displayed month, not the current value.
  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down");
  is(dp.value, "2003-02-22", testid + "key page down");

  // the monthchange event is fired when the displayed month is changed
  synthesizeKeyExpectEvent("VK_UP", { }, ktarget, "monthchange", testid + "key up after month change");
  is(dp.value, "2003-02-15", testid + "key up after month change");

  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up");
  is(dp.value, "2003-02-15", testid + "key page up");

  // check handling at the start and end of the month
  dp.value = "2010-10-01";
  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up 2010-10-01");
  is(dp.displayedMonth, 8, testid + "key page up 2010-10-01 displayedMonth");
  is(dp.displayedYear, 2010, testid + "key page up 2010-10-01 displayedYear");

  dp.value = "2010-10-01";
  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down 2010-10-01");
  is(dp.displayedMonth, 10, testid + "key page down 2010-10-01 displayedMonth");
  is(dp.displayedYear, 2010, testid + "key page down 2010-10-01 displayedYear");

  dp.value = "2010-10-31";
  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up 2010-10-31");
  is(dp.displayedMonth, 8, testid + "key page up 2010-10-31 displayedMonth");
  is(dp.displayedYear, 2010, testid + "key page up 2010-10-01 displayedYear");
  dp.value = "2010-10-31";
  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down 2010-10-31");
  is(dp.displayedMonth, 10, testid + "key page down 2010-10-31 displayedMonth");
  is(dp.displayedYear, 2010, testid + "key page up 2010-10-31 displayedYear");

  // check handling at the end of february
  dp.value = "2010-03-31";
  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up 2010-03-31");
  is(dp.displayedMonth, 1, testid + "key page up 2010-03-31 displayedMonth");
  is(dp.displayedYear, 2010, testid + "key page up 2010-03-31 displayedYear");
  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up 2010-02-28");
  is(dp.displayedMonth, 0, testid + "key page up 2010-02-28 displayedMonth");
  is(dp.displayedYear, 2010, testid + "key page up 2010-02-28 displayedYear");

  dp.value = "2010-01-31";
  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down 2010-01-31");
  is(dp.displayedMonth, 1, testid + "key page down 2010-01-31 displayedMonth");
  is(dp.displayedYear, 2010, testid + "key page up 2010-01-31 displayedYear");
  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down 2010-02-28");
  is(dp.displayedMonth, 2, testid + "key page down 2010-02-28 displayedMonth");
  is(dp.displayedYear, 2010, testid + "key page up 2010-02-28 displayedYear");

  // check handling at the end of february during a leap year
  dp.value = "2008-01-31";
  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange", testid + "key page down 2008-01-31");
  is(dp.displayedMonth, 1, testid + "key page down 2008-01-31 displayedMonth");
  is(dp.displayedYear, 2008, testid + "key page up 2008-01-31 displayedYear");
  dp.value = "2008-03-31";
  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange", testid + "key page up 2008-03-31");
  is(dp.displayedMonth, 1, testid + "key page up 2008-03-31 displayedMonth");
  is(dp.displayedYear, 2008, testid + "key page up 2008-03-31 displayedYear");

  // the value of a read only datepicker cannot be changed
  dp.value = "2003-02-15";

  dp.readOnly = true;
  synthesizeKeyExpectEvent("VK_LEFT", { }, ktarget, "!change", testid + "key left read only");
  is(dp.value, "2003-02-15", testid + "key left read only");
  synthesizeKeyExpectEvent("VK_RIGHT", { }, ktarget, "!change", testid + "key right read only");
  is(dp.value, "2003-02-15", testid + "key right read only");
  synthesizeKeyExpectEvent("VK_DOWN", { }, ktarget, "!change", testid + "key down read only");
  is(dp.value, "2003-02-15", testid + "key down read only");
  synthesizeKeyExpectEvent("VK_UP", { }, ktarget, "!change", testid + "key up read only");
  is(dp.value, "2003-02-15", testid + "key up read only");

  // month can still be changed even when readonly
  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "monthchange",
                           testid + "key page up read only");
  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "monthchange",
                           testid + "key page down read only");

  dp.readOnly = false;
  synthesizeKeyExpectEvent("VK_LEFT", { }, ktarget, "change", testid + "key left changeable again");
  is(dp.value, "2003-02-14", testid + "key left changeable again");

  // the value of a disabled datepicker cannot be changed
  dp.disabled = true;
  synthesizeKeyExpectEvent("VK_LEFT", { }, ktarget, "!change", testid + "key left disabled");
  is(dp.value, "2003-02-14", testid + "key left disabled");
  synthesizeKeyExpectEvent("VK_RIGHT", { }, ktarget, "!change", testid + "key right disabled");
  is(dp.value, "2003-02-14", testid + "key right disabled");
  synthesizeKeyExpectEvent("VK_DOWN", { }, ktarget, "!change", testid + "key down disabled");
  is(dp.value, "2003-02-14", testid + "key down disabled");
  synthesizeKeyExpectEvent("VK_UP", { }, ktarget, "!change", testid + "key up disabled");
  is(dp.value, "2003-02-14", testid + "key up disabled");

  // month cannot be changed even when disabled
  synthesizeKeyExpectEvent("VK_PAGE_DOWN", { }, ktarget, "!monthchange",
                           testid + "key page down disabled");
  synthesizeKeyExpectEvent("VK_PAGE_UP", { }, ktarget, "!monthchange",
                           testid + "key page up disabled");

  dp.disabled = false;
  synthesizeKeyExpectEvent("VK_RIGHT", { }, ktarget, "change", testid + "key right enabled again");
  is(dp.value, "2003-02-15", testid + "key right enabled again");
}

function testtag_datepicker_UI_popup()
{
  var dppopup = document.getElementById("datepicker-popup");
  is(dppopup.open, true, "datepicker popup after open");
  testtag_datepicker_UI_grid(dppopup, "popup", "datepicker popup ");
  dppopup.open = false;
}

function testtag_datepicker_UI_key(dp, testid, value, field,
                                   uyear, umonth, udate,
                                   dyear, dmonth, ddate)
{
  dp.value = value;
  field.focus();

  synthesizeKey("VK_UP", { });
  testtag_comparedate(dp, testid + " " + value + " key up", uyear, umonth, udate);

  synthesizeKey("VK_DOWN", { });
  testtag_comparedate(dp, testid + " " + value + " key down", dyear, dmonth, ddate);
}

function testtag_getdatestring(year, month, date)
{
  month = (month < 9) ? ("0" + ++month) : month + 1;
  if (date < 10)
    date = "0" + date;
  return year + "-" + month + "-" + date;
}

function testtag_comparedate(dp, testid, year, month, date, displayedMonth, displayedYear)
{
  is(dp.value, testtag_getdatestring(year, month, date), testid + " value");
  if (testid.indexOf("initial") == -1)
    is(dp.getAttribute("value"),
                  testtag_getdatestring(year, month, date),
                  testid + " value attribute");

  var dateValue = dp.dateValue;
  ok(dateValue.getFullYear() == year &&
                dateValue.getMonth() == month &&
                dateValue.getDate() == date,
                testid + " dateValue");

  is(dp.year, year, testid + " year");
  is(dp.month, month, testid + " month");
  is(dp.displayedMonth, displayedMonth ? displayedMonth : month, testid + " displayedMonth");
  is(dp.displayedYear, displayedYear ? displayedYear : year, testid + " displayedYear");
  is(dp.date, date, testid + " date");
}

]]>

</script>

</window>