 Chromium Code Reviews
 Chromium Code Reviews Issue 21163003:
  DevTools: Implement undo, redo operations for the DOMStorage views.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master
    
  
    Issue 21163003:
  DevTools: Implement undo, redo operations for the DOMStorage views.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master| Index: LayoutTests/inspector/storage-panel-dom-storage-undo-redo.html | 
| diff --git a/LayoutTests/inspector/storage-panel-dom-storage-undo-redo.html b/LayoutTests/inspector/storage-panel-dom-storage-undo-redo.html | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..76afc616a42fe69411231ae738583f60c55a5a22 | 
| --- /dev/null | 
| +++ b/LayoutTests/inspector/storage-panel-dom-storage-undo-redo.html | 
| @@ -0,0 +1,337 @@ | 
| +<html> | 
| +<head> | 
| +<script src="../http/tests/inspector/inspector-test.js"></script> | 
| +<script> | 
| + | 
| +function clearDOMStorage() | 
| +{ | 
| + localStorage.clear(); | 
| + sessionStorage.clear(); | 
| +} | 
| + | 
| +function getDOMStorageEntries(isLocalStorage) | 
| +{ | 
| + var storage = isLocalStorage ? localStorage : sessionStorage; | 
| + var entries = []; | 
| + for (var i = 0; i < storage.length; ++i) { | 
| + var key = storage.key(i); | 
| + var value = storage.getItem(key); | 
| + entries.push(key + "=" + value); | 
| + } | 
| + entries.sort(); | 
| + return "[" + entries.join() + "]"; | 
| +} | 
| + | 
| +function test() | 
| +{ | 
| + WebInspector.showPanel("resources"); | 
| + | 
| + var theLocalStorage; | 
| + var theSessionStorage; | 
| + var storages = WebInspector.domStorageModel.storages(); | 
| + for (var i = 0; i < storages.length; ++i) { | 
| + var storage = storages[i]; | 
| + if (storage.isLocalStorage) | 
| + theLocalStorage = storage; | 
| + else | 
| + theSessionStorage = storage; | 
| + } | 
| + | 
| + function dumpDOMStorage(next) | 
| + { | 
| + if (this.isLocalStorage) | 
| + InspectorTest.evaluateInPage("getDOMStorageEntries(true)", storageEntriesReceived.bind(this)); | 
| + else | 
| + InspectorTest.evaluateInPage("getDOMStorageEntries(false)", storageEntriesReceived.bind(this)); | 
| + | 
| + function storageEntriesReceived(entries) | 
| + { | 
| + InspectorTest.addResult((this.isLocalStorage ? "LocalStorage" : "SessionStorage") + " contents:" + entries.description); | 
| + next(); | 
| + } | 
| + } | 
| + | 
| + function show(storage) | 
| + { | 
| + WebInspector.panels.resources._showDOMStorage(storage); | 
| + } | 
| + | 
| + function undo(operations, next) | 
| + { | 
| + for (var i = 0; i < operations; ++i) | 
| + this.undo(); | 
| + InspectorTest.runAfterPendingDispatches(dumpDOMStorage.bind(this, next)); | 
| + } | 
| + | 
| + function redo(operations, next) | 
| + { | 
| + for (var i = 0; i < operations; ++i) | 
| + this.redo(); | 
| + InspectorTest.runAfterPendingDispatches(dumpDOMStorage.bind(this, next)); | 
| + } | 
| + | 
| + function addKeyValuePair(storage, key, value) | 
| + { | 
| + var dataGrid = WebInspector.panels.resources._domStorageViews.get(storage)._dataGrid; | 
| + var creationNode = dataGrid.rootNode().children.peekLast(); | 
| + | 
| + var elementKey = creationNode._element.children[0]; | 
| + dataGrid._startEditing(elementKey); | 
| + elementKey.textContent = key; | 
| + elementKey.dispatchEvent(InspectorTest.createKeyEvent("Enter")); | 
| + | 
| + var elementValue = creationNode._element.children[1]; | 
| + dataGrid._startEditing(elementValue); | 
| + elementValue.textContent = value; | 
| + elementValue.dispatchEvent(InspectorTest.createKeyEvent("Enter")); | 
| + } | 
| + | 
| + function modifyValueForKey(storage, key, newValue) | 
| + { | 
| + var dataGrid = WebInspector.panels.resources._domStorageViews.get(storage)._dataGrid; | 
| + var children = dataGrid.rootNode().children; | 
| + | 
| + var modificationNode; | 
| + for (var i = 0; i < children.length; ++i) { | 
| + if (children[i]._element.children[0].textContent === key) { | 
| + modificationNode = children[i]; | 
| + break; | 
| + } | 
| + } | 
| + | 
| + var elementValue = modificationNode._element.children[1]; | 
| + dataGrid._startEditing(elementValue); | 
| + elementValue.textContent = newValue; | 
| + elementValue.dispatchEvent(InspectorTest.createKeyEvent("Enter")); | 
| + } | 
| + | 
| + function changeKey(storage, oldKey, newKey) | 
| + { | 
| + var dataGrid = WebInspector.panels.resources._domStorageViews.get(storage)._dataGrid; | 
| + var children = dataGrid.rootNode().children; | 
| + | 
| + var modificationNode; | 
| + for (var i = 0; i < children.length; ++i) { | 
| + if (children[i]._element.children[0].textContent === oldKey) { | 
| + modificationNode = children[i]; | 
| + break; | 
| + } | 
| + } | 
| + var elementKey = modificationNode._element.children[0]; | 
| + dataGrid._startEditing(elementKey); | 
| + elementKey.textContent = newKey; | 
| + elementKey.dispatchEvent(InspectorTest.createKeyEvent("Enter")); | 
| + } | 
| + | 
| + InspectorTest.runTestSuite([ | 
| + function initialize(next) | 
| + { | 
| + InspectorTest.evaluateInPage("clearDOMStorage()", initialized); | 
| + | 
| + function initialized(result) | 
| + { | 
| + InspectorTest.addResult("Initialized localStorage and sessionStorage by clearing entries."); | 
| + next(); | 
| + } | 
| + }, | 
| + | 
| + function undoLocalStorageWithEmptyStack(next) | 
| + { | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theLocalStorage, 10, next)); | 
| + }, | 
| + | 
| + function redoLocalStorageWithEmptyStack(next) | 
| + { | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(redo.bind(theLocalStorage, 10, next)); | 
| + }, | 
| + | 
| + function localStorageUndoInterlacedWithAddition(next) | 
| + { | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(domStorageViewShown.bind(theLocalStorage)); | 
| + function domStorageViewShown() | 
| + { | 
| + addKeyValuePair(this, "a1", "b1"); | 
| + addKeyValuePair(this, "a2", "b2"); | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theLocalStorage, 2, firstUndoDone.bind(next))); | 
| 
apavlov
2013/08/05 09:07:15
Semantically, ...bind(next) is not the right way o
 
vivekg_samsung
2013/08/05 09:39:49
Done.
 | 
| + | 
| + function firstUndoDone() | 
| + { | 
| + addKeyValuePair(theLocalStorage, "a3", "b3"); | 
| + InspectorTest.runAfterPendingDispatches(dumpDOMStorage.bind(theLocalStorage, nextUndoDone.bind(this))); | 
| + | 
| + function nextUndoDone() | 
| + { | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theLocalStorage, 2, this)); | 
| + } | 
| + } | 
| + } | 
| + }, | 
| + | 
| + function addLocalStorageEntries(next) | 
| + { | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(domStorageViewShown.bind(theLocalStorage)); | 
| + | 
| + function domStorageViewShown() | 
| + { | 
| + addKeyValuePair(this, "a1", "b1"); | 
| + addKeyValuePair(this, "a2", "b2"); | 
| + InspectorTest.runAfterPendingDispatches(dumpDOMStorage.bind(this, next)); | 
| + } | 
| + }, | 
| + | 
| + function undoLocalStorageLastAddition(next) | 
| + { | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theLocalStorage, 2, next)); | 
| + }, | 
| + | 
| + function undoSessionStorageWithEmptyStack(next) | 
| + { | 
| + show(theSessionStorage); | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theSessionStorage, 10, next)); | 
| + }, | 
| + | 
| + function redoSessionStorageWithEmptyStack(next) | 
| + { | 
| + show(theSessionStorage); | 
| + InspectorTest.runAfterPendingDispatches(redo.bind(theSessionStorage, 10, next)); | 
| + }, | 
| + | 
| + function undoLocalStorageBeyondBounds(next) | 
| + { | 
| + InspectorTest.addResult("The entry a1=b1 is removed and any attempt to undo beyond it shouldn't cause any failure!") | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theLocalStorage, 10, next)); | 
| + }, | 
| + | 
| + function addSessionStorageEntries(next) | 
| + { | 
| + show(theSessionStorage); | 
| + InspectorTest.runAfterPendingDispatches(domStorageViewShown.bind(theSessionStorage)); | 
| + | 
| + function domStorageViewShown() | 
| + { | 
| + addKeyValuePair(this, "p1", "q1"); | 
| + addKeyValuePair(this, "p2", "q2"); | 
| + addKeyValuePair(this, "p3", "q3"); | 
| + addKeyValuePair(this, "p4", "q4"); | 
| + InspectorTest.runAfterPendingDispatches(dumpDOMStorage.bind(this, next)); | 
| + } | 
| + }, | 
| + | 
| + function redoLocalStorageBeyondBounds(next) | 
| + { | 
| + InspectorTest.addResult("The entry a1=b1 and a2=b2 is added back and any attempt to redo beyond it shouldn't cause any failure!") | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(redo.bind(theLocalStorage, 10, next)); | 
| + }, | 
| + | 
| + function undoSessionStorageLastAddition(next) | 
| + { | 
| + show(theSessionStorage); | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theSessionStorage, 2, next)); | 
| + }, | 
| + | 
| + function modifyLocalStorageValues(next) | 
| + { | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(domStorageViewShown.bind(theLocalStorage)); | 
| + | 
| + function domStorageViewShown() | 
| + { | 
| + modifyValueForKey(this, "a1", "x1"); | 
| + modifyValueForKey(this, "a2", "x2"); | 
| + InspectorTest.runAfterPendingDispatches(dumpDOMStorage.bind(this, next)); | 
| + } | 
| + }, | 
| + | 
| + function undoLocalStorageModifications(next) | 
| + { | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theLocalStorage, 2, next)); | 
| + }, | 
| + | 
| + function redoSessionStorageLastAddition(next) | 
| + { | 
| + show(theSessionStorage); | 
| + InspectorTest.runAfterPendingDispatches(redo.bind(theSessionStorage, 2, next)); | 
| + }, | 
| + | 
| + function redoLocalStorageModifications(next) | 
| + { | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(redo.bind(theLocalStorage, 2, next)); | 
| + }, | 
| + | 
| + function modifySessionStorageEntriesKey(next) | 
| + { | 
| + show(theSessionStorage); | 
| + InspectorTest.runAfterPendingDispatches(domStorageViewShown.bind(theSessionStorage)); | 
| + | 
| + function domStorageViewShown() | 
| + { | 
| + changeKey(this, "p1", "m1"); | 
| + changeKey(this, "p2", "m2"); | 
| + changeKey(this, "p3", "m3"); | 
| + changeKey(this, "p4", "m4"); | 
| + InspectorTest.runAfterPendingDispatches(dumpDOMStorage.bind(this, next)); | 
| + } | 
| + }, | 
| + | 
| + function undoLocalStorageModifications(next) | 
| + { | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theLocalStorage, 2, next)); | 
| + }, | 
| + | 
| + function undoSessionStorageKeyModifications(next) | 
| + { | 
| + show(theSessionStorage); | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theSessionStorage, 8, next)); | 
| + }, | 
| + | 
| + function validateMaxUndoRedoStackDepth(next) | 
| + { | 
| + show(theLocalStorage); | 
| + InspectorTest.runAfterPendingDispatches(domStorageViewShown.bind(theLocalStorage)); | 
| + | 
| + function domStorageViewShown() | 
| + { | 
| + var stackDepth = WebInspector.DOMStorageHistory.MAX_UNDO_REDO_DEPTH; | 
| + InspectorTest.addResult("Undo/redo stack depth limit is " + stackDepth); | 
| + InspectorTest.addResult("Performing " + (2 * stackDepth) + " actions"); | 
| + for (var i = 1; i <= stackDepth; ++i) | 
| + addKeyValuePair(this, "a" + i, "b" + i); | 
| + | 
| + InspectorTest.runAfterPendingDispatches(dumpDOMStorage.bind(this, undoMoreThanDepth.bind(this))); | 
| + | 
| + function undoMoreThanDepth() | 
| + { | 
| + InspectorTest.addResult("Performing undo operation three times the depth i.e. " + (3 * stackDepth) + " times but only last " + stackDepth + " operations are undone"); | 
| + InspectorTest.runAfterPendingDispatches(undo.bind(theLocalStorage, (3 * stackDepth), next)); | 
| + } | 
| + } | 
| + }, | 
| + | 
| + function clearDOMStorageAndFinish(next) | 
| + { | 
| + InspectorTest.evaluateInPage("clearDOMStorage()", finishTest); | 
| + | 
| + function finishTest(result) | 
| + { | 
| + InspectorTest.addResult("Finished DOMStorage undo/redo tests and cleared localStorage and sessionStorage entries."); | 
| + next(); | 
| + } | 
| + } | 
| + ]); | 
| +} | 
| +</script> | 
| +</head> | 
| +<body onload="runTest()"> | 
| +<p>This test checks the undo/redo operations are performed correctly on the DOM storage views</p> | 
| +</body> | 
| +</html> |