<html>
<head>
<script>
if (window.testRunner) {
    testRunner.waitUntilDone();
    testRunner.dumpAsText();
}

function log(message) {
    var console = document.getElementById("console");
    var li = document.createElement("li");
    var text = document.createTextNode(message);
    
    console.appendChild(li);
    li.appendChild(text);
}

function runTest() {

    var doc = window.frames[0].document;
    e = doc.getElementById("dragme");
    xdrag = e.offsetLeft + e.offsetWidth / 2;
    ydrag = e.offsetTop + e.offsetHeight / 2;
    e = doc.getElementById("target");
    xdrop = e.offsetLeft + e.offsetWidth / 2;
    ydrop = e.offsetTop + e.offsetHeight / 2;

    var timer = setInterval(function() {
                                window.frames[0].location = "../resources/drag-drop.html";
                            }, 100);

    if (!window.testRunner) {
        log("This test uses eventSender. To run it manually, drag the selected image to another position in the editable div and drop it. Renderer should not crash.");
        return;
    }
    
    var max_tries = 50; 
    for (i = 0; i < max_tries; i++) {
         eventSender.mouseMoveTo(xdrag, ydrag);
         eventSender.mouseDown();    
         eventSender.mouseMoveTo(xdrop, ydrop);
         eventSender.mouseUp();
    }

    clearInterval(timer);

    document.write("<p>Bug 37618: Crash when an image drag-drop operation happens inside a continuously refreshing iframe.</p>");
    document.write("<p>SUCCESS</p>");

    testRunner.notifyDone();
}
</script>
</head>
<body onload="runTest()">
<iframe src="../resources/drag-drop.html"></iframe>
<ul id="console"></ul>
</body>
</html>
