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 = document.createEvent('WheelEvent');
141 event.initWebKitWheelEvent(0, ticks, window, 0, 0, 0, 0,
142 false, false, false, false);
143 canvas().dispatchEvent(event);
145 // If the scrollbar started at the end of the range, make sure it ends there
147 if (scrollbarStartedAtEnd)
148 expectEquals(scrollbar().getRange(), scrollbar().getPosition());
154 * Simulates moving the mouse wheel up.
155 * @param {number} ticks Number of mouse wheel ticks to simulate.
157 function mouseZoomIn(ticks) {
159 var oldScale = graphView().scale_;
160 var oldRange = scrollbar().getRange();
164 if (oldScale == graphView().scale_) {
165 expectEquals(oldScale, TimelineGraphView.MIN_SCALE);
167 expectLT(graphView().scale_, oldScale);
169 expectGE(scrollbar().getRange(), oldRange);
173 * Simulates moving the mouse wheel down.
174 * @param {number} ticks Number of mouse wheel ticks to simulate.
176 function mouseZoomOut(ticks) {
178 var oldScale = graphView().scale_;
179 var oldRange = scrollbar().getRange();
183 expectGT(graphView().scale_, oldScale);
184 expectLE(scrollbar().getRange(), oldRange);
188 * Simulates zooming all the way with multiple mouse wheel events.
190 function mouseZoomAllTheWayIn() {
191 expectLT(TimelineGraphView.MIN_SCALE, graphView().scale_);
192 while (graphView().scale_ != TimelineGraphView.MIN_SCALE)
194 // Verify that zooming in when already at max zoom works.
199 * A Task that scrolls the scrollbar by manipulating the DOM, and then waits
200 * for the scroll to complete. Has to be a task because onscroll and DOM
201 * manipulations both occur asynchronously.
203 * Not safe to use when other asynchronously running code may try to
204 * manipulate the scrollbar itself, or adjust the length of the scrollbar.
206 * @param {int} position Position to scroll to.
207 * @extends {NetInternalsTest.Task}
209 function MouseScrollTask(position) {
210 NetInternalsTest.Task.call(this);
211 this.position_ = position;
212 // If the scrollbar's |position| and its node's |scrollLeft| values don't
213 // currently match, we set this to true and wait for |scrollLeft| to be
214 // updated, which will trigger an onscroll event.
215 this.waitingToStart_ = false;
218 MouseScrollTask.prototype = {
219 __proto__: NetInternalsTest.Task.prototype,
222 this.waitingToStart_ = false;
223 // If the scrollbar is already in the correct position, do nothing.
224 if (scrollbar().getNode().scrollLeft == this.position_) {
225 // We may still have a timer going to adjust the position of the
226 // scrollbar to some other value. If so, this will clear it.
227 scrollbar().setPosition(this.position_);
232 // Replace the onscroll event handler with our own.
233 this.oldOnScroll_ = scrollbar().getNode().onscroll;
234 scrollbar().getNode().onscroll = this.onScroll_.bind(this);
235 if (scrollbar().getNode().scrollLeft != scrollbar().getPosition()) {
236 this.waitingToStart_ = true;
240 window.setTimeout(this.startScrolling_.bind(this), 0);
243 onScroll_: function(event) {
244 // Restore the original onscroll function.
245 scrollbar().getNode().onscroll = this.oldOnScroll_;
246 // Call the original onscroll function.
247 this.oldOnScroll_(event);
249 if (this.waitingToStart_) {
254 assertEquals(this.position_, scrollbar().getNode().scrollLeft);
255 assertEquals(this.position_, scrollbar().getPosition());
261 startScrolling_: function() {
262 scrollbar().getNode().scrollLeft = this.position_;
267 * Tests setting and updating range.
269 TEST_F('NetInternalsTest', 'netInternalsTimelineViewRange', function() {
270 NetInternalsTest.switchToView('timeline');
272 // Set startTime/endTime for sanity checks.
273 startTime = graphView().startTime_;
274 endTime = graphView().endTime_;
275 sanityCheckWithTimeRange(true);
279 graphView().setDateRange(new Date(startTime), new Date(endTime));
280 sanityCheckWithTimeRange(true);
282 endTime = (new Date()).getTime();
283 graphView().updateEndDate();
285 expectGE(graphView().endTime_, endTime);
292 * Tests using the scroll bar.
294 TEST_F('NetInternalsTest', 'netInternalsTimelineViewScrollbar', function() {
295 // The range we want the graph to have.
296 var expectedGraphRange = canvas().width;
298 function checkGraphRange() {
299 expectEquals(expectedGraphRange, scrollbar().getRange());
302 var taskQueue = new NetInternalsTest.TaskQueue(true);
303 // Load a log and then switch to the timeline view. The end time is
304 // calculated so that the range is exactly |expectedGraphRange|.
306 new LoadLogWithNewEventsTask(
308 55 + graphView().scale_ * (canvas().width + expectedGraphRange)));
309 taskQueue.addFunctionTask(
310 NetInternalsTest.switchToView.bind(null, 'timeline'));
311 taskQueue.addFunctionTask(checkGraphRange);
313 taskQueue.addTask(new MouseScrollTask(0));
314 taskQueue.addTask(new MouseScrollTask(expectedGraphRange));
315 taskQueue.addTask(new MouseScrollTask(1));
316 taskQueue.addTask(new MouseScrollTask(expectedGraphRange - 1));
318 taskQueue.addFunctionTask(checkGraphRange);
319 taskQueue.addFunctionTask(sanityCheckWithTimeRange.bind(null, false));
324 * Dumps a log file to memory, modifies its events, loads it again, and
325 * makes sure the range is correctly set and not automatically updated.
327 TEST_F('NetInternalsTest', 'netInternalsTimelineViewLoadLog', function() {
328 // After loading the log file, the rest of the test runs synchronously.
329 function testBody() {
330 NetInternalsTest.switchToView('timeline');
331 sanityCheckWithTimeRange(false);
333 // Make sure everything's still fine when we switch to another view.
334 NetInternalsTest.switchToView('events');
335 sanityCheckWithTimeRange(false);
338 // Load a log and then run the rest of the test.
339 var taskQueue = new NetInternalsTest.TaskQueue(true);
340 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 10055));
341 taskQueue.addFunctionTask(testBody);
346 * Zooms out twice, and then zooms in once.
348 TEST_F('NetInternalsTest', 'netInternalsTimelineViewZoomOut', function() {
349 // After loading the log file, the rest of the test runs synchronously.
350 function testBody() {
351 NetInternalsTest.switchToView('timeline');
355 sanityCheckWithTimeRange(false);
358 // Load a log and then run the rest of the test.
359 var taskQueue = new NetInternalsTest.TaskQueue(true);
360 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 10055));
361 taskQueue.addFunctionTask(testBody);
366 * Zooms in as much as allowed, and zooms out once.
368 TEST_F('NetInternalsTest', 'netInternalsTimelineViewZoomIn', function() {
369 // After loading the log file, the rest of the test runs synchronously.
370 function testBody() {
371 NetInternalsTest.switchToView('timeline');
372 mouseZoomAllTheWayIn();
374 sanityCheckWithTimeRange(false);
377 // Load a log and then run the rest of the test.
378 var taskQueue = new NetInternalsTest.TaskQueue(true);
379 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 10055));
380 taskQueue.addFunctionTask(testBody);
385 * Tests case of all events having the same time.
387 TEST_F('NetInternalsTest', 'netInternalsTimelineViewDegenerate', function() {
388 // After loading the log file, the rest of the test runs synchronously.
389 function testBody() {
390 NetInternalsTest.switchToView('timeline');
392 mouseZoomAllTheWayIn();
394 sanityCheckWithTimeRange(false);
397 // Load a log and then run the rest of the test.
398 var taskQueue = new NetInternalsTest.TaskQueue(true);
399 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 55));
400 taskQueue.addFunctionTask(testBody);
405 * Tests case of having no events. Runs synchronously.
407 TEST_F('NetInternalsTest', 'netInternalsTimelineViewNoEvents', function() {
408 // Click the button to clear all the captured events, and then switch to
410 $(CaptureView.RESET_BUTTON_ID).click();
411 NetInternalsTest.switchToView('timeline');
413 // Set startTime/endTime for sanity checks.
414 startTime = graphView().startTime_;
415 endTime = graphView().endTime_;
417 sanityCheckWithTimeRange(true);
420 sanityCheckWithTimeRange(true);
422 mouseZoomAllTheWayIn();
423 sanityCheckWithTimeRange(true);
426 sanityCheckWithTimeRange(true);
431 })(); // Anonymous namespace