1 # Copyright 2014 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 from telemetry.core.backends.chrome import inspector_network 5 from telemetry.timeline import recording_options 6 from telemetry.unittest import tab_test_case 7 8 9 class InspectorNetworkTabTest(tab_test_case.TabTestCase): 10 class TestCase(object): 11 def __init__(self, monitoring = False, responses_count = 0, 12 subresources = None): 13 # Whether to monitor network for this case. 14 self.monitoring = monitoring 15 # Number of responses expected for this case. 16 self.responses_count = responses_count 17 # List of subresource links for this case. 18 self.subresources = subresources 19 20 def __init__(self, *args): 21 super(InspectorNetworkTabTest, self).__init__(*args) 22 23 def _NavigateAndGetHTTPResponseEvents(self, page, record_network=True): 24 opts = recording_options.TimelineRecordingOptions() 25 opts.record_network = record_network 26 self._tab.StartTimelineRecording(opts) 27 self.Navigate(page) 28 self._tab.StopTimelineRecording() 29 30 self.assertTrue(self._tab.timeline_model) 31 return self._tab.timeline_model.GetAllEventsOfName('HTTPResponse') 32 33 def testHTTPResponseTimelineRecorder(self): 34 tests = { 35 'blank.html': InspectorNetworkTabTest.TestCase(), 36 'green_rect.html': InspectorNetworkTabTest.TestCase( 37 monitoring=True, responses_count=1), 38 'image_decoding.html': InspectorNetworkTabTest.TestCase( 39 monitoring=True, responses_count=2, subresources=['image.png']), 40 } 41 for page, test in tests.iteritems(): 42 events = self._NavigateAndGetHTTPResponseEvents(page, test.monitoring) 43 self.assertEqual(test.responses_count, len(events)) 44 if not test.monitoring: 45 continue 46 47 # Verify required event fields 48 for event in events: 49 self.assertEqual('HTTPResponse', event.name) 50 resp = inspector_network.InspectorNetworkResponseData.FromTimelineEvent( 51 event) 52 self.assertLess(0.0, resp.timestamp) 53 54 self.assertTrue(resp.headers) 55 self.assertTrue(resp.headers['Content-Length']) 56 body, base64_encoded = resp.GetBody() 57 58 link = resp.url[resp.url.rfind('/') + 1 :] 59 self.assertTrue(link == page or link in test.subresources) 60 if link == page: 61 self.assertEqual(resp.GetHeader('Content-Type'), 'text/html') 62 self.assertTrue('<!DOCTYPE HTML>' in body) 63 self.assertFalse(base64_encoded) 64 else: 65 # We know this is the only subresource type in our setup. 66 self.assertEqual(resp.GetHeader('Content-Type'), 'image/png') 67 self.assertFalse('<!DOCTYPE HTML>' in body) 68 self.assertTrue(base64_encoded) 69 70 def testCacheableHTTPResponse(self): 71 # We know this page has one PNG image and its cacheable. 72 events = self._NavigateAndGetHTTPResponseEvents('image_decoding.html') 73 images_first = [] 74 for event in events: 75 resp = inspector_network.InspectorNetworkResponseData.FromTimelineEvent( 76 event) 77 if resp.GetHeader('Content-Type') == 'image/png': 78 images_first.append(resp) 79 80 self.assertEqual(1, len(images_first)) 81 self.assertFalse(images_first[0].served_from_cache) 82 83 events = self._NavigateAndGetHTTPResponseEvents('image_decoding.html') 84 images_second = [] 85 for event in events: 86 resp = inspector_network.InspectorNetworkResponseData.FromTimelineEvent( 87 event) 88 if resp.GetHeader('Content-Type') == 'image/png': 89 images_second.append(resp) 90 self.assertEqual(1, len(images_second)) 91 # On the second fetch, the image is served from cache. 92 self.assertTrue(images_second[0].served_from_cache) 93