Revision e8c4654cef692388e68e8ded7a9316d6bd613570 authored by Darren Shen on 06 April 2018, 07:51:02 UTC, committed by Chromium WPT Sync on 06 April 2018, 07:51:02 UTC
We cannot support background-repeat and background-position yet because
they are both implemented as shorthands in Blink, but are not shorthands
in the spec.

We'd need to refactor the existing code to allow shorthands to reify
as proper Typed OM objects. There are also some tricky bits to support
styleMap.set with shorthands given a proper Typed OM object.

Bug: 820299
Change-Id: I064ce37a48bee3d73965b66b323e20abf5a9099f
Reviewed-on: https://chromium-review.googlesource.com/994593
Commit-Queue: Darren Shen <shend@chromium.org>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#548705}
1 parent d6a82fd
Raw File
test_resource_timing.js
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];

        // Debugging bug 1263428
        // Feel free to remove/overwrite this piece of code
        if (actual.connectStart < actual.domainLookupEnd) {
            assert_true(false, "actual: "+JSON.stringify(actual));
        }

        assert_equals(actual.redirectStart, 0, 'redirectStart should be 0');
        assert_equals(actual.redirectEnd, 0, 'redirectEnd should be 0');
        assert_true(actual.secureConnectionStart == undefined ||
                    actual.secureConnectionStart == 0, 'secureConnectionStart should be 0 or undefined');
        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_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();
    });

}
back to top