Fix issue in about:net-internals with clicking on a column
[chromium-blink-merge.git] / chrome / test / data / webui / net_internals / events_view.js
blob0c0424bf2928e6d1c86e4c08bf36d9c11e5873f0
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']);
8 // Anonymous namespace
9 (function() {
11 // @return {Array.<object>} List of events for an abbreviated URL request.
12 function urlRequestEvents(id) {
13   return [
14     {
15       'phase': EventPhase.PHASE_BEGIN,
16       'source': {
17         'id': id,
18         'type': EventSourceType.URL_REQUEST
19       },
20       'time': '953534778',
21       'type': EventType.REQUEST_ALIVE
22     },
23     {
24       'params': {
25         'load_flags': 68223104,
26         'method': 'GET',
27         'priority': 4,
28         'url': 'http://www.google.com/'
29       },
30       'phase': EventPhase.PHASE_BEGIN,
31       'source': {
32         'id': id,
33         'type': EventSourceType.URL_REQUEST
34       },
35       'time': '953534792',
36       'type': EventType.URL_REQUEST_START_JOB
37     },
38     {
39       'phase': EventPhase.PHASE_END,
40       'source': {
41         'id': id,
42         'type': EventSourceType.URL_REQUEST
43       },
44       'time': '953534800',
45       'type': EventType.URL_REQUEST_START_JOB
46     },
47     {
48       'phase': EventPhase.PHASE_BEGIN,
49       'source': {
50         'id': id,
51         'type': EventSourceType.URL_REQUEST
52       },
53       'time': '953534906',
54       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST
55     },
56     {
57       'params': {
58         'headers': [
59           'Host: www.google.com',
60           'Connection: keep-alive',
61           'User-Agent: Mozilla/5.0',
62           'Accept: text/html',
63           'Accept-Encoding: gzip,deflate,sdch',
64           'Accept-Language: en-US,en;q=0.8',
65           'Accept-Charset: ISO-8859-1',
66           'X-Random-Header-With-Quotes: "Quoted String"""',
67         ],
68         'line': 'GET / HTTP/1.1\r\n'
69       },
70       'phase': EventPhase.PHASE_NONE,
71       'source': {
72         'id': id,
73         'type': EventSourceType.URL_REQUEST
74       },
75       'time': '953534910',
76       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST_HEADERS
77     },
78     {
79       'phase': EventPhase.PHASE_END,
80       'source': {
81         'id': id,
82         'type': EventSourceType.URL_REQUEST
83       },
84       'time': '953534915',
85       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST
86     },
87     {
88       'phase': EventPhase.PHASE_END,
89       'source': {
90         'id': id,
91         'type': EventSourceType.URL_REQUEST
92       },
93       'time': '953535567',
94       'type': EventType.REQUEST_ALIVE
95     }
96   ];
99 /**
100  * Tests the filters, both in terms of filtering correctly and UI.
101  */
102 TEST_F('NetInternalsTest', 'netInternalsEventsViewFilter', function() {
103   // Sets the filter and checks the results.
104   // @param {string} filter Filter to use.
105   // @param {Array.<boolean>} matches Ordered list of whether or not each source
106   //     matches |filter|.  Order must match display order after applying the
107   //     filter.
108   function checkFilter(filter, matches) {
109     EventsView.getInstance().setFilterText_(filter);
111     var postFilter = 0;
112     for (var i = 0; i < matches.length; ++i) {
113       if (matches[i])
114         ++postFilter;
115     }
117     // Updating the display is normally done asynchronously, so have to manually
118     // call update function to check displayed event count.
119     EventsView.getInstance().repaintFilterCounter_();
121     expectEquals(postFilter + ' of ' + matches.length,
122                  $(EventsView.FILTER_COUNT_ID).innerText,
123                  filter);
125     var tbody = $(EventsView.TBODY_ID);
126     assertEquals(matches.length, tbody.childElementCount, filter);
128     var visibleCount = 0;
129     for (var i = 0; i < tbody.childElementCount; ++i) {
130       expectEquals(matches[i],
131                    NetInternalsTest.nodeIsVisible(tbody.children[i]),
132                    filter);
133     }
134   }
136   EventsTracker.getInstance().deleteAllLogEntries();
137   checkFilter('', [], 0);
139   // A completed request.
140   g_browser.receivedLogEntries(urlRequestEvents(31));
141   checkFilter('', [true], 1);
143   // An incomplete request.
144   g_browser.receivedLogEntries(urlRequestEvents(56).slice(0, 3));
145   checkFilter('', [true, true], 2);
147   // Filters used alone and in all combinations.
148   // |text| is the string to add to the filter.
149   // |matches| is a 2-element array of booleans indicating which of the two
150   //      requests passes the filter.
151   var testFilters = [
152     {text: 'http://www.google.com', matches: [true, true] },
153     {text: 'MyMagicPony', matches: [false, false] },
154     {text: 'type:URL_REQUEST', matches: [true, true] },
155     {text: 'type:SOCKET,URL_REQUEST', matches: [true, true] },
156     {text: 'type:SOCKET', matches: [false, false] },
157     {text: '-type:PONY', matches: [true, true] },
158     {text: '-type:URL_REQUEST', matches: [false, false] },
159     {text: 'id:31,32', matches: [true, false] },
160     {text: '-id:31,32', matches: [false, true] },
161     {text: 'id:32,56,', matches: [false, true] },
162     {text: '-is:active', matches: [true, false] },
163     {text: 'is:active', matches: [false, true] },
164     {text: '-is:error', matches: [true, true] },
165     {text: 'is:error', matches: [false, false] },
166     // Partial match of source type.
167     {text: 'URL_REQ', matches: [true, true] },
168     // Partial match of event type type.
169     {text: 'SEND_REQUEST', matches: [true, false] },
170     // Check that ":" works in strings.
171     { text: 'Host:', matches: [true, false] },
172     { text: '::', matches: [false, false] },
173     // Test quotes.
174     { text: '"Quoted String"', matches: [true, false] },
175     { text: '"Quoted source"', matches: [false, false] },
176     { text: '"\\"Quoted String\\""', matches: [true, false] },
177     { text: '"\\"\\"Quoted String\\""', matches: [false, false] },
178     { text: '\\"\\"\\"', matches: [true, false] },
179     { text: '\\"\\"\\"\\"', matches: [false, false] },
180     { text: '"Host: www.google.com"', matches: [true, false], },
181     { text: 'Connection:" keep-alive"', matches: [true, false], },
182     { text: '-Connection:" keep-alive"', matches: [false, true], },
183     { text: '"Host: GET"', matches: [false, false] },
184     // Make sure sorting has no effect on filters.  Sort by ID so order is
185     // preserved.
186     { text: 'sort:"id"', matches: [true, true] },
187     { text: '-sort:"shoe size"', matches: [true, true] },
188     { text: '"-sort:shoe size"', matches: [false, false] },
189   ];
191   for (var filter1 = 0; filter1 < testFilters.length; ++filter1) {
192     checkFilter(testFilters[filter1].text, testFilters[filter1].matches);
193     // Check |filter1| in combination with all the other filters.
194     for (var filter2 = 0; filter2 < testFilters.length; ++filter2) {
195       var matches = [];
196       for (var i = 0; i < testFilters[filter1].matches.length; ++i) {
197         // The merged filter matches an entry if both individual filters do.
198         matches[i] = testFilters[filter1].matches[i] &&
199                      testFilters[filter2].matches[i];
200       }
202       checkFilter(testFilters[filter1].text + ' ' + testFilters[filter2].text,
203                   matches,
204                   1);
205     }
206   }
208   // Tests with unmatched quotes.  Unlike the strings above, combining them with
209   // other filters is not the same as applying both filters independently.
210   checkFilter('"Quoted String', [true, false]);
211   checkFilter('"Quoted String source', [false, false]);
212   checkFilter('Quoted" String', [true, false]);
213   checkFilter('Quoted" source', [false, false]);
214   checkFilter('Quoted "String', [true, false]);
216   // Test toggling sort method, without any filters.
217   var eventsView = EventsView.getInstance();
218   eventsView.setFilterText_('');
219   $(EventsView.SORT_BY_DESCRIPTION_ID).click();
220   expectEquals('sort:desc', eventsView.getFilterText_());
221   $(EventsView.SORT_BY_DESCRIPTION_ID).click();
222   expectEquals('-sort:desc', eventsView.getFilterText_());
223   $(EventsView.SORT_BY_ID_ID).click();
224   expectEquals('sort:id', eventsView.getFilterText_());
226   // Sort by default is by ID, so toggling ID when there's no filter results in
227   // sort:-id.
228   eventsView.setFilterText_('');
229   $(EventsView.SORT_BY_ID_ID).click();
230   expectEquals('-sort:id', eventsView.getFilterText_());
231   $(EventsView.SORT_BY_ID_ID).click();
232   expectEquals('sort:id', eventsView.getFilterText_());
234   // Test toggling sort method with filters.
235   eventsView.setFilterText_('text');
236   $(EventsView.SORT_BY_ID_ID).click();
237   expectEquals('-sort:id text', eventsView.getFilterText_());
238   $(EventsView.SORT_BY_ID_ID).click();
239   expectEquals('sort:id text', eventsView.getFilterText_());
240   $(EventsView.SORT_BY_SOURCE_TYPE_ID).click();
241   expectEquals('sort:source text', eventsView.getFilterText_());
242   eventsView.setFilterText_('text sort:id "more text"');
243   $(EventsView.SORT_BY_ID_ID).click();
244   expectEquals('-sort:id text "more text"', eventsView.getFilterText_());
246   testDone();
249 })();  // Anonymous namespace