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 // @return {Array.<object>} List of events for an abbreviated URL request.
12 function urlRequestEvents(id
) {
15 'phase': EventPhase
.PHASE_BEGIN
,
18 'type': EventSourceType
.URL_REQUEST
21 'type': EventType
.REQUEST_ALIVE
25 'load_flags': 68223104,
28 'url': 'http://www.google.com/'
30 'phase': EventPhase
.PHASE_BEGIN
,
33 'type': EventSourceType
.URL_REQUEST
36 'type': EventType
.URL_REQUEST_START_JOB
39 'phase': EventPhase
.PHASE_END
,
42 'type': EventSourceType
.URL_REQUEST
45 'type': EventType
.URL_REQUEST_START_JOB
48 'phase': EventPhase
.PHASE_BEGIN
,
51 'type': EventSourceType
.URL_REQUEST
54 'type': EventType
.HTTP_TRANSACTION_SEND_REQUEST
59 'Host: www.google.com',
60 'Connection: keep-alive',
61 'User-Agent: Mozilla/5.0',
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"""',
68 'line': 'GET / HTTP/1.1\r\n'
70 'phase': EventPhase
.PHASE_NONE
,
73 'type': EventSourceType
.URL_REQUEST
76 'type': EventType
.HTTP_TRANSACTION_SEND_REQUEST_HEADERS
79 'phase': EventPhase
.PHASE_END
,
82 'type': EventSourceType
.URL_REQUEST
85 'type': EventType
.HTTP_TRANSACTION_SEND_REQUEST
88 'phase': EventPhase
.PHASE_END
,
91 'type': EventSourceType
.URL_REQUEST
94 'type': EventType
.REQUEST_ALIVE
100 * Tests the filters, both in terms of filtering correctly and UI.
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
108 function checkFilter(filter
, matches
) {
109 EventsView
.getInstance().setFilterText_(filter
);
112 for (var i
= 0; i
< matches
.length
; ++i
) {
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
,
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
]),
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.
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] },
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
186 { text
: 'sort:"id"', matches
: [true, true] },
187 { text
: '-sort:"shoe size"', matches
: [true, true] },
188 { text
: '"-sort:shoe size"', matches
: [false, false] },
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
) {
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
];
202 checkFilter(testFilters
[filter1
].text
+ ' ' + testFilters
[filter2
].text
,
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
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_());
249 })(); // Anonymous namespace