Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / test / data / webui / net_internals / timeline_view.js
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 // Include test fixture.
6 GEN_INCLUDE(['net_internals_test.js']);
7
8 // Anonymous namespace
9 (function() {
10
11 // Range of time set on a log once loaded used by sanity checks.
12 // Used by sanityCheckWithTimeRange.
13 var startTime = null;
14 var endTime = null;
15
16 function timelineView() {
17   return TimelineView.getInstance();
18 }
19
20 function graphView() {
21   return timelineView().graphView_;
22 }
23
24 function scrollbar() {
25   return graphView().scrollbar_;
26 }
27
28 function canvas() {
29   return graphView().canvas_;
30 }
31
32 /**
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.
36  *
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.
39  *
40  * @param {int} startTime Time of the begin event.
41  * @param {int} endTime Time of the end event.
42  * @extends {NetInternalsTest.Task}
43  */
44 function LoadLogWithNewEventsTask(startTime, endTime) {
45   NetInternalsTest.Task.call(this);
46   this.startTime_ = startTime;
47   this.endTime_ = endTime;
48 }
49
50 LoadLogWithNewEventsTask.prototype = {
51   __proto__: NetInternalsTest.Task.prototype,
52
53   /**
54    * Starts creating a log dump.
55    */
56   start: function() {
57     log_util.createLogDumpAsync('test', this.onLogDumpCreated.bind(this), true);
58   },
59
60   /**
61    * Modifies the log dump and loads it.
62    */
63   onLogDumpCreated: function(logDumpText) {
64     var logDump = JSON.parse(logDumpText);
65
66     logDump.constants.timeTickOffset = '0';
67     logDump.events = [];
68
69     var source = new NetInternalsTest.Source(1, EventSourceType.SOCKET);
70     logDump.events.push(
71         NetInternalsTest.createBeginEvent(source, EventType.SOCKET_ALIVE,
72                                           this.startTime_, null));
73     logDump.events.push(
74         NetInternalsTest.createMatchingEndEvent(logDump.events[0],
75                                                 this.endTime_, null));
76     logDumpText = JSON.stringify(logDump);
77
78     assertEquals('Log loaded.', log_util.loadLogFile(logDumpText));
79
80     endTime = this.endTime_;
81     startTime = this.startTime_;
82     if (startTime >= endTime)
83       --startTime;
84
85     sanityCheckWithTimeRange(false);
86
87     this.onTaskDone();
88   }
89 };
90
91 /**
92  * Checks certain invariant properties of the TimelineGraphView and the
93  * scroll bar.
94  */
95 function sanityCheck() {
96   expectLT(graphView().startTime_, graphView().endTime_);
97   expectLE(0, scrollbar().getPosition());
98   expectLE(scrollbar().getPosition(), scrollbar().getRange());
99 }
100
101 /**
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.
109  */
110 function sanityCheckWithTimeRange(expectUpdateTimer) {
111   if (!expectUpdateTimer) {
112     expectEquals(null, timelineView().updateIntervalId_);
113   } else {
114     expectNotEquals(null, timelineView().updateIntervalId_);
115   }
116   assertNotEquals(startTime, null);
117   assertNotEquals(endTime, null);
118   expectEquals(startTime, graphView().startTime_);
119   expectEquals(endTime, graphView().endTime_);
120   sanityCheck(false);
121 }
122
123 /**
124  * Checks what sanityCheck does, but also checks that |startTime| and |endTime|
125  * are the same as those used by the graph.
126  */
127 function sanityCheckNotUpdating() {
128   expectEquals(null, timelineView().updateIntervalId_);
129   sanityCheckWithTimeRange();
130 }
131
132 /**
133  * Simulates mouse wheel movement over the canvas element.
134  * @param {number} ticks Number of mouse wheel ticks to simulate.
135  */
136 function mouseZoom(ticks) {
137   var scrollbarStartedAtEnd =
138       (scrollbar().getRange() == scrollbar().getPosition());
139
140   var event = new WheelEvent('mousewheel', {deltaX: 0, deltaY: -ticks});
141   canvas().dispatchEvent(event);
142
143   // If the scrollbar started at the end of the range, make sure it ends there
144   // as well.
145   if (scrollbarStartedAtEnd)
146     expectEquals(scrollbar().getRange(), scrollbar().getPosition());
147
148   sanityCheck();
149 }
150
151 /**
152  * Simulates moving the mouse wheel up.
153  * @param {number} ticks Number of mouse wheel ticks to simulate.
154  */
155 function mouseZoomIn(ticks) {
156   assertGT(ticks, 0);
157   var oldScale = graphView().scale_;
158   var oldRange = scrollbar().getRange();
159
160   mouseZoom(ticks);
161
162   if (oldScale == graphView().scale_) {
163     expectEquals(oldScale, TimelineGraphView.MIN_SCALE);
164   } else {
165     expectLT(graphView().scale_, oldScale);
166   }
167   expectGE(scrollbar().getRange(), oldRange);
168 }
169
170 /**
171  * Simulates moving the mouse wheel down.
172  * @param {number} ticks Number of mouse wheel ticks to simulate.
173  */
174 function mouseZoomOut(ticks) {
175   assertGT(ticks, 0);
176   var oldScale = graphView().scale_;
177   var oldRange = scrollbar().getRange();
178
179   mouseZoom(-ticks);
180
181   expectGT(graphView().scale_, oldScale);
182   expectLE(scrollbar().getRange(), oldRange);
183 }
184
185 /**
186  * Simulates zooming all the way with multiple mouse wheel events.
187  */
188 function mouseZoomAllTheWayIn() {
189   expectLT(TimelineGraphView.MIN_SCALE, graphView().scale_);
190   while (graphView().scale_ != TimelineGraphView.MIN_SCALE)
191     mouseZoomIn(8);
192   // Verify that zooming in when already at max zoom works.
193   mouseZoomIn(1);
194 }
195
196 /**
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.
200  *
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.
203  *
204  * @param {int} position Position to scroll to.
205  * @extends {NetInternalsTest.Task}
206  */
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;
214 }
215
216 MouseScrollTask.prototype = {
217   __proto__: NetInternalsTest.Task.prototype,
218
219   start: function() {
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_);
226       this.onTaskDone();
227       return;
228     }
229
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;
235       return;
236     }
237
238     window.setTimeout(this.startScrolling_.bind(this), 0);
239   },
240
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);
246
247     if (this.waitingToStart_) {
248       this.start();
249       return;
250     }
251
252     assertEquals(this.position_, scrollbar().getNode().scrollLeft);
253     assertEquals(this.position_, scrollbar().getPosition());
254
255     sanityCheck();
256     this.onTaskDone();
257   },
258
259   startScrolling_: function() {
260     scrollbar().getNode().scrollLeft = this.position_;
261   }
262 };
263
264 /**
265  * Tests setting and updating range.
266  */
267 TEST_F('NetInternalsTest', 'netInternalsTimelineViewRange', function() {
268   NetInternalsTest.switchToView('timeline');
269
270   // Set startTime/endTime for sanity checks.
271   startTime = graphView().startTime_;
272   endTime = graphView().endTime_;
273   sanityCheckWithTimeRange(true);
274
275   startTime = 0;
276   endTime = 10;
277   graphView().setDateRange(new Date(startTime), new Date(endTime));
278   sanityCheckWithTimeRange(true);
279
280   endTime = (new Date()).getTime();
281   graphView().updateEndDate();
282
283   expectGE(graphView().endTime_, endTime);
284   sanityCheck();
285
286   testDone();
287 });
288
289 /**
290  * Tests using the scroll bar.
291  */
292 TEST_F('NetInternalsTest', 'netInternalsTimelineViewScrollbar', function() {
293   // The range we want the graph to have.
294   var expectedGraphRange = canvas().width;
295
296   function checkGraphRange() {
297     expectEquals(expectedGraphRange, scrollbar().getRange());
298   }
299
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|.
303   taskQueue.addTask(
304       new LoadLogWithNewEventsTask(
305           55,
306           55 + graphView().scale_ * (canvas().width + expectedGraphRange)));
307   taskQueue.addFunctionTask(
308       NetInternalsTest.switchToView.bind(null, 'timeline'));
309   taskQueue.addFunctionTask(checkGraphRange);
310
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));
315
316   taskQueue.addFunctionTask(checkGraphRange);
317   taskQueue.addFunctionTask(sanityCheckWithTimeRange.bind(null, false));
318   taskQueue.run();
319 });
320
321 /**
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.
324  */
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);
330
331     // Make sure everything's still fine when we switch to another view.
332     NetInternalsTest.switchToView('events');
333     sanityCheckWithTimeRange(false);
334   }
335
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);
340   taskQueue.run();
341 });
342
343 /**
344  * Zooms out twice, and then zooms in once.
345  */
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');
350     mouseZoomOut(1);
351     mouseZoomOut(1);
352     mouseZoomIn(1);
353     sanityCheckWithTimeRange(false);
354   }
355
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);
360   taskQueue.run();
361 });
362
363 /**
364  * Zooms in as much as allowed, and zooms out once.
365  */
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();
371     mouseZoomOut(1);
372     sanityCheckWithTimeRange(false);
373   }
374
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);
379   taskQueue.run();
380 });
381
382 /**
383  * Tests case of all events having the same time.
384  */
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');
389     mouseZoomOut(1);
390     mouseZoomAllTheWayIn();
391     mouseZoomOut(1);
392     sanityCheckWithTimeRange(false);
393   }
394
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);
399   taskQueue.run();
400 });
401
402 /**
403  * Tests case of having no events.  Runs synchronously.
404  */
405 TEST_F('NetInternalsTest', 'netInternalsTimelineViewNoEvents', function() {
406   // Click the button to clear all the captured events, and then switch to
407   // timeline
408   $(CaptureView.RESET_BUTTON_ID).click();
409   NetInternalsTest.switchToView('timeline');
410
411   // Set startTime/endTime for sanity checks.
412   startTime = graphView().startTime_;
413   endTime = graphView().endTime_;
414
415   sanityCheckWithTimeRange(true);
416
417   mouseZoomOut(1);
418   sanityCheckWithTimeRange(true);
419
420   mouseZoomAllTheWayIn();
421   sanityCheckWithTimeRange(true);
422
423   mouseZoomOut(1);
424   sanityCheckWithTimeRange(true);
425
426   testDone();
427 });
428
429 })();  // Anonymous namespace