<html>
<head>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script src="../../http/tests/inspector/dom/resources/InspectorDOMListener.js"></script>
<script>
function test()
{
    // Create a DOM listener to convert nodeIds to tag names.
    var dom = createDOMListener();

    // Caching the output to avoid searching through the log.
    var output = [];
    var documentId;
    var domSearchQueries = [
        {
            query: "p",
            nodes: []
        },
        {
            query: "p",
            nodes: [".base1"]
        },
        {
            query: "p",
            nodes: [".base2"]
        },
        {
            query: "p",
            nodes: [".base1", ".base2"]
        },
        {
            query: "p",
            nodes: ["iframe"]
        },

        // XPath should return just the children of the selected nodes.
        {
            query: "//p",
            nodes: [".base1"]
        },
        {
            query: "//div",
            nodes: [".base1"]
        }
    ];

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

    function onGotDocument(message) {
        InspectorProtocol.checkForError(message);
        dom.collectNode(message.result.root);
        documentId = message.result.root.nodeId;
        performSearches(domSearchQueries, testFinished);
    }

    function performSearches(list, callback)
    {
        function next() {
            if (list.length)
                search(list.shift(), next);
            else
                callback();
        }
        next();
    }

    function search(queryData, callback)
    {
        resolveSelectors(queryData.nodes, function(nodeIds) {
            output.push("=== Query: " + JSON.stringify(queryData.query) + " in [" + queryData.nodes.join(", ") + "] ===");
            InspectorProtocol.sendCommand("DOM.performSearch", {query: queryData.query, nodeIds: nodeIds}, function(message) {
                InspectorProtocol.checkForError(message);
                printSearchResults(message.result, callback);
            });
        });
    }

    function resolveSelectors(nodes, callback)
    {
        var results = new Array(nodes.length);
        var remaining = nodes.length;
        if (!remaining)
            return callback(results);
        nodes.forEach(function(selector, index) {
            InspectorProtocol.sendCommand("DOM.querySelector", {nodeId: documentId, selector: selector}, function(message) {
                InspectorProtocol.checkForError(message);
                results[index] = message.result.nodeId;
                if (--remaining <= 0)
                    callback(results);
            });
        });
    }

    function printSearchResults(results, callback)
    {
        output.push("Count: " + results.resultCount);
        if (!results.resultCount)
            return callback();

        var options = {"searchId": results.searchId, "fromIndex": 0, "toIndex": results.resultCount};
        InspectorProtocol.sendCommand("DOM.getSearchResults", options, function(message) {
            for (var nodeId of message.result.nodeIds)
                output.push(dom.getNodeIdentifier(nodeId));
            callback();
        });
    }

    function testFinished()
    {
        ProtocolTest.log(output.join("\n"));
        ProtocolTest.completeTest();
    }
}
</script>
</head>
<body onload="runTest()" class="main-frame">
    <p>Testing DOM.performSearch with parent node ids.</p>

    <div class="base1">
        <p class="base1 main-frame"></p>
    </div>

    <div class="base2">
        <p class="base2 main-frame"></p>
    </div>

    <iframe src="resources/dom-search-iframe.html"></iframe>
</body>
</html>
