chromium/third_party/blink/web_tests/accessibility/accessibility-node-memory-management.html

<!DOCTYPE HTML>
<html>
<body>
<script src="../resources/js-test.js"></script>

<canvas id="canvas" tabindex="-1"></canvas>

<div id="console"></div>
<script>
description("This test makes sure that AccessibilityNodeObjects are properly detached when the node they point to is deleted.");

if (window.testRunner && window.accessibilityController) {
    testRunner.dumpAsText();

    // Create an ordinary button on the page, focus it and get its accessibility role.
    var button = document.createElement('button');
    document.body.appendChild(button);
    button.focus();
    window.axElement = accessibilityController.focusedElement;
    window.expectedButtonRole = axElement.role;

    // Now remove the node from the tree and get the role of the detached accessibility object.
    document.body.removeChild(button);
    window.expectedDetachedRole = axElement.role;
    shouldBeTrue("expectedButtonRole != expectedDetachedRole");

    // This time create a button that's a child of a canvas element. It will be focusable but not rendered.
    // In particular, this will create an AccessibilityNodeObject rather than an AccessibilityRenderObject.
    var canvas = document.getElementById('canvas');
    (function() {
        var button = document.createElement('button');
        canvas.appendChild(button);

        // Note: focusing the button and using that to get its accessibility object creates an extra
        // reference to the button and it won't get deleted when we want it to. So instead we focus the
        // canvas and get its first child.
        canvas.focus();
        window.axElement = accessibilityController.focusedElement.childAtIndex(0);

        window.canvasButtonRole = axElement.role;
        shouldBe("canvasButtonRole", "expectedButtonRole");

        // Now delete the node.
        canvas.removeChild(button);
    })();

    // Explicitly run garbage collection now; since there are no more references to the button,
    // the node will be destroyed.
    gc();

    // Ensure that the accessibility object is detached by checking its role.
    window.detachedCanvasButtonRole = axElement.role;
    shouldBe("detachedCanvasButtonRole", "expectedDetachedRole");
}

</script>

</body>
</html>