chromium/third_party/blink/web_tests/fast/events/touch/gesture/gesture-tap-frame-removed.html

<!DOCTYPE HTML>
<script src="../../../../resources/js-test.js"></script>
<style>
#target {
  width: 50px;
  height: 50px;
}
</style>
<iframe id="target" src="resources/event-delegator.html"></iframe>
<div id=console></div>
<script>
var removalEventType;

function onEventInFrame(e) {
    debug("Received " + e.type + " in child frame");
    if (e.type == removalEventType) {
        debug('Removing iframe');
        target.parentNode.removeChild(target);
        gc();
    }
}

function eventLogger(e) {
    debug("Received " + e.type + " in main frame");
}

document.addEventListener('mousemove', eventLogger);
document.addEventListener('mousedown', eventLogger);
document.addEventListener('mouseup', eventLogger);
document.addEventListener('click', eventLogger);

description("Verifies that a tap occurring on an iframe that gets removed during tap handling doesn't cause a crash.");

var rect = target.getBoundingClientRect();
var point = {
    x: rect.left + rect.width / 2,
    y: rect.top + rect.height / 2
};

function doTapAndRemove(type)
{
    return new Promise(function(resolve, reject) {

        var clone = target.cloneNode();
        var insertionPoint = target.nextSibling;

        debug('Test case: Remove during ' + type);
        removalEventType = type;

        eventSender.gestureTapDown(point.x, point.y);
        eventSender.gestureShowPress(point.x, point.y);
        debug("Sending GestureTap");
        eventSender.gestureTap(point.x, point.y);

        // Verify that the iframe was removed.
        shouldBeNull("document.getElementById('target')");

        // Ensure the event is done being processed.
        setTimeout(function() {
            // Reinsert the target node for the next run.
            insertionPoint.parentNode.insertBefore(clone, insertionPoint);
            clone.addEventListener('load', function() {
                debug('iframe loaded');
                debug('');
                setTimeout(resolve, 0);
            });
            window.target = clone;
        }, 0);
    });
}

if (window.eventSender) {
    jsTestIsAsync = true;
    target.onload = function() {
        doTapAndRemove('mousemove')
        .then(function() { return doTapAndRemove('mousedown'); })
        .then(function() { return doTapAndRemove('mouseup'); })
        .catch(function(err) {
            testFailed("Promise rejected: " + err.message);
        }).then(finishJSTest);
    }
} else {
    debug("This test requires eventSender");
}
</script>