<!DOCTYPE HTML>
<html>
<head>
<title>Test various interactions between fetch, service-workers and resource timing</title>
<meta charset="utf-8" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<link rel="help" href="https://w3c.github.io/resource-timing/" >
<!--
    This test checks that the different properties in a PerformanceResourceTimingEntry
    measure what they are supposed to measure according to spec.

    It is achieved by generating programmatic delays and redirects inside a service worker,
    and checking how the different metrics respond to the delays and redirects.

    The deltas are not measured precisely, but rather relatively to the delay.
    The delay needs to be long enough so that it's clear that what's measured is the test's
    programmatic delay and not arbitrary system delays.
-->
</head>

<body>
<script>

const delay = 200;
const absolutePath = `${base_path()}/simple.txt`
function toSequence({before, after, entry}) {
    /*
        The order of keys is the same as in this chart:
        https://w3c.github.io/resource-timing/#attribute-descriptions
    */
    const keys = [
        'startTime',
        'redirectStart',
        'redirectEnd',
        'workerStart',
        'fetchStart',
        'connectStart',
        'requestStart',
        'responseStart',
        'responseEnd'
    ];

    let cursor = before;
    const step = value => {
        // A zero/null value, reflect that in the sequence
        if (!value)
            return value;

        // Value is the same as before
        if (value === cursor)
            return "same";

        // Oops, value is in the wrong place
        if (value < cursor)
            return "back";

        // Delta is greater than programmatic delay, this is where the delay is measured.
        if ((value - cursor) >= delay)
            return "delay";

        // Some small delta, probably measuring an actual networking stack delay
        return "tick";
    }

    const res = keys.map(key => {
        const value = step(entry[key]);
        if (entry[key])
            cursor = entry[key];
        return [key, value];
    });

    return Object.fromEntries([...res, ['after', step(after)]]);
}
async function testVariant(t, variant) {
    const worker_url = 'resources/fetch-variants-worker.js';
    const url = encodeURIComponent(`simple.txt?delay=${delay}&variant=${variant}`);
    const scope = `resources/iframe-with-fetch-variants.html?url=${url}`;
    const registration = await service_worker_unregister_and_register(t, worker_url, scope);
    t.add_cleanup(() => registration.unregister());
    await wait_for_state(t, registration.installing, 'activated');
    const frame = await with_iframe(scope);
    t.add_cleanup(() => frame.remove());
    const result = await new Promise(resolve => window.addEventListener('message', message => {
        resolve(message.data);
    }))

    return toSequence(result);
}

promise_test(async t => {
    const result = await testVariant(t, 'redirect');
    assert_equals(result.redirectStart, 0);
}, 'Redirects done from within a service-worker should not be exposed to client ResourceTiming');

promise_test(async t => {
    const result = await testVariant(t, 'forward');
    assert_equals(result.connectStart, 'same');
}, 'Connection info from within a service-worker should not be exposed to client ResourceTiming');

promise_test(async t => {
    const result = await testVariant(t, 'forward');
    assert_not_equals(result.requestStart, 'back');
}, 'requestStart should never be before fetchStart');

promise_test(async t => {
    const result = await testVariant(t, 'delay-after-fetch');
    const whereIsDelayMeasured = Object.entries(result).find(r => r[1] === 'delay')[0];
    assert_equals(whereIsDelayMeasured, 'responseStart');
}, 'Delay from within service-worker (after internal fetching) should be accessible through `responseStart`');

promise_test(async t => {
    const result = await testVariant(t, 'delay-before-fetch');
    const whereIsDelayMeasured = Object.entries(result).find(r => r[1] === 'delay')[0];
    assert_equals(whereIsDelayMeasured, 'responseStart');
}, 'Delay from within service-worker (before internal fetching) should be measured before responseStart in the client ResourceTiming entry');
</script>

</body>
</html>
