
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>window.performance User Timing measure() method is working properly</title>
        <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
        <link rel="help" href="https://w3c.github.io/user-timing/#dom-performance-measure"/>
        <script src="/resources/testharness.js"></script>
        <script src="/resources/testharnessreport.js"></script>
        <script src="/common/performance-timeline-utils.js"></script>
        <script src="resources/webperftestharness.js"></script>

    <script>
        // test data
        var startMarkName = "mark_start";
        var startMarkValue;
        var endMarkName = "mark_end";
        var endMarkValue;
        var measures;
        var testThreshold = 20;

        // test measures
        var measureTestDelay = 200;
        var TEST_MEASURES =
        [
            {
                name:                   "measure_no_start_no_end",
                startMark:              undefined,
                endMark:                undefined,
                startTime:              undefined,
                duration:               undefined,
                entryType:              "measure",
                entryMatch:             undefined,
                order:                  undefined,
                found:                  false
            },
            {
                name:                   "measure_start_no_end",
                startMark:              "mark_start",
                endMark:                undefined,
                startTime:              undefined,
                duration:               undefined,
                entryType:              "measure",
                entryMatch:             undefined,
                order:                  undefined,
                found:                  false
            },
            {
                name:                   "measure_start_end",
                startMark:              "mark_start",
                endMark:                "mark_end",
                startTime:              undefined,
                duration:               undefined,
                entryType:              "measure",
                entryMatch:             undefined,
                order:                  undefined,
                found:                  false
            },
            {
                name:                   "measure_no_start_end",
                startMark:              undefined,
                endMark:                "mark_end",
                startTime:              undefined,
                duration:               undefined,
                entryType:              "measure",
                entryMatch:             undefined,
                order:                  undefined,
                found:                  false
            },
            // intentional duplicate of the first measure, used to confirm names can be re-used
            {
                name:                   "measure_no_start_no_end",
                startMark:              undefined,
                endMark:                undefined,
                startTime:              undefined,
                duration:               undefined,
                entryType:              "measure",
                entryMatch:             undefined,
                order:                  undefined,
                found:                  false
            }
        ];
        // the index of the duplicate "measure_no_start_no_end"
        const duplicate_index = TEST_MEASURES.map(m=>m.name).lastIndexOf('measure_no_start_no_end');

        setup({explicit_done: true});

        test_namespace();

        function onload_test()
        {
            // test for existence of User Timing and Performance Timeline interface
            if (!has_required_interfaces())
            {
                test_true(false,
                          "The User Timing and Performance Timeline interfaces, which are required for this test, " +
                          "are defined.");

                done();
            }
            else
            {
                // create the start mark for the test measures
                window.performance.mark(startMarkName);

                // get the start mark's value
                startMarkValue = window.performance.getEntriesByName(startMarkName)[0].startTime;

                // create the test end mark using the test delay; this will allow for a significant difference between
                // the mark values that should be represented in the duration of measures using these marks
                step_timeout(measure_test_cb, measureTestDelay);
            }
        }

        function measure_test_cb()
        {
            // create the end mark for the test measures
            window.performance.mark(endMarkName);

            // get the end mark's value
            endMarkValue = window.performance.getEntriesByName(endMarkName)[0].startTime;

            // loop through all measure scenarios and create the corresponding measures
            for (var i in TEST_MEASURES)
            {
                var scenario = TEST_MEASURES[i];

                if (scenario.startMark == undefined && scenario.endMark == undefined)
                {
                    // both startMark and endMark are undefined, don't provide either parameters
                    window.performance.measure(scenario.name);

                    // when startMark isn't provided to the measure() call, a DOMHighResTimeStamp corresponding
                    // to the navigationStart attribute with a timebase of the same attribute is used; this is
                    // equivalent to 0
                    scenario.startTime = 0;

                    // when endMark isn't provided to the measure() call, a DOMHighResTimeStamp corresponding to
                    // the current time with a timebase of the navigationStart attribute is used
                    scenario.duration = (new Date()) - window.performance.timing.navigationStart;
                }
                else if (scenario.startMark != undefined && scenario.endMark == undefined)
                {
                    // only startMark is defined, provide startMark and don't provide endMark
                    window.performance.measure(scenario.name, scenario.startMark);

                    // when startMark is provided to the measure() call, the value of the mark whose name is
                    // provided is used for the startMark
                    scenario.startTime = startMarkValue;

                    // when endMark isn't provided to the measure() call, a DOMHighResTimeStamp corresponding to
                    // the current time with a timebase of the navigationStart attribute is used
                    scenario.duration = window.performance.now() -
                                                startMarkValue;
                }
                else if (scenario.startMark != undefined && scenario.endMark != undefined)
                {
                    // both startMark and endMark are defined, provide both parameters
                    window.performance.measure(scenario.name, scenario.startMark, scenario.endMark);

                    // when startMark is provided to the measure() call, the value of the mark whose name is
                    // provided is used for the startMark
                    scenario.startTime = startMarkValue;

                    // when endMark is provided to the measure() call, the value of the mark whose name is
                    // provided is used for the endMark
                    scenario.duration = endMarkValue - startMarkValue;
                }
                else if (scenario.startMark == undefined && scenario.endMark != undefined)
                {
                    // endMark is defined but startMark is undefined, provide both parameters
                    window.performance.measure(scenario.name, scenario.startMark, scenario.endMark);

                    // when startMark isn't provided to the measure() call, a DOMHighResTimeStamp corresponding
                    // to the navigationStart attribute with a timebase of the same attribute is used; this is
                    // equivalent to 0
                    scenario.startTime = 0;

                    // when endMark is provided to the measure() call, the value of the mark whose name is
                    // provided is used for the endMark
                    scenario.duration = endMarkValue;
                } else
                {
                    test_true(false, 'Test measure scenario unhandled');
                }
            }

            // test that expected measures are returned by getEntriesByName
            for (var i in TEST_MEASURES)
            {
                entries = window.performance.getEntriesByName(TEST_MEASURES[i].name);
                // for all test measures, the test will be validate the test measure against the first entry returned
                // by getEntriesByName(), except for the last measure, where since it is a duplicate measure, the test
                // will validate it against the second entry returned by getEntriesByName()
                test_measure(entries[(i == duplicate_index ? 1 : 0)],
                            "window.performance.getEntriesByName(\"" + TEST_MEASURES[i].name + "\")[" +
                            (i == duplicate_index ? 1 : 0) + "]",
                            TEST_MEASURES[i].name,
                            TEST_MEASURES[i].startTime,
                            TEST_MEASURES[i].duration);
                TEST_MEASURES[i].entryMatch = entries[(i == duplicate_index ? 1 : 0)];
            }

            // test that expected measures are returned by getEntriesByName with the entryType parameter provided
            for (var i in TEST_MEASURES)
            {
                entries = window.performance.getEntriesByName(TEST_MEASURES[i].name, "measure");

                test_true(match_entries(entries[(i == duplicate_index ? 1 : 0)], TEST_MEASURES[i].entryMatch),
                          "window.performance.getEntriesByName(\"" + TEST_MEASURES[i].name + "\", \"measure\")[" +
                          (i == duplicate_index ? 1 : 0) + "] returns an object containing the \"" + TEST_MEASURES[i].name +
                          "\" measure in the correct order, and its value matches the \"" + TEST_MEASURES[i].name +
                          "\" measure returned by window.performance.getEntriesByName(\"" + TEST_MEASURES[i].name +
                          "\")");
            }

            // test that expected measures are returned by getEntries
            entries = get_test_entries(window.performance.getEntries(), "measure");

            test_measure_list(entries, "window.performance.getEntries()", TEST_MEASURES);

            // test that expected measures are returned by getEntriesByType
            entries = window.performance.getEntriesByType("measure");

            test_measure_list(entries, "window.performance.getEntriesByType(\"measure\")", TEST_MEASURES);

            done();
        }

        function match_entries(entry1, entry2, threshold)
        {
            if (threshold == undefined)
            {
                threshold = 0;
            }

            var pass = true;

            // match name
            pass = pass && (entry1.name == entry2.name);

            // match startTime
            pass = pass && (Math.abs(entry1.startTime - entry2.startTime) <= testThreshold);

            // match entryType
            pass = pass && (entry1.entryType == entry2.entryType);

            // match duration
            pass = pass && (Math.abs(entry1.duration - entry2.duration) <= testThreshold);

            return pass;
        }

        function test_measure(measureEntry, measureEntryCommand, expectedName, expectedStartTime, expectedDuration)
        {
            // test name
            test_true(measureEntry.name == expectedName, measureEntryCommand + ".name == \"" + expectedName + "\"");

            // test startTime; since for a mark, the startTime is always equal to a mark's value or the value of a
            // navigation timing attribute, the actual startTime should match the expected value exactly
            test_true(Math.abs(measureEntry.startTime - expectedStartTime) == 0,
                      measureEntryCommand + ".startTime is correct");

            // test entryType
            test_true(measureEntry.entryType == "measure", measureEntryCommand + ".entryType == \"measure\"");

            // test duration, allow for an acceptable threshold in the difference between the actual duration and the
            // expected value for the duration
            test_true(Math.abs(measureEntry.duration - expectedDuration) <= testThreshold, measureEntryCommand +
                      ".duration is approximately correct (up to " + testThreshold + "ms difference allowed)");
        }

        function test_measure_list(measureEntryList, measureEntryListCommand, measureScenarios)
        {
            // give all entries a "found" property that can be set to ensure it isn't tested twice
            for (var i in measureEntryList)
            {
                measureEntryList[i].found = false;
            }

            for (var i in measureScenarios)
            {
                measureScenarios[i].found = false;

                for (var j in measureEntryList)
                {
                    if (match_entries(measureEntryList[j], measureScenarios[i]) && !measureEntryList[j].found)
                    {
                        test_true(match_entries(measureEntryList[j], measureScenarios[i].entryMatch),
                                  measureEntryListCommand + " returns an object containing the \"" +
                                  measureScenarios[i].name + "\" measure, and it's value matches the measure " +
                                  "returned by window.performance.getEntriesByName(\"" + measureScenarios[i].name +
                                  "\")[" + (i == duplicate_index ? 1 : 0) + "].");

                        measureEntryList[j].found = true;
                        measureScenarios[i].found = true;
                        break;
                    }
                }

                if (!measureScenarios[i].found)
                {
                    test_true(false,
                              measureEntryListCommand + " returns an object containing the \"" +
                              measureScenarios[i].name + "\" measure.");
                }
            }

            // verify order of output of getEntriesByType
            var startTimeCurr = 0;
            var pass = true;
            for (var i in measureEntryList)
            {
                if (measureEntryList[i].startTime < startTimeCurr)
                {
                    pass = false;
                }
                startTimeCurr = measureEntryList[i].startTime;
            }
            test_true(pass,
                      measureEntryListCommand + " returns an object containing all test " +
                      "measures in order.");
        }

        function get_test_entries(entryList, entryType)
        {
            var testEntries = new Array();

            // filter entryList
            for (var i in entryList)
            {
                if (entryList[i].entryType == entryType)
                {
                    testEntries.push(entryList[i]);
                }
            }

            return testEntries;
        }
    </script>
    </head>
    <body onload="onload_test();">
        <h1>Description</h1>
        <p>This test validates that the performance.measure() method is working properly. This test creates the
           following measures to test this method:
            <ul>
                <li>"measure_no_start_no_end": created using a measure() call without a startMark or endMark
                    provided</li>
                <li>"measure_start_no_end": created using a measure() call with only the startMark provided</li>
                <li>"measure_start_end": created using a measure() call with both a startMark or endMark provided</li>
                <li>"measure_no_start_end": created using a measure() call with only the endMark provided</li>
                <li>"measure_no_start_no_end": duplicate of the first measure, used to confirm names can be re-used</li>
            </ul>
           After creating each measure, the existence of these measures is validated by calling
           performance.getEntriesByName() (both with and without the entryType parameter provided),
           performance.getEntriesByType(), and performance.getEntries()
        </p>

        <div id="log"></div>
    </body>
</html>
