Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: chrome/test/data/webui/history_browsertest.js

Issue 2830983005: Remove old webui History page on desktop and mobile (Closed)
Patch Set: merge Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/test/data/webui/BUILD.gn ('k') | chrome/test/data/webui/history_ui_browsertest.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 GEN('#include "chrome/test/data/webui/history_ui_browsertest.h"');
6
7 /** @const */ var TOTAL_RESULT_COUNT = 160;
8 /** @const */ var WAIT_TIMEOUT = 200;
9
10 /**
11 * Test fixture for history WebUI testing.
12 * @constructor
13 * @extends {testing.Test}
14 */
15 function HistoryUIBrowserTest() {}
16
17 /**
18 * Create a fake history result with the given timestamp.
19 * @param {Number} timestamp Timestamp of the entry, in ms since the epoch.
20 * @param {String} url The URL to set on this entry.
21 * @return {Object} An object representing a history entry.
22 */
23 function createHistoryEntry(timestamp, url) {
24 var d = new Date(timestamp);
25 // Extract domain from url.
26 var domainMatch = url.replace(/^.+?:\/\//, '').match(/[^/]+/);
27 var domain = domainMatch ? domainMatch[0] : '';
28 return {
29 dateTimeOfDay: d.getHours() + ':' + d.getMinutes(),
30 dateRelativeDay: d.toDateString(),
31 allTimestamps: [timestamp],
32 starred: false,
33 time: timestamp,
34 title: d.toString(), // Use the stringified date as the title.
35 url: url,
36 domain: domain
37 };
38 }
39
40 /**
41 * Wait for the history backend to call the global function named
42 * |callbackName|, and then execute |afterFunction|. This allows tests to
43 * wait on asynchronous backend operations before proceeding.
44 */
45 function waitForCallback(callbackName, afterFunction) {
46 var originalCallback = window[callbackName];
47
48 // Install a wrapper that temporarily replaces the original function.
49 window[callbackName] = function() {
50 window[callbackName] = originalCallback;
51 originalCallback.apply(this, arguments);
52 afterFunction();
53 };
54 }
55
56 /**
57 * Asynchronously execute the global function named |functionName|. This
58 * should be used for all calls from backend stubs to the frontend.
59 */
60 function callFrontendAsync(functionName) {
61 var args = Array.prototype.slice.call(arguments, 1);
62 setTimeout(function() {
63 window[functionName].apply(window, args);
64 }, 1);
65 }
66
67 /**
68 * Checks that all the checkboxes in the [|start|, |end|] interval are checked
69 * and that their IDs are properly set. Does that against the checkboxes in
70 * |checked|, starting from the |startInChecked| position.
71 * @param {Array} checked An array of all the relevant checked checkboxes
72 * on this page.
73 * @param {Number} start The starting checkbox id.
74 * @param {Number} end The ending checkbox id.
75 */
76 function checkInterval(checked, start, end) {
77 for (var i = start; i <= end; i++)
78 expectEquals('checkbox-' + i, checked[i - start].id);
79 }
80
81 /**
82 * Returns a period of 7 days, |offset| weeks back from |today|. The behavior
83 * of this function should be identical to
84 * BrowsingHistoryHandler::SetQueryTimeInWeeks.
85 * @param {Number} offset Number of weeks to go back.
86 * @param {Date} today Which date to consider as "today" (since we're not using
87 * the actual current date in this case).
88 * @return {Object} An object containing the begin date and the end date of the
89 * computed period.
90 */
91 function setQueryTimeInWeeks(offset, today) {
92 // Going back one day at a time starting from midnight will make sure that
93 // the other values get updated properly.
94 var endTime = new Date(today);
95 endTime.setHours(24, 0, 0, 0);
96 for (var i = 0; i < 7 * offset; i++)
97 endTime.setDate(endTime.getDate() - 1);
98 var beginTime = new Date(endTime);
99 for (var i = 0; i < 7; i++)
100 beginTime.setDate(beginTime.getDate() - 1);
101 return {'endTime': endTime, 'beginTime': beginTime};
102 }
103
104 /**
105 * Returns the period of a month, |offset| months back from |today|. The
106 * behavior of this function should be identical to
107 * BrowsingHistoryHandler::SetQueryTimeInMonths.
108 * @param {Number} offset Number of months to go back.
109 * @param {Date} today Which date to consider as "today" (since we're not using
110 * the actual current date in this case).
111 * @return {Object} An object containing the begin date and the end date of the
112 * computed period.
113 */
114 function setQueryTimeInMonths(offset, today) {
115 var endTime = new Date(today);
116 var beginTime = new Date(today);
117 // Last day of this month.
118 endTime.setMonth(endTime.getMonth() + 1, 0);
119 // First day of the current month.
120 beginTime.setMonth(beginTime.getMonth(), 1);
121 for (var i = 0; i < offset; i++) {
122 beginTime.setMonth(beginTime.getMonth() - 1);
123 endTime.setMonth(endTime.getMonth() - 1);
124 }
125 return {'endTime': endTime, 'beginTime': beginTime};
126 }
127
128 /**
129 * Base fixture for History WebUI testing.
130 * @extends {testing.Test}
131 * @constructor
132 */
133 function BaseHistoryWebUITest() {}
134
135 BaseHistoryWebUITest.prototype = {
136 __proto__: testing.Test.prototype,
137
138 /**
139 * Browse to the history page & call our preLoad().
140 */
141 browsePreload: 'chrome://history-frame',
142
143 /** @override */
144 typedefCppFixture: 'HistoryUIBrowserTest',
145
146 /** @override */
147 runAccessibilityChecks: true,
148
149 /** @override */
150 accessibilityIssuesAreErrors: true,
151
152 /** @override */
153 isAsync: true,
154 };
155
156 /**
157 * Fixture for History WebUI testing which returns some fake history results
158 * to the frontend. Other fixtures that want to stub out calls to the backend
159 * can extend this one.
160 * @extends {BaseHistoryWebUITest}
161 * @constructor
162 */
163 function HistoryWebUIFakeBackendTest() {
164 }
165
166 HistoryWebUIFakeBackendTest.prototype = {
167 __proto__: BaseHistoryWebUITest.prototype,
168
169 /**
170 * Register handlers to stub out calls to the history backend.
171 * @override
172 */
173 preLoad: function() {
174 this.registerMockHandler_(
175 'queryHistory', this.queryHistoryStub_.bind(this));
176 },
177
178 /**
179 * Register a mock handler for a message to the history backend.
180 * @param handlerName The name of the message to mock.
181 * @param handler The mock message handler function.
182 */
183 registerMockHandler_: function(handlerName, handler) {
184 // Mock4JS doesn't pass in the actual arguments to the stub, but it _will_
185 // pass the original args to the matcher object. SaveMockArguments acts as
186 // a proxy for another matcher, but keeps track of all the arguments it was
187 // asked to match.
188 var savedArgs = new SaveMockArguments();
189
190 this.makeAndRegisterMockHandler([handlerName]);
191 this.mockHandler.stubs()[handlerName](savedArgs.match(ANYTHING)).will(
192 callFunctionWithSavedArgs(savedArgs, handler));
193 },
194
195 /**
196 * Default stub for the queryHistory message to the history backend.
197 * Simulates an empty history database. Override this to customize this
198 * behavior for particular tests.
199 * @param {Array} arguments The original arguments to queryHistory.
200 */
201 queryHistoryStub_: function(args) {
202 callFrontendAsync(
203 'historyResult', { term: args[0], finished: true }, []);
204 }
205 };
206
207 function queryHistoryImpl(args, beginTime, history) {
208 var searchText = args[0];
209 var offset = args[1];
210 var range = args[2];
211 var endTime = args[3] || Number.MAX_VALUE;
212 var maxCount = args[4];
213
214 var results = [];
215 if (searchText) {
216 for (var k = 0; k < history.length; k++) {
217 // Search only by title in this stub.
218 if (history[k].title.indexOf(searchText) != -1)
219 results.push(history[k]);
220 }
221 } else {
222 results = history;
223 }
224
225 // Advance past all entries newer than the specified end time.
226 var i = 0;
227 // Finished is set from the history database so this behavior may not be
228 // completely identical.
229 var finished = true;
230 while (i < results.length && results[i].time >= endTime)
231 ++i;
232
233 if (beginTime) {
234 var j = i;
235 while (j < results.length && results[j].time >= beginTime)
236 ++j;
237
238 finished = (j == results.length);
239 results = results.slice(i, j);
240 } else {
241 results = results.slice(i);
242 }
243
244 if (maxCount) {
245 finished = (maxCount >= results.length);
246 results = results.slice(0, maxCount);
247 }
248
249 var queryStartTime = '';
250 var queryEndTime = '';
251 if (results.length) {
252 queryStartTime = results[results.length - 1].dateRelativeDay;
253 queryEndTime = results[0].dateRelativeDay;
254 } else if (beginTime) {
255 queryStartTime = Date(beginTime);
256 queryEndTime = Date(endTime);
257 }
258
259 callFrontendAsync(
260 'historyResult',
261 {
262 term: searchText,
263 finished: finished,
264 queryInterval: queryStartTime + ' - ' + queryEndTime,
265 },
266 results);
267 }
268
269 /**
270 * Fixture for History WebUI testing which returns some fake history results
271 * to the frontend.
272 * @extends {HistoryWebUIFakeBackendTest}
273 * @constructor
274 */
275 function HistoryWebUITest() {}
276
277 HistoryWebUITest.prototype = {
278 __proto__: HistoryWebUIFakeBackendTest.prototype,
279
280 preLoad: function() {
281 HistoryWebUIFakeBackendTest.prototype.preLoad.call(this);
282
283 this.registerMockHandler_(
284 'removeVisits', this.removeVisitsStub_.bind(this));
285
286 // Prepare a list of fake history results. The entries will begin at
287 // 1:00 AM on Sept 2, 2008, and will be spaced two minutes apart.
288 var timestamp = new Date(2008, 9, 2, 1, 0).getTime();
289 this.fakeHistory_ = [];
290
291 for (var i = 0; i < TOTAL_RESULT_COUNT; i++) {
292 this.fakeHistory_.push(
293 createHistoryEntry(timestamp, 'http://google.com/' + timestamp));
294 timestamp -= 2 * 60 * 1000; // Next visit is two minutes earlier.
295 }
296 },
297
298 /**
299 * Stub for the 'queryHistory' message to the history backend.
300 * Simulates a history database using the fake history data that is
301 * initialized in preLoad().
302 * @param {Array} arguments The original arguments to queryHistory.
303 */
304 queryHistoryStub_: function(args) {
305 var searchText = args[0];
306 var offset = args[1];
307 var range = args[2];
308 var endTime = args[3] || Number.MAX_VALUE;
309 var maxCount = args[4];
310 if (range == HistoryModel.Range.ALL_TIME) {
311 queryHistoryImpl(args, null, this.fakeHistory_);
312 return;
313 }
314 if (range == HistoryModel.Range.WEEK)
315 var interval = setQueryTimeInWeeks(offset, this.today);
316 else
317 var interval = setQueryTimeInMonths(offset, this.today);
318
319 args[3] = interval.endTime.getTime();
320 queryHistoryImpl(args, interval.beginTime.getTime(), this.fakeHistory_);
321 },
322
323 /**
324 * Stub for the 'removeVisits' message to the history backend.
325 * This will modify the fake history data in the test instance, so that
326 * further 'queryHistory' messages will not contain the deleted entries.
327 * @param {Array} arguments The original arguments to removeVisits.
328 */
329 removeVisitsStub_: function(args) {
330 for (var i = 0; i < args.length; ++i) {
331 var url = args[i].url;
332 var timestamps = args[i].timestamps;
333 assertEquals(timestamps.length, 1);
334 this.removeVisitsToUrl_(url, new Date(timestamps[0]));
335 }
336 callFrontendAsync('deleteComplete');
337 },
338
339 /**
340 * Removes any visits to |url| on the same day as |date| from the fake
341 * history data.
342 * @param {string} url
343 * @param {Date} date
344 */
345 removeVisitsToUrl_: function(url, date) {
346 var day = date.toDateString();
347 var newHistory = [];
348 for (var i = 0, visit; visit = this.fakeHistory_[i]; ++i) {
349 if (url != visit.url || visit.dateRelativeDay != day)
350 newHistory.push(visit);
351 }
352 this.fakeHistory_ = newHistory;
353 }
354 };
355
356 /**
357 * Examines the time column of every entry on the page, and ensure that they
358 * are all the same width.
359 */
360 function ensureTimeWidthsEqual() {
361 var times = document.querySelectorAll('.entry .time');
362 var timeWidth = times[0].clientWidth;
363 for (var i = 1; i < times.length; ++i) {
364 assertEquals(timeWidth, times[i].clientWidth);
365 }
366 }
367
368 // Times out on Mac: http://crbug.com/336845
369 TEST_F('HistoryWebUIFakeBackendTest', 'DISABLED_emptyHistory', function() {
370 expectTrue($('newest-button').hidden);
371 expectTrue($('newer-button').hidden);
372 expectTrue($('older-button').hidden);
373 testDone();
374 });
375
376 // Times out on Win: http://crbug.com/336845
377 TEST_F('HistoryWebUITest', 'DISABLED_basicTest', function() {
378 var resultCount = document.querySelectorAll('.entry').length;
379
380 // Check that there are two days of entries.
381 var dayHeaders = document.querySelectorAll('.day');
382 assertEquals(2, dayHeaders.length);
383 expectNotEquals(dayHeaders[0].textContent, dayHeaders[1].textContent);
384
385 // Check that the entries in each day are time-ordered, and that no
386 // duplicate URLs appear on a given day.
387 var urlsByDay = {};
388 var lastDate = new Date();
389 for (var day = 0; day < dayHeaders.length; ++day) {
390 var dayTitle = dayHeaders[day].textContent;
391 var dayResults = document.querySelectorAll('.day-results')[day];
392 var entries = dayResults.querySelectorAll('.entry');
393 expectGT(entries.length, 0);
394
395 for (var i = 0, entry; entry = entries[i]; ++i) {
396 var time = entry.querySelector('.time').textContent;
397 expectGT(time.length, 0);
398
399 var date = new Date(dayTitle + ' ' + time);
400 expectGT(lastDate, date);
401 lastDate = date;
402
403 // Ensure it's not a duplicate URL for this day.
404 var dayAndUrl = day + entry.querySelector('a').href;
405 expectFalse(urlsByDay.hasOwnProperty(dayAndUrl));
406 urlsByDay[dayAndUrl] = dayAndUrl;
407
408 // Reconstruct the entry date from the title, and ensure that it's
409 // consistent with the date header and with the time.
410 var entryDate = new Date(entry.querySelector('.title').textContent);
411 expectEquals(entryDate.getYear(), date.getYear());
412 expectEquals(entryDate.getMonth(), date.getMonth());
413 expectEquals(entryDate.getDay(), date.getDay());
414 expectEquals(entryDate.getHours(), date.getHours());
415 expectEquals(entryDate.getMinutes(), date.getMinutes());
416 }
417 }
418
419 // Check that there are 3 page navigation links and that only the "Older"
420 // link is visible.
421 expectEquals(3, document.querySelectorAll('[is="action-link"]').length);
422 expectTrue($('newest-button').hidden);
423 expectTrue($('newer-button').hidden);
424 expectFalse($('older-button').hidden);
425
426 ensureTimeWidthsEqual();
427
428 // Go to the next page.
429 $('older-button').click();
430 waitForCallback('historyResult', function() {
431 resultCount += document.querySelectorAll('.entry').length;
432
433 // Check that the two pages include all of the entries.
434 expectEquals(TOTAL_RESULT_COUNT, resultCount);
435
436 // Check that the day header was properly continued -- the header for the
437 // last day on the first page should be a substring of the header on the
438 // second page. E.g. "Wed, Oct 8, 2008" and "Web, Oct 8, 2008 - cont'd".
439 var newDayHeaders = document.querySelectorAll('.day');
440 expectEquals(1, newDayHeaders.length);
441 expectEquals(0,
442 newDayHeaders[0].textContent.indexOf(dayHeaders[1].textContent));
443
444 // Check that the "Newest" and "Newer" links are now visible, but the
445 // "Older" link is hidden.
446 expectEquals(3, document.querySelectorAll('[is="action-link"]').length);
447 expectFalse($('newest-button').hidden);
448 expectFalse($('newer-button').hidden);
449 expectTrue($('older-button').hidden);
450
451 ensureTimeWidthsEqual();
452
453 // Go back to the first page, and check that the same day headers are there.
454 $('newest-button').click();
455 var newDayHeaders = document.querySelectorAll('.day');
456 expectEquals(2, newDayHeaders.length);
457
458 expectNotEquals(newDayHeaders[0].textContent,
459 newDayHeaders[1].textContent);
460 expectEquals(dayHeaders[0].textContent, newDayHeaders[0].textContent);
461 expectEquals(dayHeaders[1].textContent, newDayHeaders[1].textContent);
462
463 testDone();
464 });
465 });
466
467 /**
468 * Test bulk deletion of history entries.
469 * Disabled because it is currently very flaky on the Windows XP bot.
470 */
471 TEST_F('HistoryWebUITest', 'DISABLED_bulkDeletion', function() {
472 var checkboxes = document.querySelectorAll(
473 '#results-display input[type=checkbox]');
474
475 // Immediately confirm the history deletion.
476 confirmDeletion = function(okCallback, cancelCallback) {
477 okCallback();
478 };
479
480 // The "remove" button should be initially disabled.
481 var removeButton = $('remove-selected');
482 expectTrue(removeButton.disabled);
483
484 checkboxes[0].click();
485 expectFalse(removeButton.disabled);
486
487 var firstEntry = document.querySelector('.title a').textContent;
488 removeButton.click();
489
490 // After deletion, expect the results to be reloaded.
491 waitForCallback('historyResult', function() {
492 expectNotEquals(document.querySelector('.title a').textContent, firstEntry);
493 expectTrue(removeButton.disabled);
494
495 // Delete the first 3 entries.
496 checkboxes = document.querySelectorAll(
497 '#results-display input[type=checkbox]');
498 checkboxes[0].click();
499 checkboxes[1].click();
500 checkboxes[2].click();
501 expectFalse(removeButton.disabled);
502
503 var nextEntry = document.querySelectorAll('.title a')[3];
504 removeButton.click();
505 waitForCallback('historyResult', function() {
506 // The next entry after the deleted ones should now be the first.
507 expectEquals(document.querySelector('.title a').textContent,
508 nextEntry.textContent);
509 testDone();
510 });
511 });
512 });
513
514 /**
515 * Test selecting multiple entries using shift click.
516 * Disabled due to time out on all platforms: crbug/375910
517 */
518 TEST_F('HistoryWebUITest', 'DISABLED_multipleSelect', function() {
519 var checkboxes = document.querySelectorAll(
520 '#results-display input[type=checkbox]');
521
522 var getAllChecked = function() {
523 return Array.prototype.slice.call(document.querySelectorAll(
524 '#results-display input[type=checkbox]:checked'));
525 };
526
527 // Make sure that nothing is checked.
528 expectEquals(0, getAllChecked().length);
529
530 var shiftClick = function(el) {
531 el.dispatchEvent(new MouseEvent('click', { shiftKey: true }));
532 };
533
534 // Check the start.
535 shiftClick($('checkbox-4'));
536 // And the end.
537 shiftClick($('checkbox-9'));
538
539 // See if they are checked.
540 var checked = getAllChecked();
541 expectEquals(6, checked.length);
542 checkInterval(checked, 4, 9);
543
544 // Extend the selection.
545 shiftClick($('checkbox-14'));
546
547 checked = getAllChecked();
548 expectEquals(11, checked.length);
549 checkInterval(checked, 4, 14);
550
551 // Now do a normal click on a higher ID box and a shift click on a lower ID
552 // one (test the other way around).
553 $('checkbox-24').click();
554 shiftClick($('checkbox-19'));
555
556 checked = getAllChecked();
557 expectEquals(17, checked.length);
558 // First set of checkboxes (11).
559 checkInterval(checked, 4, 14);
560 // Second set (6).
561 checkInterval(checked.slice(11), 19, 24);
562
563 // Test deselection.
564 $('checkbox-26').click();
565 shiftClick($('checkbox-20'));
566
567 checked = getAllChecked();
568 // checkbox-20 to checkbox-24 should be deselected now.
569 expectEquals(12, checked.length);
570 // First set of checkboxes (11).
571 checkInterval(checked, 4, 14);
572 // Only checkbox-19 should still be selected.
573 expectEquals('checkbox-19', checked[11].id);
574
575 testDone();
576 });
577
578 TEST_F('HistoryWebUITest', 'DISABLED_searchHistory', function() {
579 var getResultCount = function() {
580 return document.querySelectorAll('.entry').length;
581 };
582 // See that all the elements are there.
583 expectEquals(RESULTS_PER_PAGE, getResultCount());
584
585 // See that the search works.
586 $('search-field').value = 'Thu Oct 02 2008';
587 $('search-button').click();
588
589 waitForCallback('historyResult', function() {
590 expectEquals(31, getResultCount());
591
592 // Clear the search.
593 $('search-field').value = '';
594 $('search-button').click();
595 waitForCallback('historyResult', function() {
596 expectEquals(RESULTS_PER_PAGE, getResultCount());
597 testDone();
598 });
599 });
600 });
601
602 function setPageState(searchText, page, groupByDomain, range, offset) {
603 window.location = '#' + PageState.getHashString(
604 searchText, page, groupByDomain, range, offset);
605 }
606
607 function RangeHistoryWebUITest() {}
608
609 RangeHistoryWebUITest.prototype = {
610 __proto__: HistoryWebUITest.prototype,
611
612 /** @override */
613 preLoad: function() {
614 HistoryWebUITest.prototype.preLoad.call(this);
615 // Repeat the domain visits every 4 days. The nested lists contain the
616 // domain suffixes for the visits in a day.
617 var domainSuffixByDay = [
618 [1, 2, 3, 4],
619 [1, 2, 2, 3],
620 [1, 2, 1, 2],
621 [1, 1, 1, 1]
622 ];
623
624 var buildDomainUrl = function(timestamp) {
625 var d = new Date(timestamp);
626 // Repeat the same setup of domains every 4 days.
627 var day = d.getDate() % 4;
628 // Assign an entry for every 6 hours so that we get 4 entries per day
629 // maximum.
630 var visitInDay = Math.floor(d.getHours() / 6);
631 return 'http://google' + domainSuffixByDay[day][visitInDay] + '.com/' +
632 timestamp;
633 };
634
635 // Prepare a list of fake history results. Start the results on
636 // 11:00 PM on May 2, 2012 and add 4 results every day (one result every 6
637 // hours).
638 var timestamp = new Date(2012, 4, 2, 23, 0).getTime();
639 this.today = new Date(2012, 4, 2);
640 this.fakeHistory_ = [];
641
642 // Put in 2 days for May and 30 days for April so the results span over
643 // the month limit.
644 for (var i = 0; i < 4 * 32; i++) {
645 this.fakeHistory_.push(
646 createHistoryEntry(timestamp, buildDomainUrl(timestamp)));
647 timestamp -= 6 * 60 * 60 * 1000;
648 }
649
650 // Leave March empty.
651 timestamp -= 31 * 24 * 3600 * 1000;
652
653 // Put results in February.
654 for (var i = 0; i < 29 * 4; i++) {
655 this.fakeHistory_.push(
656 createHistoryEntry(timestamp, buildDomainUrl(timestamp)));
657 timestamp -= 6 * 60 * 60 * 1000;
658 }
659 },
660
661 setUp: function() {
662 // Show the filter controls as if the command line switch was active.
663 $('top-container').hidden = true;
664 $('history-page').classList.add('big-topbar-page');
665 $('filter-controls').hidden = false;
666 expectFalse($('filter-controls').hidden);
667 },
668 };
669
670 /**
671 * Disabled due intermitent failures on multiple OSes http://crbug.com/377338
672 */
673 TEST_F('RangeHistoryWebUITest', 'DISABLED_allView', function() {
674 // Check that we start off in the all time view.
675 expectTrue($('timeframe-controls').querySelector('input').checked);
676 // See if the correct number of days is shown.
677 var dayHeaders = document.querySelectorAll('.day');
678 assertEquals(Math.ceil(RESULTS_PER_PAGE / 4), dayHeaders.length);
679 testDone();
680 });
681
682 /**
683 * Checks whether the domains in a day are ordered decreasingly.
684 * @param {Element} element Ordered list containing the grouped domains for a
685 * day.
686 */
687 function checkGroupedVisits(element) {
688 // The history page contains the number of visits next to a domain in
689 // parentheses (e.g. 'google.com (5)'). This function extracts that number
690 // and returns it.
691 var getNumberVisits = function(element) {
692 return parseInt(element.textContent.replace(/\D/g, ''), 10);
693 };
694
695 // Read the number of visits from each domain and make sure that it is lower
696 // than or equal to the number of visits from the previous domain.
697 var domainEntries = element.querySelectorAll('.number-visits');
698 var currentNumberOfVisits = getNumberVisits(domainEntries[0]);
699 for (var j = 1; j < domainEntries.length; j++) {
700 var numberOfVisits = getNumberVisits(domainEntries[j]);
701 assertTrue(currentNumberOfVisits >= numberOfVisits);
702 currentNumberOfVisits = numberOfVisits;
703 }
704 }
705
706 // Times out on Mac and Win: http://crbug.com/336845
707 TEST_F('RangeHistoryWebUITest', 'DISABLED_weekViewGrouped', function() {
708 // Change to weekly view.
709 setPageState('', 0, HistoryModel.Range.WEEK, 0);
710 waitForCallback('historyResult', function() {
711 // See if the correct number of days is still shown.
712 var dayResults = document.querySelectorAll('.day-results');
713 assertEquals(7, dayResults.length);
714
715 // Check whether the results are ordered by visits.
716 for (var i = 0; i < dayResults.length; i++)
717 checkGroupedVisits(dayResults[i]);
718
719 ensureTimeWidthsEqual();
720
721 testDone();
722 });
723 });
724
725 // Times out on Mac and Win: http://crbug.com/336845
726 TEST_F('RangeHistoryWebUITest', 'DISABLED_monthViewGrouped', function() {
727 // Change to monthly view.
728 setPageState('', 0, HistoryModel.Range.MONTH, 0);
729 waitForCallback('historyResult', function() {
730 // See if the correct number of days is shown.
731 var monthResults = document.querySelectorAll('.month-results');
732 assertEquals(1, monthResults.length);
733
734 checkGroupedVisits(monthResults[0]);
735 ensureTimeWidthsEqual();
736
737 testDone();
738 });
739 });
740
741 // Times out on Mac: http://crbug.com/336845
742 TEST_F('RangeHistoryWebUITest', 'DISABLED_monthViewEmptyMonth', function() {
743 // Change to monthly view.
744 setPageState('', 0, HistoryModel.Range.MONTH, 2);
745
746 waitForCallback('historyResult', function() {
747 // See if the correct number of days is shown.
748 var resultsDisplay = $('results-display');
749 assertEquals(0, resultsDisplay.querySelectorAll('.months-results').length);
750 var noResults = loadTimeData.getString('noResults');
751 assertNotEquals(-1, $('results-header').textContent.indexOf(noResults));
752
753 testDone();
754 });
755 });
756
757 /**
758 * Fixture for History WebUI tests using the real history backend.
759 * @extends {BaseHistoryWebUITest}
760 * @constructor
761 */
762 function HistoryWebUIRealBackendTest() {}
763
764 HistoryWebUIRealBackendTest.prototype = {
765 __proto__: BaseHistoryWebUITest.prototype,
766
767 /** @override */
768 testGenPreamble: function() {
769 // Add some visits to the history database.
770 GEN(' AddPageToHistory(0, "http://google.com", "Google");');
771 GEN(' AddPageToHistory(1, "http://example.com", "Example");');
772 GEN(' AddPageToHistory(2, "http://google.com", "Google");');
773
774 // Add a visit on the next day.
775 GEN(' AddPageToHistory(36, "http://google.com", "Google");');
776 },
777
778 /** @override */
779 setUp: function() {
780 BaseHistoryWebUITest.prototype.setUp.call(this);
781
782 // Enable when failure is resolved.
783 // AX_TEXT_04: http://crbug.com/560914
784 this.accessibilityAuditConfig.ignoreSelectors(
785 'linkWithUnclearPurpose',
786 '#notification-bar > SPAN > A');
787 },
788 };
789
790 /**
791 * Simple test that verifies that the correct entries are retrieved from the
792 * history database and displayed in the UI.
793 */
794 // Times out on Mac and Win: http://crbug.com/336845
795 TEST_F('HistoryWebUIRealBackendTest', 'DISABLED_basic', function() {
796 // Check that there are two days of entries, and three entries in total.
797 assertEquals(2, document.querySelectorAll('.day').length);
798 assertEquals(3, document.querySelectorAll('.entry').length);
799
800 testDone();
801 });
802
803 // Times out on Mac: http://crbug.com/336845
804 TEST_F('HistoryWebUIRealBackendTest',
805 'DISABLED_atLeastOneFocusable', function() {
806 var results = document.querySelectorAll('#results-display [tabindex="0"]');
807 expectGE(results.length, 1);
808 testDone();
809 });
810
811 // Times out on Mac: http://crbug.com/336845
812 TEST_F('HistoryWebUIRealBackendTest',
813 'DISABLED_deleteRemovesEntry', function() {
814 assertTrue(historyModel.deletingHistoryAllowed);
815
816 var visit = document.querySelector('.entry').visit;
817 visit.titleLink.focus();
818 assertEquals(visit.titleLink, document.activeElement);
819
820 var deleteKey = new KeyboardEvent('keydown',
821 {bubbles: true, cancelable: true, key: 'Delete'});
822
823 assertFalse(historyModel.isDeletingVisits());
824 expectFalse(visit.titleLink.dispatchEvent(deleteKey));
825 expectTrue(historyModel.isDeletingVisits());
826
827 expectNotEquals(visit.dropDown, document.activeElement);
828 testDone();
829 });
830
831 /**
832 * Test individual deletion of history entries.
833 */
834 TEST_F('HistoryWebUIRealBackendTest', 'singleDeletion', function() {
835 // Deletes the history entry represented by |entryElement|, and calls callback
836 // when the deletion is complete.
837 var removeEntry = function(entryElement, callback) {
838 var dropDownButton = entryElement.querySelector('.drop-down');
839 var removeMenuItem = $('remove-visit');
840
841 assertFalse(dropDownButton.disabled);
842 assertFalse(removeMenuItem.disabled);
843
844 waitForCallback('onEntryRemoved', callback);
845
846 cr.dispatchSimpleEvent(dropDownButton, 'mousedown');
847
848 var e = new Event('command', {bubbles: true});
849 e.command = removeMenuItem.command;
850 removeMenuItem.dispatchEvent(e);
851 };
852
853 var secondTitle = document.querySelectorAll('.entry a')[1].textContent;
854 var thirdTitle = document.querySelectorAll('.entry a')[2].textContent;
855
856 // historyDeleted() should not be called when deleting individual entries
857 // using the drop down.
858 waitForCallback('historyDeleted', function() {
859 testDone([false, 'historyDeleted() called when deleting single entry']);
860 });
861
862 expectEquals(2, document.querySelectorAll('.day').length);
863
864 // Delete the first entry. The previous second entry should now be the first.
865 removeEntry(document.querySelector('.entry'), function() {
866 expectEquals(secondTitle, document.querySelector('.entry a').textContent);
867
868 // After removing the first entry, its day header should also be gone.
869 expectEquals(1, document.querySelectorAll('.day').length);
870
871 // Delete another entry. The original third entry should now be the first.
872 removeEntry(document.querySelector('.entry'), function() {
873 expectEquals(thirdTitle, document.querySelector('.entry a').textContent);
874 testDone();
875 });
876 });
877 });
878
879 TEST_F('HistoryWebUIRealBackendTest', 'leftRightChangeFocus', function() {
880 var visit = document.querySelector('.entry').visit;
881 visit.titleLink.focus();
882 assertEquals(visit.titleLink, document.activeElement);
883
884 var right = new KeyboardEvent('keydown',
885 {bubbles: true, cancelable: true, key: 'ArrowRight'});
886 expectFalse(visit.titleLink.dispatchEvent(right));
887
888 assertEquals(visit.dropDown, document.activeElement);
889
890 var left = new KeyboardEvent('keydown',
891 {bubbles: true, cancelable: true, key: 'ArrowLeft'});
892 expectFalse(visit.dropDown.dispatchEvent(left));
893
894 expectEquals(visit.titleLink, document.activeElement);
895 testDone();
896 });
897
898 TEST_F('HistoryWebUIRealBackendTest', 'showConfirmDialogAndCancel', function() {
899 waitForCallback('deleteComplete', function() {
900 testDone([false, "history deleted when it shouldn't have been"]);
901 });
902
903 document.querySelector('input[type=checkbox]').click();
904 $('remove-selected').click();
905
906 assertTrue($('alertOverlay').classList.contains('showing'));
907 assertFalse($('history-page').contains(document.activeElement));
908
909 var esc = new KeyboardEvent('keydown',
910 {bubbles: true, cancelable: true, key: 'Escape'});
911
912 document.documentElement.dispatchEvent(esc);
913 assertFalse($('alertOverlay').classList.contains('showing'));
914
915 testDone();
916 });
917
918 TEST_F('HistoryWebUIRealBackendTest', 'showConfirmDialogAndRemove', function() {
919 document.querySelector('input[type=checkbox]').click();
920 $('remove-selected').click();
921
922 assertTrue($('alertOverlay').classList.contains('showing'));
923 assertFalse($('history-page').contains(document.activeElement));
924
925 waitForCallback('deleteComplete', testDone);
926
927 var enter = new KeyboardEvent('keydown',
928 {bubbles: true, cancelable: true, key: 'Enter'});
929 document.documentElement.dispatchEvent(enter);
930 assertFalse($('alertOverlay').classList.contains('showing'));
931 });
932
933 // Times out on Mac: http://crbug.com/336845
934 TEST_F('HistoryWebUIRealBackendTest',
935 'DISABLED_menuButtonActivatesOneRow', function() {
936 var entries = document.querySelectorAll('.entry');
937 assertEquals(3, entries.length);
938 assertTrue(entries[0].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
939 assertTrue($('action-menu').hidden);
940
941 // Show the menu via mousedown on the menu button.
942 var menuButton = entries[2].querySelector('.menu-button');
943 menuButton.dispatchEvent(new MouseEvent('mousedown'));
944 expectFalse($('action-menu').hidden);
945
946 // Check that the active item has changed.
947 expectTrue(entries[2].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
948 expectFalse(entries[0].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
949
950 testDone();
951 });
952
953 // Flaky: http://crbug.com/527434
954 TEST_F('HistoryWebUIRealBackendTest',
955 'DISABLED_shiftClickActivatesOneRow', function () {
956 var entries = document.querySelectorAll('.entry');
957 assertEquals(3, entries.length);
958 assertTrue(entries[0].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
959
960 entries[0].visit.checkBox.focus();
961 assertEquals(entries[0].visit.checkBox, document.activeElement);
962
963 entries[0].visit.checkBox.click();
964 assertTrue(entries[0].visit.checkBox.checked);
965
966 var entryBox = entries[2].querySelector('.entry-box');
967 entryBox.dispatchEvent(new MouseEvent('click', {shiftKey: true}));
968 assertTrue(entries[1].visit.checkBox.checked);
969
970 // Focus shouldn't have changed, but the checkbox should toggle.
971 expectEquals(entries[0].visit.checkBox, document.activeElement);
972
973 expectTrue(entries[0].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
974 expectFalse(entries[2].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
975
976 var shiftDown = new MouseEvent('mousedown', {shiftKey: true, bubbles: true});
977 entries[2].visit.checkBox.dispatchEvent(shiftDown);
978 expectEquals(entries[2].visit.checkBox, document.activeElement);
979
980 // 'focusin' events aren't dispatched while tests are run in batch (e.g.
981 // --test-launcher-jobs=2). Simulate this. TODO(dbeam): fix instead.
982 cr.dispatchSimpleEvent(document.activeElement, 'focusin', true, true);
983
984 expectFalse(entries[0].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
985 expectTrue(entries[2].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
986
987 testDone();
988 });
989
990 /**
991 * Fixture for History WebUI testing when deletions are prohibited.
992 * @extends {HistoryWebUIRealBackendTest}
993 * @constructor
994 */
995 function HistoryWebUIDeleteProhibitedTest() {}
996
997 HistoryWebUIDeleteProhibitedTest.prototype = {
998 __proto__: HistoryWebUIRealBackendTest.prototype,
999
1000 /** @override */
1001 testGenPreamble: function() {
1002 HistoryWebUIRealBackendTest.prototype.testGenPreamble.call(this);
1003 GEN(' SetDeleteAllowed(false);');
1004 },
1005 };
1006
1007 // Test UI when removing entries is prohibited.
1008 // Times out on Mac: http://crbug.com/336845
1009 TEST_F('HistoryWebUIDeleteProhibitedTest',
1010 'DISABLED_deleteProhibited', function() {
1011 // No checkboxes should be created.
1012 var checkboxes = document.querySelectorAll(
1013 '#results-display input[type=checkbox]');
1014 expectEquals(0, checkboxes.length);
1015
1016 // The "remove" button should be disabled.
1017 var removeButton = $('remove-selected');
1018 expectTrue(removeButton.disabled);
1019
1020 // The "Remove from history" drop-down item should be disabled.
1021 var removeVisit = $('remove-visit');
1022 expectTrue(removeVisit.disabled);
1023
1024 testDone();
1025 });
1026
1027 TEST_F('HistoryWebUIDeleteProhibitedTest', 'atLeastOneFocusable', function() {
1028 var results = document.querySelectorAll('#results-display [tabindex="0"]');
1029 expectGE(results.length, 1);
1030 testDone();
1031 });
1032
1033 TEST_F('HistoryWebUIDeleteProhibitedTest', 'leftRightChangeFocus', function() {
1034 var visit = document.querySelector('.entry').visit;
1035 visit.titleLink.focus();
1036 assertEquals(visit.titleLink, document.activeElement);
1037
1038 var right = new KeyboardEvent('keydown',
1039 {bubbles: true, cancelable: true, key: 'ArrowRight'});
1040 expectFalse(visit.titleLink.dispatchEvent(right));
1041
1042 assertEquals(visit.dropDown, document.activeElement);
1043
1044 var left = new KeyboardEvent('keydown',
1045 {bubbles: true, cancelable: true, key: 'ArrowLeft'});
1046 expectFalse(visit.dropDown.dispatchEvent(left));
1047
1048 expectEquals(visit.titleLink, document.activeElement);
1049 testDone();
1050 });
1051
1052 TEST_F('HistoryWebUIDeleteProhibitedTest', 'deleteIgnored', function() {
1053 assertFalse(historyModel.deletingHistoryAllowed);
1054
1055 var visit = document.querySelector('.entry').visit;
1056 visit.titleLink.focus();
1057 assertEquals(visit.titleLink, document.activeElement);
1058
1059 var deleteKey = new KeyboardEvent('keydown',
1060 {bubbles: true, cancelable: true, key: 'Delete'});
1061
1062 assertFalse(historyModel.isDeletingVisits());
1063 expectTrue(visit.titleLink.dispatchEvent(deleteKey));
1064 expectFalse(historyModel.isDeletingVisits());
1065
1066 expectEquals(visit.titleLink, document.activeElement);
1067 testDone();
1068 });
1069
1070 /**
1071 * Fixture for History WebUI testing IDN.
1072 * @extends {BaseHistoryWebUITest}
1073 * @constructor
1074 */
1075 function HistoryWebUIIDNTest() {}
1076
1077 HistoryWebUIIDNTest.prototype = {
1078 __proto__: BaseHistoryWebUITest.prototype,
1079
1080 /** @override */
1081 testGenPreamble: function() {
1082 // Add some visits to the history database.
1083 GEN(' AddPageToHistory(0, "http://xn--d1abbgf6aiiy.xn--p1ai/",' +
1084 ' "Some");');
1085
1086 // Clear AcceptLanguages to get domain in unicode.
1087 GEN(' ClearAcceptLanguages();');
1088 },
1089 };
1090
1091 /**
1092 * Simple test that verifies that the correct entries are retrieved from the
1093 * history database and displayed in the UI.
1094 */
1095 // Times out on Mac: http://crbug.com/336845
1096 TEST_F('HistoryWebUIIDNTest', 'DISABLED_basic', function() {
1097 // Check that there is only one entry and domain is in unicode.
1098 assertEquals(1, document.querySelectorAll('.domain').length);
1099 assertEquals("\u043f\u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442." +
1100 "\u0440\u0444", document.querySelector('.domain').textContent);
1101
1102 testDone();
1103 });
1104
1105 /**
1106 * Fixture for a test that uses the real backend and tests how the history
1107 * page deals with odd schemes in URLs.
1108 * @extends {HistoryWebUIRealBackendTest}
1109 */
1110 function HistoryWebUIWithSchemesTest() {}
1111
1112 HistoryWebUIWithSchemesTest.prototype = {
1113 __proto__: HistoryWebUIRealBackendTest.prototype,
1114
1115 /** @override */
1116 testGenPreamble: function() {
1117 // Add a bunch of entries on the same day, including some weird schemes.
1118 GEN(' AddPageToHistory(12, "http://google.com", "Google");');
1119 GEN(' AddPageToHistory(13, "file:///tmp/foo", "");');
1120 GEN(' AddPageToHistory(14, "mailto:chromium@chromium.org", "");');
1121 GEN(' AddPageToHistory(15, "tel:555123456", "");');
1122 },
1123
1124 setUp: function() {
1125 // Show the filter controls as if the command line switch was active.
1126 $('top-container').hidden = true;
1127 $('history-page').classList.add('big-topbar-page');
1128 $('filter-controls').hidden = false;
1129 expectFalse($('filter-controls').hidden);
1130 },
1131 };
1132
1133 TEST_F('HistoryWebUIWithSchemesTest', 'groupingWithSchemes', function() {
1134 // Switch to the week view.
1135 $('timeframe-controls').querySelectorAll('input')[1].click();
1136 waitForCallback('historyResult', function() {
1137 // Each URL should be organized under a different "domain".
1138 expectEquals(document.querySelectorAll('.entry').length, 4);
1139 expectEquals(document.querySelectorAll('.site-domain-wrapper').length, 4);
1140 testDone();
1141 });
1142 });
OLDNEW
« no previous file with comments | « chrome/test/data/webui/BUILD.gn ('k') | chrome/test/data/webui/history_ui_browsertest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698