blob: e52890056f593656c1d7954e98c80275ae934ca6 [file] [log] [blame]
<!DOCTYPE html> <!-- webkit-test-runner [ enableUndoManagerAPI=true ] -->
<html>
<meta charset="utf8">
<head>
<script src="../../resources/js-test.js"></script>
<script src="../editing.js"></script>
<script>
jsTestIsAsync = true;
function objectCountAfterSimulatingMemoryPressureAndGarbageCollection() {
internals.beginSimulatedMemoryPressure();
internals.endSimulatedMemoryPressure();
GCController.collect();
return GCController.getJSObjectCount();
}
async function runTest() {
description("Verifies that JSUndoItems are deleted when they are no longer needed by the platform clipboard. This test requires WebKitTestRunner.");
if (!window.GCController)
return;
editor = document.getElementById("editor");
editor.focus();
const undoItemCount = 200;
for (let i = 0; i < undoItemCount; ++i) {
document.undoManager.addItem(new UndoItem({
label: "",
undo: () => { },
redo: () => { }
}));
}
for (let i = 0; i < undoItemCount; ++i)
document.execCommand("Undo");
objectCountBeforeClearingUndoStack = objectCountAfterSimulatingMemoryPressureAndGarbageCollection();
selectAllCommand();
typeCharacterCommand("E");
// Wait until almost all of the wrappers are collected. For each UndoItem, we expect a total of 3 wrappers:
// one each for the undo and redo handlers, and one for the UndoItem itself. However, we also give ourselves
// some wiggle room for additional wrappers created when calling some testing helper functions. This is
// still a useful test, since it will time out in the case where either our undo items or their undo/redo
// handlers are not properly relinquished once they're no longer needed.
const minimumNumberOfWrappersToCollectBeforePassing = 3 * undoItemCount - 20;
objectCountAfterClearingUndoStack = objectCountBeforeClearingUndoStack;
while (objectCountBeforeClearingUndoStack - objectCountAfterClearingUndoStack < minimumNumberOfWrappersToCollectBeforePassing) {
await new Promise(resolve => setTimeout(resolve, 100));
objectCountAfterClearingUndoStack = objectCountAfterSimulatingMemoryPressureAndGarbageCollection();
}
shouldBeGreaterThanOrEqual("objectCountBeforeClearingUndoStack - objectCountAfterClearingUndoStack", `${minimumNumberOfWrappersToCollectBeforePassing}`);
finishJSTest();
}
</script>
</head>
<body onload="runTest()">
<div contenteditable id="editor"></div>
<pre id="description"></pre>
<pre id="console"></pre>
</body>
</html>