<!DOCTYPE html>
<html>
<head>
<style>
.scrollable_region {
    width: 680px;
}
.scrollable_select option:nth-child(odd) {
    background: #f3f3f3;
}
</style>
<script src="../../../resources/js-test-pre.js"></script>
<script>
    jsTestIsAsync = true;
    var clientInset = 100;

    var selectTarget;
    var pageScrollPositionBefore;
    var selectScrollPositionBefore;

    function checkForScroll()
    {
        // The page should not have scrolled at all.
        var pageScrollPositionAfter = document.scrollingElement.scrollTop;
        var selectScrollPositionAfter = selectTarget.scrollTop;

        if (pageScrollPositionBefore != pageScrollPositionAfter)
            testFailed("Page received wheel events.");
        else
            testPassed("Page did not receive wheel events.");

        finishJSTest();
    }

    function scrollTest()
    {
        pageScrollPositionBefore = document.scrollingElement.scrollTop;

        selectTarget = document.getElementById('target');
        selectTarget.scrollTop = selectTarget.scrollHeight - selectTarget.clientHeight - 100;

        selectScrollPositionBefore = selectTarget.scrollTop;
 
        // Scroll the #source until we reach the #target.
        var startPosX = selectTarget.offsetLeft + 20;
        debug("div display height = " + selectTarget.clientHeight);
        var startPosY = Math.round(selectTarget.offsetTop) + Math.round(selectTarget.clientHeight) + clientInset - 2; // Very near top (accounting for top content inset).
        eventSender.mouseMoveTo(startPosX, startPosY);
        debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");

        eventSender.monitorWheelEvents();
        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
        eventSender.callAfterScrollingCompletes(checkForScroll);
    }

    function setupTopLevel() 
    {
        description("Tests that a select doesn't pass wheel events to main frame when scrolling at bottom");

        if (window.internals)
            window.internals.setTopContentInset(clientInset);

        if (window.eventSender) {
            setTimeout(scrollTest, 0);
            return;
        }
        
        var messageLocation = document.getElementById('parent');
        var message = document.createElement('div');
        message.innerHTML = "<p>To manually run this test, place the mouse pointer "
            + "inside the select box, and scroll near (but not AT) the bottom of the range. Use the mouse wheel or a two-finger "
            + "swipe to scroll through the rest of the select options.</p>"
            + "<p>You should not see the page position change if this test is successful.</p>";
        messageLocation.appendChild(message);
        finishJSTest();
    }

    window.addEventListener('load', () => {
        setupTopLevel();
    }, false);
</script>
</head>
<body>
<div id="parent" style="height: 2000px; width: 2000px;">
    <div id="source" style="height: 100px; width: 500px;">
        Put mouse here and flick downwards
    </div>
        <div class="scrollable_region">
            <h3>Scrollable Select</h3>
            <select id="target" class="scrollable_select" size="8">
                <option>content1</option>
                <option>content2</option>
                <option>content3</option>
                <option>content4</option>
                <option>content5</option>
                <option>content6</option>
                <option>content7</option>
                <option>content8</option>
                <option>content9</option>
                <option>content10</option>
                <option>content11</option>
                <option>content12</option>
                <option>content13</option>
                <option>content14</option>
                <option>content15</option>
                <option>content16</option>
                <option>content17</option>
                <option>content18</option>
                <option>content19</option>
                <option>content20</option>
                <option>content21</option>
            </select>
        </div>
    </div>
</div>
<div id="console"></div>
<script src="../../../resources/js-test-post.js"></script>
</body>
</html>
