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.
5 // Include test fixture.
6 GEN_INCLUDE(['net_internals_test.js']);
11 // Range of time set on a log once loaded used by sanity checks.
12 // Used by sanityCheckWithTimeRange.
16 function timelineView() {
17 return TimelineView.getInstance();
20 function graphView() {
21 return timelineView().graphView_;
24 function scrollbar() {
25 return graphView().scrollbar_;
29 return graphView().canvas_;
33 * A Task that creates a log dump, modifies it so |timeTicks| are all in UTC,
34 * clears all events from the log, and then adds two new SOCKET events, which
35 * have the specified start and end times.
37 * Most of these tests start with this task first. This gives us a known
38 * starting state, and prevents the data from automatically updating.
40 * @param {int} startTime Time of the begin event.
41 * @param {int} endTime Time of the end event.
42 * @extends {NetInternalsTest.Task}
44 function LoadLogWithNewEventsTask(startTime, endTime) {
45 NetInternalsTest.Task.call(this);
46 this.startTime_ = startTime;
47 this.endTime_ = endTime;
50 LoadLogWithNewEventsTask.prototype = {
51 __proto__: NetInternalsTest.Task.prototype,
54 * Starts creating a log dump.
57 log_util.createLogDumpAsync('test', this.onLogDumpCreated.bind(this), true);
61 * Modifies the log dump and loads it.
63 onLogDumpCreated: function(logDumpText) {
64 var logDump = JSON.parse(logDumpText);
66 logDump.constants.timeTickOffset = '0';
69 var source = new NetInternalsTest.Source(1, EventSourceType.SOCKET);
71 NetInternalsTest.createBeginEvent(source, EventType.SOCKET_ALIVE,
72 this.startTime_, null));
74 NetInternalsTest.createMatchingEndEvent(logDump.events[0],
75 this.endTime_, null));
76 logDumpText = JSON.stringify(logDump);
78 assertEquals('Log loaded.', log_util.loadLogFile(logDumpText));
80 endTime = this.endTime_;
81 startTime = this.startTime_;
82 if (startTime >= endTime)
85 sanityCheckWithTimeRange(false);
92 * Checks certain invariant properties of the TimelineGraphView and the
95 function sanityCheck() {
96 expectLT(graphView().startTime_, graphView().endTime_);
97 expectLE(0, scrollbar().getPosition());
98 expectLE(scrollbar().getPosition(), scrollbar().getRange());
102 * Checks what sanityCheck does, but also checks that |startTime| and |endTime|
103 * are the same as those used by the graph, as well as whether we have a timer
104 * running to update the graph's end time. To avoid flake, this should only
105 * be used synchronously relative to when |startTime| and |endTime| were set,
106 * unless |expectUpdateTimer| is false.
107 * @param {bool} expectUpdateTimer true if the TimelineView should currently
108 * have an update end time timer running.
110 function sanityCheckWithTimeRange(expectUpdateTimer) {
111 if (!expectUpdateTimer) {
112 expectEquals(null, timelineView().updateIntervalId_);
114 expectNotEquals(null, timelineView().updateIntervalId_);
116 assertNotEquals(startTime, null);
117 assertNotEquals(endTime, null);
118 expectEquals(startTime, graphView().startTime_);
119 expectEquals(endTime, graphView().endTime_);
124 * Checks what sanityCheck does, but also checks that |startTime| and |endTime|
125 * are the same as those used by the graph.
127 function sanityCheckNotUpdating() {
128 expectEquals(null, timelineView().updateIntervalId_);
129 sanityCheckWithTimeRange();
133 * Simulates mouse wheel movement over the canvas element.
134 * @param {number} ticks Number of mouse wheel ticks to simulate.
136 function mouseZoom(ticks) {
137 var scrollbarStartedAtEnd =
138 (scrollbar().getRange() == scrollbar().getPosition());
140 var event = new WheelEvent('mousewheel', {deltaX: 0, deltaY: -ticks});
141 canvas().dispatchEvent(event);
143 // If the scrollbar started at the end of the range, make sure it ends there
145 if (scrollbarStartedAtEnd)
146 expectEquals(scrollbar().getRange(), scrollbar().getPosition());
152 * Simulates moving the mouse wheel up.
153 * @param {number} ticks Number of mouse wheel ticks to simulate.
155 function mouseZoomIn(ticks) {
157 var oldScale = graphView().scale_;
158 var oldRange = scrollbar().getRange();
162 if (oldScale == graphView().scale_) {
163 expectEquals(oldScale, TimelineGraphView.MIN_SCALE);
165 expectLT(graphView().scale_, oldScale);
167 expectGE(scrollbar().getRange(), oldRange);
171 * Simulates moving the mouse wheel down.
172 * @param {number} ticks Number of mouse wheel ticks to simulate.
174 function mouseZoomOut(ticks) {
176 var oldScale = graphView().scale_;
177 var oldRange = scrollbar().getRange();
181 expectGT(graphView().scale_, oldScale);
182 expectLE(scrollbar().getRange(), oldRange);
186 * Simulates zooming all the way with multiple mouse wheel events.
188 function mouseZoomAllTheWayIn() {
189 expectLT(TimelineGraphView.MIN_SCALE, graphView().scale_);
190 while (graphView().scale_ != TimelineGraphView.MIN_SCALE)
192 // Verify that zooming in when already at max zoom works.
197 * A Task that scrolls the scrollbar by manipulating the DOM, and then waits
198 * for the scroll to complete. Has to be a task because onscroll and DOM
199 * manipulations both occur asynchronously.
201 * Not safe to use when other asynchronously running code may try to
202 * manipulate the scrollbar itself, or adjust the length of the scrollbar.
204 * @param {int} position Position to scroll to.
205 * @extends {NetInternalsTest.Task}
207 function MouseScrollTask(position) {
208 NetInternalsTest.Task.call(this);
209 this.position_ = position;
210 // If the scrollbar's |position| and its node's |scrollLeft| values don't
211 // currently match, we set this to true and wait for |scrollLeft| to be
212 // updated, which will trigger an onscroll event.
213 this.waitingToStart_ = false;
216 MouseScrollTask.prototype = {
217 __proto__: NetInternalsTest.Task.prototype,
220 this.waitingToStart_ = false;
221 // If the scrollbar is already in the correct position, do nothing.
222 if (scrollbar().getNode().scrollLeft == this.position_) {
223 // We may still have a timer going to adjust the position of the
224 // scrollbar to some other value. If so, this will clear it.
225 scrollbar().setPosition(this.position_);
230 // Replace the onscroll event handler with our own.
231 this.oldOnScroll_ = scrollbar().getNode().onscroll;
232 scrollbar().getNode().onscroll = this.onScroll_.bind(this);
233 if (scrollbar().getNode().scrollLeft != scrollbar().getPosition()) {
234 this.waitingToStart_ = true;
238 window.setTimeout(this.startScrolling_.bind(this), 0);
241 onScroll_: function(event) {
242 // Restore the original onscroll function.
243 scrollbar().getNode().onscroll = this.oldOnScroll_;
244 // Call the original onscroll function.
245 this.oldOnScroll_(event);
247 if (this.waitingToStart_) {
252 assertEquals(this.position_, scrollbar().getNode().scrollLeft);
253 assertEquals(this.position_, scrollbar().getPosition());
259 startScrolling_: function() {
260 scrollbar().getNode().scrollLeft = this.position_;
265 * Tests setting and updating range.
267 TEST_F('NetInternalsTest', 'netInternalsTimelineViewRange', function() {
268 NetInternalsTest.switchToView('timeline');
270 // Set startTime/endTime for sanity checks.
271 startTime = graphView().startTime_;
272 endTime = graphView().endTime_;
273 sanityCheckWithTimeRange(true);
277 graphView().setDateRange(new Date(startTime), new Date(endTime));
278 sanityCheckWithTimeRange(true);
280 endTime = (new Date()).getTime();
281 graphView().updateEndDate();
283 expectGE(graphView().endTime_, endTime);
290 * Tests using the scroll bar.
292 TEST_F('NetInternalsTest', 'netInternalsTimelineViewScrollbar', function() {
293 // The range we want the graph to have.
294 var expectedGraphRange = canvas().width;
296 function checkGraphRange() {
297 expectEquals(expectedGraphRange, scrollbar().getRange());
300 var taskQueue = new NetInternalsTest.TaskQueue(true);
301 // Load a log and then switch to the timeline view. The end time is
302 // calculated so that the range is exactly |expectedGraphRange|.
304 new LoadLogWithNewEventsTask(
306 55 + graphView().scale_ * (canvas().width + expectedGraphRange)));
307 taskQueue.addFunctionTask(
308 NetInternalsTest.switchToView.bind(null, 'timeline'));
309 taskQueue.addFunctionTask(checkGraphRange);
311 taskQueue.addTask(new MouseScrollTask(0));
312 taskQueue.addTask(new MouseScrollTask(expectedGraphRange));
313 taskQueue.addTask(new MouseScrollTask(1));
314 taskQueue.addTask(new MouseScrollTask(expectedGraphRange - 1));
316 taskQueue.addFunctionTask(checkGraphRange);
317 taskQueue.addFunctionTask(sanityCheckWithTimeRange.bind(null, false));
322 * Dumps a log file to memory, modifies its events, loads it again, and
323 * makes sure the range is correctly set and not automatically updated.
325 TEST_F('NetInternalsTest', 'netInternalsTimelineViewLoadLog', function() {
326 // After loading the log file, the rest of the test runs synchronously.
327 function testBody() {
328 NetInternalsTest.switchToView('timeline');
329 sanityCheckWithTimeRange(false);
331 // Make sure everything's still fine when we switch to another view.
332 NetInternalsTest.switchToView('events');
333 sanityCheckWithTimeRange(false);
336 // Load a log and then run the rest of the test.
337 var taskQueue = new NetInternalsTest.TaskQueue(true);
338 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 10055));
339 taskQueue.addFunctionTask(testBody);
344 * Zooms out twice, and then zooms in once.
346 TEST_F('NetInternalsTest', 'netInternalsTimelineViewZoomOut', function() {
347 // After loading the log file, the rest of the test runs synchronously.
348 function testBody() {
349 NetInternalsTest.switchToView('timeline');
353 sanityCheckWithTimeRange(false);
356 // Load a log and then run the rest of the test.
357 var taskQueue = new NetInternalsTest.TaskQueue(true);
358 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 10055));
359 taskQueue.addFunctionTask(testBody);
364 * Zooms in as much as allowed, and zooms out once.
366 TEST_F('NetInternalsTest', 'netInternalsTimelineViewZoomIn', function() {
367 // After loading the log file, the rest of the test runs synchronously.
368 function testBody() {
369 NetInternalsTest.switchToView('timeline');
370 mouseZoomAllTheWayIn();
372 sanityCheckWithTimeRange(false);
375 // Load a log and then run the rest of the test.
376 var taskQueue = new NetInternalsTest.TaskQueue(true);
377 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 10055));
378 taskQueue.addFunctionTask(testBody);
383 * Tests case of all events having the same time.
385 TEST_F('NetInternalsTest', 'netInternalsTimelineViewDegenerate', function() {
386 // After loading the log file, the rest of the test runs synchronously.
387 function testBody() {
388 NetInternalsTest.switchToView('timeline');
390 mouseZoomAllTheWayIn();
392 sanityCheckWithTimeRange(false);
395 // Load a log and then run the rest of the test.
396 var taskQueue = new NetInternalsTest.TaskQueue(true);
397 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 55));
398 taskQueue.addFunctionTask(testBody);
403 * Tests case of having no events. Runs synchronously.
405 TEST_F('NetInternalsTest', 'netInternalsTimelineViewNoEvents', function() {
406 // Click the button to clear all the captured events, and then switch to
408 $(CaptureView.RESET_BUTTON_ID).click();
409 NetInternalsTest.switchToView('timeline');
411 // Set startTime/endTime for sanity checks.
412 startTime = graphView().startTime_;
413 endTime = graphView().endTime_;
415 sanityCheckWithTimeRange(true);
418 sanityCheckWithTimeRange(true);
420 mouseZoomAllTheWayIn();
421 sanityCheckWithTimeRange(true);
424 sanityCheckWithTimeRange(true);
429 })(); // Anonymous namespace