<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="../resources/inspector-test.js"></script>
<script>
function createRequest() {
    let img = document.createElement("img");
    img.src = "https://localhost:8443/resources/square100.png";
    document.body.appendChild(img);
}

function test()
{
    let suite = InspectorTest.createAsyncSuite("ResourceTimingData");

    suite.addTestCase({
        name: "CheckResourceTimingInformationForResource",
        description: "Check if a resource has timing information.",
        test(resolve, reject) {
            Promise.all([
                WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded),
                WI.Resource.awaitEvent(WI.Resource.Event.ResponseReceived),
                WI.Resource.awaitEvent(WI.Resource.Event.LoadingDidFinish)
            ])
            .then(([resourceWasAddedEvent, responseReceivedEvent, loadingDidFinishEvent]) => {
                let resource = resourceWasAddedEvent.data.resource;

                InspectorTest.expectThat(resource instanceof WI.Resource, "Resource should be created.");
                InspectorTest.expectThat(resource === responseReceivedEvent.target, "Added Resource received a response.");
                InspectorTest.expectThat(resource === loadingDidFinishEvent.target, "Added Resource did finish loading.");

                let timingData = resource.timingData;
                InspectorTest.expectThat(timingData instanceof WI.ResourceTimingData, "Newly added resource should have a resource timing model.");
                InspectorTest.expectThat(timingData.startTime > 0, "Resource should have a start time.");
                InspectorTest.expectThat(timingData.requestStart > 0, "Resource should have a request start time.");
                InspectorTest.expectThat(timingData.responseStart > 0, "Resource should have a response start time.");

                InspectorTest.expectThat(typeof timingData.domainLookupStart === "number" && typeof timingData.domainLookupEnd === "number", "domainLookupStart and domainLookupEnd should both be NaN or a number.");
                InspectorTest.expectThat(typeof timingData.connectStart === "number" && typeof timingData.connectStart === "number", "connectStart and connectEnd should both be NaN or a number.");

                InspectorTest.expectThat(timingData.startTime <= timingData.requestStart, "requestStart should come after startTime.");
                InspectorTest.expectThat(isNaN(timingData.secureConnectionStart) || timingData.connectStart <= timingData.secureConnectionStart, "A secure connection should be reused or secureConnectionStart should come after connectStart.");
                InspectorTest.expectThat(timingData.requestStart <= timingData.responseStart, "responseStart should come after requestStart.");
                InspectorTest.expectThat(timingData.responseStart <= timingData.responseEnd, "responseEnd should come after responseStart.");
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("createRequest()");
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
    <p>Tests that a resource has timing information.</p>
</body>
</html>
