<script src="../../../../resources/js-test.js"></script>
<script src="../../../../resources/ui-helper.js"></script>
<script>
jsTestIsAsync = true;
touchEndEventCount = 0;

async function runTest()
{
    window.addEventListener("touchstart", function(event) {
        event.preventDefault();
        testPassed(`touchstart on window - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented}`);
    }, false);

    window.addEventListener("touchend", function(event) {
        event.preventDefault();
        testPassed(`touchend on window - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented}`);
        touchEndEventCount++;
    }, false);

    document.addEventListener("touchstart", function(event) {
        event.preventDefault();
        testPassed(`touchstart on document - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented}`);
    }, false);

    document.addEventListener("touchend", function(event) {
        event.preventDefault();
        testPassed(`touchend on document - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented}`);
        touchEndEventCount++;
    }, false);

    document.documentElement.addEventListener("touchstart", function(event) {
        event.preventDefault();
        testPassed(`touchstart on documentElement - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented}`);
    }, false);

    document.documentElement.addEventListener("touchend", function(event) {
        event.preventDefault();
        testPassed(`touchend on documentElement - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented}`);
        touchEndEventCount++;
    }, false);

    let body = document.querySelector("body");

    body.addEventListener("touchstart", function(event) {
        event.preventDefault();
        testPassed(`touchstart on body - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented}`);
    }, false);

    body.addEventListener("touchend", function(event) {
        event.preventDefault();
        testPassed(`touchend on body - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented}`);
        touchEndEventCount++;
    }, false);

    if (window.testRunner && testRunner.runUIScript) {
        description("This test verifies that touchstart and touchend event listeners are passive by default on document, window, documentElement, and body. This test requires WebKitTestRunner.");
        await UIHelper.dragFromPointToPoint(50, 250, 50, 30, 0.1);
        await new Promise(resolve => shouldBecomeEqual("touchEndEventCount", "4", resolve));
        finishJSTest();
    }
}

window.addEventListener('load', runTest, false);
</script>
<body style="height: 500vh">
</body>
