diff options
Diffstat (limited to 'testing/web-platform/tests/resource-timing/test_resource_timing.js')
-rw-r--r-- | testing/web-platform/tests/resource-timing/test_resource_timing.js | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/testing/web-platform/tests/resource-timing/test_resource_timing.js b/testing/web-platform/tests/resource-timing/test_resource_timing.js new file mode 100644 index 0000000000..598a727bf8 --- /dev/null +++ b/testing/web-platform/tests/resource-timing/test_resource_timing.js @@ -0,0 +1,228 @@ +var TEST_ALLOWED_TIMING_DELTA = 20; + +var waitTimer; +var expectedEntries = {}; + +var initiatorTypes = ["iframe", "img", "link", "script", "xmlhttprequest"]; + +var tests = {}; +setup(function() { + for (var i in initiatorTypes) { + var type = initiatorTypes[i]; + tests[type] = { + "entry": async_test("window.performance.getEntriesByName() and window.performance.getEntriesByNameType() return same data (" + type + ")"), + "simple_attrs": async_test("PerformanceEntry has correct name, initiatorType, startTime, and duration (" + type + ")"), + "timing_attrs": async_test("PerformanceEntry has correct order of timing attributes (" + type + ")"), + "network_attrs": async_test("PerformanceEntry has correct network transfer attributes (" + type + ")"), + "protocol": async_test("PerformanceEntry has correct protocol attribute (" + type + ")") + }; + } +}); + +function resolve(path) { + var a = document.createElement("a"); + a.href = path; + return a.href; +} + +onload = function() +{ + // check that the Performance Timeline API exists + test(function() { + assert_idl_attribute(window.performance, "getEntriesByName", + "window.performance.getEntriesByName() is defined"); + }); + test(function() { + assert_idl_attribute(window.performance, "getEntriesByType", + "window.performance.getEntriesByType() is defined"); + }); + test(function() { + assert_idl_attribute(window.performance, "getEntries", + "window.performance.getEntries() is defined"); + }); + + var expected_entry; + var url; + var type; + var startTime; + var element; + var encodedBodySize; + var decodedBodySize; + for (var i in initiatorTypes) { + startTime = window.performance.now(); + type = initiatorTypes[i]; + if (type != "xmlhttprequest") { + element = document.createElement(type); + } else { + element = null; + } + switch (type) { + case "iframe": + url = resolve("resources/resource_timing_test0.html"); + element.src = url; + encodedBodySize = 215; + decodedBodySize = 215; + break; + case "img": + url = resolve("resources/resource_timing_test0.png"); + element.src = url; + encodedBodySize = 249; + decodedBodySize = 249; + break; + case "link": + element.rel = "stylesheet"; + url = resolve("resources/resource_timing_test0.css"); + element.href = url; + encodedBodySize = 44; + decodedBodySize = 44; + break; + case "script": + element.type = "text/javascript"; + url = resolve("resources/resource_timing_test0.js"); + element.src = url; + encodedBodySize = 133; + decodedBodySize = 133; + break; + case "xmlhttprequest": + var xmlhttp = new XMLHttpRequest(); + url = resolve("resources/gzip_xml.py"); + xmlhttp.open('GET', url, true); + xmlhttp.send(); + encodedBodySize = 112; + decodedBodySize = 125; + break; + } + + expected_entry = {name:url, + startTime: startTime, + initiatorType: type, + encodedBodySize: encodedBodySize, + decodedBodySize: decodedBodySize + }; + + switch (type) { + case "link": + poll_for_stylesheet_load(expected_entry); + document.body.appendChild(element); + break; + case "xmlhttprequest": + xmlhttp.onload = (function(entry) { + return function (event) { + resource_load(entry); + }; + })(expected_entry); + break; + default: + element.onload = (function(entry) { + return function (event) { + resource_load(entry); + }; + })(expected_entry); + document.body.appendChild(element); + } + + } +}; + +function poll_for_stylesheet_load(expected_entry) { + var t = tests[expected_entry.initiatorType]; + + function inner() { + for(var i=0; i<document.styleSheets.length; i++) { + var sheet = document.styleSheets[i]; + if (sheet.href === expected_entry.name) { + try { + // try/catch avoids throwing if sheet object exists before it is loaded, + // which is a bug, but not what we are trying to test here. + var hasRules = sheet.cssRules.length > 0; + } catch(e) { + hasRules = false; + } + if (hasRules) { + t["entry"].step_timeout(function() { + resource_load(expected_entry); + }, 200); + return; + } + } + } + t["entry"].step_timeout(inner, 100); + } + inner(); +} + +function resource_load(expected) +{ + var t = tests[expected.initiatorType]; + + t["entry"].step(function() { + var entries_by_name = window.performance.getEntriesByName(expected.name); + assert_equals(entries_by_name.length, 1, "should have a single entry for each resource (without type)"); + var entries_by_name_type = window.performance.getEntriesByName(expected.name, "resource"); + assert_equals(entries_by_name_type.length, 1, "should have a single entry for each resource (with type)"); + assert_not_equals(entries_by_name, entries_by_name_type, "values should be copies"); + for (p in entries_by_name[0]) { + var assertMethod = assert_equals + if (Array.isArray(entries_by_name[0][p]) && Array.isArray(entries_by_name_type[0][p])) { + assertMethod = assert_array_equals + } + assertMethod(entries_by_name[0][p], entries_by_name_type[0][p], "Property " + p + " should match"); + } + this.done(); + }); + + t["simple_attrs"].step(function() { + var actual = window.performance.getEntriesByName(expected.name)[0]; + var expected_type = expected.initiatorType; + assert_equals(actual.name, expected.name); + assert_equals(actual.initiatorType, expected_type); + assert_equals(actual.entryType, "resource"); + assert_greater_than_equal(actual.startTime, expected.startTime, "startTime is after the script to initiate the load ran"); + assert_equals(actual.duration, (actual.responseEnd - actual.startTime)); + this.done(); + }); + + t["timing_attrs"].step(function test() { + const entries = window.performance.getEntriesByName(expected.name); + assert_equals(entries.length, 1, 'There should be a single matching entry'); + const actual = entries[0]; + if (window.location.protocol == "http:") { + assert_equals(actual.secureConnectionStart, 0, 'secureConnectionStart should be 0 in http'); + } else { + assert_greater_than(actual.secureConnectionStart, 0, 'secureConnectionStart should not be 0 in https'); + } + + assert_equals(actual.redirectStart, 0, 'redirectStart should be 0'); + assert_equals(actual.redirectEnd, 0, 'redirectEnd should be 0'); + assert_equals(actual.fetchStart, actual.startTime, 'fetchStart is equal to startTime'); + assert_greater_than_equal(actual.domainLookupStart, actual.fetchStart, 'domainLookupStart after fetchStart'); + assert_greater_than_equal(actual.domainLookupEnd, actual.domainLookupStart, 'domainLookupEnd after domainLookupStart'); + assert_greater_than_equal(actual.connectStart, actual.domainLookupEnd, 'connectStart after domainLookupEnd'); + assert_greater_than_equal(actual.connectEnd, actual.connectStart, 'connectEnd after connectStart'); + assert_true(actual.secureConnectionStart == 0 || actual.secureConnectionStart <= actual.requestStart, + "secureConnectionStart should be either 0 or smaller than/equals to requestStart") + assert_greater_than_equal(actual.requestStart, actual.connectEnd, 'requestStart after connectEnd'); + assert_greater_than_equal(actual.responseStart, actual.requestStart, 'responseStart after requestStart'); + assert_greater_than_equal(actual.responseEnd, actual.responseStart, 'responseEnd after responseStart'); + this.done(); + }); + + t["network_attrs"].step(function test() { + var actual = window.performance.getEntriesByName(expected.name)[0]; + assert_equals(actual.encodedBodySize, expected.encodedBodySize, "encodedBodySize size"); + assert_equals(actual.decodedBodySize, expected.decodedBodySize, "decodedBodySize size"); + + // Transfer size will vary from browser to browser based on default headers, etc. This + // test verifies that transferSize for uncached resources is greater than on-the-wire + // body size. + assert_greater_than(actual.transferSize, actual.encodedBodySize, "transferSize size"); + this.done(); + }); + + t["protocol"].step(function() { + var actual = window.performance.getEntriesByName(expected.name)[0]; + assert_equals(actual.nextHopProtocol, "http/1.1", "expected protocol"); + this.done(); + }); + +} |