<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<link rel="stylesheet" href="resources/search-stylesheet.css">
<script src="resources/search-script.js"></script>
<script>
function triggerDownloadingResources() {
    let worker = new Worker("resources/search-worker.js");

    let xhr = new XMLHttpRequest;
    xhr.open("GET", "resources/search-xhr.txt", true);
    xhr.addEventListener("load", done);
    xhr.send();

    function done() {
        TestPage.dispatchEventToFrontend('PageIsReady');
    }
}

function test()
{
    function sanitizeURL(url) {
        return url.replace(/^.*?LayoutTests\//, "");
    }

    let suite = InspectorTest.createAsyncSuite("Page.searchInResources and Page.searchInResource");

    const searchString = "SeArCh-StRiNg";
    const searchStringCaseSensitive = searchString.toUpperCase();
    const searchStringRegex = "(search|OTHER)-STRING";

    let searchResults = null;
    let searchResultsCaseSensitive = null;
    let searchResultsIsRegex = null;
    let searchResultsCaseSensitiveIsRegex = null;

    suite.addTestCase({
        name: "SearchAllResources",
        description: "Able to find text results in different resources.",
        test(resolve, reject) {
            PageAgent.searchInResources(searchString, (error, results) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(results.length > 0, "Should find results in multiple resources.");
                searchResults = results.sort((a, b) => a.url.localeCompare(b.url));
                for (let result of searchResults)
                    InspectorTest.log(`FOUND: ${sanitizeURL(result.url)} (${result.matchesCount})`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchAllResources.CaseSensitive",
        description: "Able to find text results in different resources.",
        test(resolve, reject) {
            const caseSensitive = true;
            PageAgent.searchInResources(searchStringCaseSensitive, caseSensitive, (error, results) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(results.length > 0, "Should find results in multiple resources.");
                searchResultsCaseSensitive = results.sort((a, b) => a.url.localeCompare(b.url));
                for (let result of searchResultsCaseSensitive)
                    InspectorTest.log(`FOUND: ${sanitizeURL(result.url)} (${result.matchesCount})`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchAllResources.IsRegex",
        description: "Able to find text results in different resources.",
        test(resolve, reject) {
            const caseSensitive = undefined;
            const isRegex = true;
            PageAgent.searchInResources(searchStringRegex, caseSensitive, isRegex, (error, results) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(results.length > 0, "Should find results in multiple resources.");
                searchResultsIsRegex = results.sort((a, b) => a.url.localeCompare(b.url));
                for (let result of searchResultsIsRegex)
                    InspectorTest.log(`FOUND: ${sanitizeURL(result.url)} (${result.matchesCount})`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchAllResources.CaseSensitiveIsRegex",
        description: "Able to find text results in different resources.",
        test(resolve, reject) {
            const caseSensitive = true;
            const isRegex = true;
            PageAgent.searchInResources(searchStringRegex, caseSensitive, isRegex, (error, results) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(results.length > 0, "Should find results in multiple resources.");
                searchResultsCaseSensitiveIsRegex = results.sort((a, b) => a.url.localeCompare(b.url));
                for (let result of searchResultsCaseSensitiveIsRegex)
                    InspectorTest.log(`FOUND: ${sanitizeURL(result.url)} (${result.matchesCount})`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchInScriptResource",
        description: "Able to find text results in an individual Script resource.",
        test(resolve, reject) {
            let result = searchResults.find((result) => /search-script\.js$/.test(result.url));
            if (!result)
                reject();

            PageAgent.searchInResource(result.frameId, result.url, searchString, (error, matches) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`);
                for (let match of matches)
                    InspectorTest.log(`MATCH: ${JSON.stringify(match)}`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchInScriptResource.CaseSensitive",
        description: "Able to find text results in an individual Script resource.",
        test(resolve, reject) {
            let result = searchResultsCaseSensitive.find((result) => /search-script\.js$/.test(result.url));
            if (!result)
                reject();

            const caseSensitive = true;
            PageAgent.searchInResource(result.frameId, result.url, searchStringCaseSensitive, caseSensitive, (error, matches) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`);
                for (let match of matches)
                    InspectorTest.log(`MATCH: ${JSON.stringify(match)}`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchInScriptResource.IsRegex",
        description: "Able to find text results in an individual Script resource.",
        test(resolve, reject) {
            let result = searchResultsIsRegex.find((result) => /search-script\.js$/.test(result.url));
            if (!result)
                reject();

            const caseSensitive = undefined;
            const isRegex = true;
            PageAgent.searchInResource(result.frameId, result.url, searchStringRegex, caseSensitive, isRegex, (error, matches) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`);
                for (let match of matches)
                    InspectorTest.log(`MATCH: ${JSON.stringify(match)}`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchInScriptResource.CaseSensitiveIsRegex",
        description: "Able to find text results in an individual Script resource.",
        test(resolve, reject) {
            let result = searchResultsCaseSensitiveIsRegex.find((result) => /search-script\.js$/.test(result.url));
            if (!result)
                reject();

            const caseSensitive = true;
            const isRegex = true;
            PageAgent.searchInResource(result.frameId, result.url, searchStringRegex, caseSensitive, isRegex, (error, matches) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`);
                for (let match of matches)
                    InspectorTest.log(`MATCH: ${JSON.stringify(match)}`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchInXHRResource",
        description: "Able to find text results in an individual XHR resource.",
        test(resolve, reject) {
            let result = searchResults.find((result) => /search-xhr\.txt$/.test(result.url));
            if (!result)
                reject();

            const isRegex = undefined;
            const caseSensitive = undefined;

            PageAgent.searchInResource(result.frameId, result.url, searchString, caseSensitive, isRegex, result.requestId, (error, matches) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`);
                for (let match of matches)
                    InspectorTest.log(`MATCH: ${JSON.stringify(match)}`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchInXHRResource.CaseSensitive",
        description: "Able to find text results in an individual XHR resource.",
        test(resolve, reject) {
            let result = searchResultsCaseSensitive.find((result) => /search-xhr\.txt$/.test(result.url));
            if (!result)
                reject();

            const isRegex = undefined;
            const caseSensitive = true;

            PageAgent.searchInResource(result.frameId, result.url, searchStringCaseSensitive, caseSensitive, isRegex, result.requestId, (error, matches) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`);
                for (let match of matches)
                    InspectorTest.log(`MATCH: ${JSON.stringify(match)}`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchInXHRResource.IsRegex",
        description: "Able to find text results in an individual XHR resource.",
        test(resolve, reject) {
            let result = searchResultsIsRegex.find((result) => /search-xhr\.txt$/.test(result.url));
            if (!result)
                reject();

            const isRegex = true;
            const caseSensitive = undefined;

            PageAgent.searchInResource(result.frameId, result.url, searchStringRegex, caseSensitive, isRegex, result.requestId, (error, matches) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`);
                for (let match of matches)
                    InspectorTest.log(`MATCH: ${JSON.stringify(match)}`);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SearchInXHRResource.CaseSensitiveIsRegex",
        description: "Able to find text results in an individual XHR resource.",
        test(resolve, reject) {
            let result = searchResultsCaseSensitiveIsRegex.find((result) => /search-xhr\.txt$/.test(result.url));
            if (!result)
                reject();

            const isRegex = true;
            const caseSensitive = true;

            PageAgent.searchInResource(result.frameId, result.url, searchStringRegex, caseSensitive, isRegex, result.requestId, (error, matches) => {
                InspectorTest.assert(!error, "Should not be a protocol error.");
                InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`);
                for (let match of matches)
                    InspectorTest.log(`MATCH: ${JSON.stringify(match)}`);
                resolve();
            });
        }
    });

    InspectorTest.awaitEvent("PageIsReady")
    .then((event) => {
        suite.runTestCasesAndFinish();
    });

    InspectorTest.evaluateInPage("triggerDownloadingResources()");
}
</script>
</head>
<body onload="runTest()">
<p>Tests for the Page.searchInResources and Page.searchInResource commands.</p>
</body>
</html>
