<html>
<head>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
</head>
<body onLoad="runTest()">

<p>Checking Web Inspector protocol (specifically aria-current attribute) for the Accessibility Node Inspector.</p>

<div id="examples">

	<!-- All of these eval to 'false', ARIACurrent should not be set -->
    <ul><li><a class="ex" data-expected="false" href="/">Nav1</a></li></ul>
    <ul><li><a class="ex" data-expected="false" href="/" aria-current="false">Nav2</a></li></ul>
    <ul><li><a class="ex" data-expected="false" href="/" aria-current="">Nav3</a></li></ul>
    <ul><li><a class="ex" data-expected="false" href="/" aria-current=" ">Nav4</a></li></ul>
    <ul><li><a class="ex" data-expected="false" href="/" aria-current="	">Nav5</a></li></ul> <!-- tab char -->
    <ul><li><a class="ex" data-expected="false" href="/" aria-current="
    ">Nav6</a></li></ul> <!-- newline char -->

    <!-- Known token values in ARIA 1.1 -->
    <ul><li><a class="ex" data-expected="page" href="/" aria-current="page">Nav7</a></li></ul>
    <ul><li><a class="ex" data-expected="step" href="/" aria-current="step">Nav8</a></li></ul>
    <ul><li><a class="ex" data-expected="location" href="/" aria-current="location">Nav9</a></li></ul>
    <ul><li><a class="ex" data-expected="date" href="/" aria-current="date">Nav10</a></li></ul>
    <ul><li><a class="ex" data-expected="time" href="/" aria-current="time">Nav11</a></li></ul>
    <ul><li><a class="ex" data-expected="true" href="/" aria-current="true">Nav12</a></li></ul>

    <!-- All other string values -->
    <ul><li><a class="ex" data-expected="true" href="/" aria-current="sometext">Nav13</a></li></ul>
    <ul><li><a class="ex" data-expected="true" href="/" aria-current="page step">Nav14</a></li></ul>
    <ul><li><a class="ex" data-expected="page" href="/" aria-current="page ">Nav15</a></li></ul>
    <ul><li><a class="ex" data-expected="step" href="/" aria-current="  step ">Nav16</a></li></ul>

</div>

<script>

function $(id) {
    return document.getElementById(id);
}

function cleanup() {
    // Hide the test element container to avoid irrelevant output diffs on subsequent updates.
    $("examples").style.display = "none";
}

function test() {

    var examples = [];
    var documentNodeId = null;
    var bodyNodeId = null;

    function onGotDocument(response) {
        InspectorProtocol.checkForError(response);
        documentNodeId = response.result.root.nodeId;
        InspectorProtocol.sendCommand("DOM.querySelectorAll", {"nodeId": documentNodeId, "selector": ".ex"}, onGotQuerySelectorAll);
    }

    function onGotQuerySelectorAll(response) {
        InspectorProtocol.checkForError(response);
        examples = response.result.nodeIds;
        ProtocolTest.log("Total elements to be tested: " + examples.length + ".");
        loop();
    }

    function loop() {
        if (examples.length) {
            InspectorProtocol.sendCommand("DOM.getOuterHTML", {"nodeId": examples[examples.length-1]}, onGotOuterHTML);
        } else {
            finishTest();
        }
    }

    function onGotOuterHTML(response) {
        InspectorProtocol.checkForError(response);
        var outerHTML = response.result.outerHTML;
        outerHTML = outerHTML.replace(/ class="ex"/g, ""); // remove any duplicated, unnecessary class attributes
        ProtocolTest.log("\n" + outerHTML);
        InspectorProtocol.sendCommand("DOM.getAccessibilityPropertiesForNode", {"nodeId": examples[examples.length-1]}, onGotAccessibilityProperties);
    }

    function onGotAccessibilityProperties(response) {
        InspectorProtocol.checkForError(response);
        logAccessibilityProperties(response.result.properties);
        examples.pop();
        loop();
    }

    function logAccessibilityProperties(properties) {
        for (var key in properties) {
            var value = properties[key];
            switch (key){
            case "current":
                ProtocolTest.log("    " + key + ": " + value);
                break;
            default:
                continue;
            }
        }
    }

    function finishTest() {
        InspectorProtocol.sendCommand("Runtime.evaluate", {"expression": "cleanup()"}, function(){
            ProtocolTest.completeTest();
        });
    }

    InspectorProtocol.sendCommand("DOM.getDocument", {}, onGotDocument);

}
</script>
</body>
</html>