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

Side by Side Diff: chrome/test/data/webui/net_internals/timeline_view.js

Issue 8474001: Add a timeline view to about:net-internals. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Update comments Created 9 years, 1 month 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 | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 // Anonymous namespace
6 (function() {
7
8 // Range of time set on a log once loaded used by sanity checks.
9 // Used by sanityCheckWithTimeRange.
10 var startTime = null;
11 var endTime = null;
12
13 var timelineView = TimelineView.getInstance();
14 var graphView = timelineView.graphView_;
15 var scrollbar = graphView.scrollbar_;
16 var canvas = graphView.canvas_;
17
18 /**
19 * A Task that creates a log dump, modifies it so |timeTicks| are all in UTC,
20 * clears all events from the log, and then adds two new SOCKET events, which
21 * are two full widths of the scrollbar apart, at the current zoom.
22 *
23 * Most of these tests start with this task first. This gives us a known
24 * starting state, and prevents the data from automatically updating.
25 *
26 * @param {int} startTime Time of the begin event.
27 * @param {int} startTime Time of the end event.
28 * @extends {netInternalsTest.Task}
29 */
30 function LoadLogWithNewEventsTask(startTime, endTime) {
31 netInternalsTest.Task.call(this);
32 this.startTime_ = startTime;
33 this.endTime_ = endTime;
34 }
35
36 LoadLogWithNewEventsTask.prototype = {
37 __proto__: netInternalsTest.Task.prototype,
38
39 /**
40 * Starts creating a log dump.
41 */
42 start: function() {
43 logutil.createLogDumpAsync('test', this.onLogDumpCreated.bind(this));
44 },
45
46 /**
47 * Modifies the log dump and loads it.
48 */
49 onLogDumpCreated: function(logDumpText) {
50 var logDump = JSON.parse(logDumpText);
51
52 logDump.constants.timeTickOffset = '0';
53 logDump.events = [];
54
55 var source = new netInternalsTest.Source(1, LogSourceType.SOCKET);
56 logDump.events.push(
57 netInternalsTest.CreateBeginEvent(source, LogEventType.SOCKET_ALIVE,
58 this.startTime_, null));
59 logDump.events.push(
60 netInternalsTest.CreateMatchingEndEvent(logDump.events[0],
61 this.endTime_, null));
62 logDumpText = JSON.stringify(logDump);
63
64 assertEquals('Log loaded.', logutil.loadLogFile(logDumpText));
65
66 endTime = this.endTime_;
67 startTime = this.startTime_;
68 if (startTime >= endTime)
69 --startTime;
70
71 sanityCheckWithTimeRange(false);
72
73 this.onTaskDone();
74 }
75 };
76
77 /**
78 * Checks certain invariant properties of the TimelineGraphView and the
79 * scroll bar.
80 */
81 function sanityCheck() {
82 expectLT(graphView.startTime_, graphView.endTime_);
83 expectLE(0, scrollbar.getPosition());
84 expectLE(scrollbar.getPosition(), scrollbar.getRange());
85 }
86
87 /**
88 * Checks what sanityCheck does, but also checks that |startTime| and |endTime|
89 * are the same as those used by the graph, as well as whether we have a timer
90 * running to update the graph's end time. To avoid flake, this should only
91 * be used synchronously relative to when |startTime| and |endTime| were set,
92 * unless |expectUpdateTimer| is false.
93 * @param {bool} expectUpdateTimer true if the TimelineView should currently
94 * have an update end time timer running.
95 */
96 function sanityCheckWithTimeRange(expectUpdateTimer) {
97 if (!expectUpdateTimer) {
98 expectEquals(null, timelineView.updateIntervalId_);
99 } else {
100 expectNotEquals(null, timelineView.updateIntervalId_);
101 }
102 assertNotEquals(startTime, null);
103 assertNotEquals(endTime, null);
104 expectEquals(startTime, graphView.startTime_);
105 expectEquals(endTime, graphView.endTime_);
106 sanityCheck(false);
107 }
108
109 /**
110 * Checks what sanityCheck does, but also checks that |startTime| and |endTime|
111 * are the same as those used by the graph.
112 */
113 function sanityCheckNotUpdating() {
114 expectEquals(null, timelineView.updateIntervalId_);
115 sanityCheckWithTimeRange();
116 }
117
118 /**
119 * Simulates mouse wheel movement over the canvas element.
120 * @param {number} mouseWheelMovement Amount of movement to simulate.
121 */
122 function mouseZoom(mouseWheelMovement) {
123 var scrollbarStartedAtEnd =
124 (scrollbar.getRange() == scrollbar.getPosition());
125
126 var event = document.createEvent('WheelEvent');
127 event.initWebKitWheelEvent(0, mouseWheelMovement, window, 0, 0, 0, 0,
128 false, false, false, false);
129 canvas.dispatchEvent(event);
130
131 // If the scrollbar started at the end of the range, make sure it ends there
132 // as well.
133 if (scrollbarStartedAtEnd)
134 expectEquals(scrollbar.getRange(), scrollbar.getPosition());
135
136 sanityCheck();
137 }
138
139 /**
140 * Simulates moving the mouse wheel up.
141 */
142 function mouseZoomIn() {
143 var oldScale = graphView.scale_;
144 var oldRange = scrollbar.getRange();
145
146 mouseZoom(1);
147
148 if (oldScale == graphView.scale_) {
149 expectEquals(oldScale, TimelineGraphView.MIN_SCALE);
150 } else {
151 expectLT(graphView.scale_, oldScale);
152 }
153 expectGE(scrollbar.getRange(), oldRange);
154 }
155
156 /**
157 * Simulates moving the mouse wheel down.
158 */
159 function mouseZoomOut() {
eroman 2011/11/16 04:03:46 nice with the testing!
160 var oldScale = graphView.scale_;
161 var oldRange = scrollbar.getRange();
162
163 mouseZoom(-1);
164
165 expectGT(graphView.scale_, oldScale);
166 expectLE(scrollbar.getRange(), oldRange);
167 }
168
169 /**
170 * Simulates zooming all the way by repeated mousemovement.
171 */
172 function mouseZoomAllTheWayIn() {
173 expectLT(TimelineGraphView.MIN_SCALE, graphView.scale_);
174 while (graphView.scale_ != TimelineGraphView.MIN_SCALE)
175 mouseZoomIn();
176 // Verify that zooming in when already at max zoom works.
177 mouseZoomIn();
178 }
179
180 /**
181 * A Task that scrolls the scrollbar by manipulating the DOM, and then waits
182 * for the scroll to complete. Has to be a task because onscroll and DOM
183 * manipulations both occur asynchronously.
184 *
185 * Not safe to use when other asynchronously running code may try to
186 * maniplulate the scrollbar itself, or adjust the length of the scrollbar.
187 *
188 * @param {int} startTime Time of the begin event.
189 * @param {int} startTime Time of the end event.
190 * @extends {netInternalsTest.Task}
191 */
192 function MouseScrollTask(position) {
193 netInternalsTest.Task.call(this);
194 this.position_ = position;
195 // If the scrollbar's |position| and its node's |scrollLeft| values don't
196 // currently match, we set this to true and wait for |scrollLeft| to be
197 // updated, which will trigger an onscroll event.
198 this.waitingToStart_ = false;
199 }
200
201 MouseScrollTask.prototype = {
202 __proto__: netInternalsTest.Task.prototype,
203
204 start: function() {
205 this.waitingToStart_ = false;
206 // If the scrollbar is already in the correct position, do nothing.
207 if (scrollbar.getNode().scrollLeft == this.position_) {
208 // We may still have a timer going to adjust the position of the
209 // scrollbar. If so, this will clear it.
210 scrollbar.setPosition(this.position_);
211 this.onTaskDone();
212 return;
213 }
214
215 // Replace the onscroll event handler with our own.
216 this.oldOnScroll_ = scrollbar.getNode().onscroll;
217 scrollbar.getNode().onscroll = this.onScroll_.bind(this);
218 if (scrollbar.getNode().scrollLeft != scrollbar.getPosition()) {
219 this.waitingToStart_ = true;
220 return;
221 }
222
223 window.setTimeout(this.startScrolling_.bind(this), 0);
224 },
225
226 onScroll_: function(event) {
227 // Restore the original onscroll function.
228 scrollbar.getNode().onscroll = this.oldOnScroll_;
229 // Call the original onscroll function.
230 this.oldOnScroll_(event);
231
232 if (this.waitingToStart_) {
233 this.start();
234 return;
235 }
236
237 assertEquals(this.position_, scrollbar.getNode().scrollLeft);
238 assertEquals(this.position_, scrollbar.getPosition());
239
240 sanityCheck();
241 this.onTaskDone();
242 },
243
244 startScrolling_: function() {
245 scrollbar.getNode().scrollLeft = this.position_;
246 }
247 };
248
249 netInternalsTest.test('netInternalsTimelineViewRange', function() {
250 netInternalsTest.switchToView('timeline');
251
252 // Set startTime/endTime for sanity checks.
253 startTime = graphView.startTime_;
254 endTime = graphView.endTime_;
255 sanityCheckWithTimeRange(true);
256
257 startTime = 0;
258 endTime = 10;
259 graphView.setDateRange(new Date(startTime), new Date(endTime));
260 sanityCheckWithTimeRange(true);
261
262 endTime = (new Date()).getTime();
263 graphView.updateEndDate();
264
265 expectGE(graphView.endTime_, endTime);
266 sanityCheck();
267
268 testDone();
269 });
270
271 netInternalsTest.test('netInternalsTimelineViewScrollbar', function() {
272 var expectedGraphRange = canvas.width;
273
274 function checkGraphRange() {
275 expectEquals(expectedGraphRange, scrollbar.getRange());
276 }
277
278 var taskQueue = new netInternalsTest.TaskQueue(true);
279 // Load a log and then switch to the timeline view.
280 taskQueue.addTask(
281 new LoadLogWithNewEventsTask(
282 55, 55 + graphView.scale_ * (canvas.width + expectedGraphRange)));
283 taskQueue.addFunctionTask(
284 netInternalsTest.switchToView.bind(null, 'timeline'));
285 taskQueue.addFunctionTask(checkGraphRange);
286
287 taskQueue.addTask(new MouseScrollTask(0));
288 taskQueue.addTask(new MouseScrollTask(expectedGraphRange));
289 taskQueue.addTask(new MouseScrollTask(1));
290 taskQueue.addTask(new MouseScrollTask(expectedGraphRange - 1));
291
292 taskQueue.addFunctionTask(checkGraphRange);
293 taskQueue.addFunctionTask(sanityCheckWithTimeRange.bind(null, false));
294 taskQueue.run();
295 });
296
297 netInternalsTest.test('netInternalsTimelineViewLoadLog', function() {
298 // After loading the log file, the rest of the test runs synchronously.
299 function testBody() {
300 netInternalsTest.switchToView('timeline');
301 sanityCheckWithTimeRange(false);
302
303 // Make sure everything's still fine when we switch to another view.
304 netInternalsTest.switchToView('events');
305 sanityCheckWithTimeRange(false);
306 }
307
308 // Load a log and then run the rest of the test.
309 var taskQueue = new netInternalsTest.TaskQueue(true);
310 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 10055));
311 taskQueue.addFunctionTask(testBody);
312 taskQueue.run();
313 });
314
315 netInternalsTest.test('netInternalsTimelineViewZoomOut', function() {
316 // After loading the log file, the rest of the test runs synchronously.
317 function testBody() {
318 netInternalsTest.switchToView('timeline');
319 mouseZoomOut();
320 mouseZoomOut();
321 mouseZoomIn();
322 sanityCheckWithTimeRange(false);
323 }
324
325 // Load a log and then run the rest of the test.
326 var taskQueue = new netInternalsTest.TaskQueue(true);
327 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 10055));
328 taskQueue.addFunctionTask(testBody);
329 taskQueue.run();
330 });
331
332 netInternalsTest.test('netInternalsTimelineViewZoomIn', function() {
333 // After loading the log file, the rest of the test runs synchronously.
334 function testBody() {
335 netInternalsTest.switchToView('timeline');
336 mouseZoomAllTheWayIn();
337 mouseZoomOut();
338 sanityCheckWithTimeRange(false);
339 }
340
341 // Load a log and then run the rest of the test.
342 var taskQueue = new netInternalsTest.TaskQueue(true);
343 taskQueue.addTask(new LoadLogWithNewEventsTask(55, 10055));
344 taskQueue.addFunctionTask(testBody);
345 taskQueue.run();
346 });
347
348 netInternalsTest.test('netInternalsTimelineViewDegenerate', function() {
349 // After loading the log file, the rest of the test runs synchronously.
350 function testBody() {
351 netInternalsTest.switchToView('timeline');
352 mouseZoomOut();
353 mouseZoomAllTheWayIn();
354 mouseZoomOut();
355 sanityCheckWithTimeRange(false);
356 }
357
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);
362 taskQueue.run();
363 });
364
365 /**
366 * Since we don't need to load a log file, this test can run synchronously.
367 */
368 netInternalsTest.test('netInternalsTimelineViewNoEvents', function() {
369 // Click on delete all on events view, and then switch to timeline view.
370 netInternalsTest.switchToView('events');
371 $(EventsView.DELETE_ALL_ID).click();
372 netInternalsTest.switchToView('timeline');
373
374 // Set startTime/endTime for sanity checks.
375 startTime = graphView.startTime_;
376 endTime = graphView.endTime_;
377
378 sanityCheckWithTimeRange(true);
379
380 mouseZoomOut();
381 sanityCheckWithTimeRange(true);
382
383 mouseZoomAllTheWayIn();
384 sanityCheckWithTimeRange(true);
385
386 mouseZoomOut();
387 sanityCheckWithTimeRange(true);
388
389 testDone();
390 });
391
392 })(); // Anonymous namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698