@ -35,7 +35,7 @@ import { vi } from "vitest";
import { queryByText } from "@testing-library/react" ;
import { HistoryEntry } from "../history" ;
import { AppStateChange , ElementsChange } from "../change" ;
import { Snapshot } from "../store" ;
import { Snapshot , StoreAction } from "../store" ;
const { h } = window ;
@ -176,7 +176,7 @@ describe("history", () => {
excalidrawAPI . updateScene ( {
elements : [ rect1 , rect2 ] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
expect ( API . getUndoStack ( ) . length ) . toBe ( 1 ) ;
@ -188,7 +188,7 @@ describe("history", () => {
excalidrawAPI . updateScene ( {
elements : [ rect1 , rect2 ] ,
commitToStore: true , // even though the flag is on, same elements are passed, nothing to commit
storeAction: StoreAction.CAPTURE , // even though the flag is on, same elements are passed, nothing to commit
} ) ;
expect ( API . getUndoStack ( ) . length ) . toBe ( 1 ) ;
expect ( API . getRedoStack ( ) . length ) . toBe ( 0 ) ;
@ -556,7 +556,7 @@ describe("history", () => {
appState : {
name : "New name" ,
} ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
expect ( API . getUndoStack ( ) . length ) . toBe ( 1 ) ;
@ -567,7 +567,7 @@ describe("history", () => {
appState : {
viewBackgroundColor : "#000" ,
} ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
expect ( API . getUndoStack ( ) . length ) . toBe ( 2 ) ;
expect ( API . getRedoStack ( ) . length ) . toBe ( 0 ) ;
@ -580,7 +580,7 @@ describe("history", () => {
name : "New name" ,
viewBackgroundColor : "#000" ,
} ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
expect ( API . getUndoStack ( ) . length ) . toBe ( 2 ) ;
expect ( API . getRedoStack ( ) . length ) . toBe ( 0 ) ;
@ -1235,7 +1235,7 @@ describe("history", () => {
excalidrawAPI . updateScene ( {
elements : [ rect1 , text , rect2 ] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
// bind text1 to rect1
@ -1638,6 +1638,7 @@ describe("history", () => {
< Excalidraw
excalidrawAPI = { ( api ) = > excalidrawAPIPromise . resolve ( api as any ) }
handleKeyboardGlobally = { true }
isCollaborating = { true }
/ > ,
) ;
excalidrawAPI = await excalidrawAPIPromise ;
@ -1663,6 +1664,7 @@ describe("history", () => {
strokeColor : blue ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -1700,6 +1702,7 @@ describe("history", () => {
strokeColor : yellow ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -1747,6 +1750,7 @@ describe("history", () => {
backgroundColor : yellow ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
// At this point our entry gets updated from `red` -> `blue` into `red` -> `yellow`
@ -1762,6 +1766,7 @@ describe("history", () => {
backgroundColor : violet ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
// At this point our (inversed) entry gets updated from `red` -> `yellow` into `violet` -> `yellow`
@ -1790,6 +1795,7 @@ describe("history", () => {
// Initialize scene
excalidrawAPI . updateScene ( {
elements : [ rect1 , rect2 ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
// Simulate local update
@ -1798,7 +1804,7 @@ describe("history", () => {
newElementWith ( h . elements [ 0 ] , { groupIds : [ "A" ] } ) ,
newElementWith ( h . elements [ 1 ] , { groupIds : [ "A" ] } ) ,
] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
const rect3 = API . createElement ( { type : "rectangle" , groupIds : [ "B" ] } ) ;
@ -1812,6 +1818,7 @@ describe("history", () => {
rect3 ,
rect4 ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -1857,6 +1864,7 @@ describe("history", () => {
] ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ; // undo `actionFinalize`
@ -1951,6 +1959,7 @@ describe("history", () => {
isDeleted : false , // undeletion might happen due to concurrency between clients
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
expect ( API . getSelectedElements ( ) ) . toEqual ( [ ] ) ;
@ -2027,6 +2036,7 @@ describe("history", () => {
isDeleted : true ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
expect ( h . elements ) . toEqual ( [
@ -2088,6 +2098,7 @@ describe("history", () => {
isDeleted : true ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -2163,6 +2174,7 @@ describe("history", () => {
isDeleted : true ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -2201,6 +2213,7 @@ describe("history", () => {
isDeleted : false ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . redo ( ) ;
@ -2246,6 +2259,7 @@ describe("history", () => {
// Simulate remote update
excalidrawAPI . updateScene ( {
elements : [ rect1 , rect2 ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . withModifierKeys ( { ctrl : true } , ( ) = > {
@ -2255,6 +2269,7 @@ describe("history", () => {
// Simulate remote update
excalidrawAPI . updateScene ( {
elements : [ h . elements [ 0 ] , h . elements [ 1 ] , rect3 , rect4 ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . withModifierKeys ( { ctrl : true } , ( ) = > {
@ -2275,6 +2290,7 @@ describe("history", () => {
isDeleted : true ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -2299,6 +2315,7 @@ describe("history", () => {
isDeleted : false ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . redo ( ) ;
@ -2309,6 +2326,7 @@ describe("history", () => {
// Simulate remote update
excalidrawAPI . updateScene ( {
elements : [ h . elements [ 0 ] , h . elements [ 1 ] , rect3 , rect4 ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . redo ( ) ;
@ -2354,6 +2372,7 @@ describe("history", () => {
isDeleted : true ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -2374,6 +2393,7 @@ describe("history", () => {
} ) ,
h . elements [ 1 ] ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -2416,6 +2436,7 @@ describe("history", () => {
isDeleted : true ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -2458,6 +2479,7 @@ describe("history", () => {
h . elements [ 0 ] ,
h . elements [ 1 ] ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
expect ( API . getUndoStack ( ) . length ) . toBe ( 2 ) ;
@ -2496,6 +2518,7 @@ describe("history", () => {
h . elements [ 0 ] ,
h . elements [ 1 ] ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
expect ( API . getUndoStack ( ) . length ) . toBe ( 2 ) ;
@ -2546,6 +2569,7 @@ describe("history", () => {
h . elements [ 0 ] , // rect2
h . elements [ 1 ] , // rect1
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -2575,6 +2599,7 @@ describe("history", () => {
h . elements [ 0 ] , // rect3
h . elements [ 2 ] , // rect1
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -2604,6 +2629,7 @@ describe("history", () => {
// Simulate remote update
excalidrawAPI . updateScene ( {
elements : [ . . . h . elements , rect ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
mouse . moveTo ( 60 , 60 ) ;
@ -2655,6 +2681,7 @@ describe("history", () => {
// // Simulate remote update
excalidrawAPI . updateScene ( {
elements : [ . . . h . elements , rect3 ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
mouse . moveTo ( 100 , 100 ) ;
@ -2744,6 +2771,7 @@ describe("history", () => {
// Simulate remote update
excalidrawAPI . updateScene ( {
elements : [ . . . h . elements , rect3 ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
mouse . moveTo ( 100 , 100 ) ;
@ -2920,6 +2948,7 @@ describe("history", () => {
// Initialize the scene
excalidrawAPI . updateScene ( {
elements : [ container , text ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
// Simulate local update
@ -2932,7 +2961,7 @@ describe("history", () => {
containerId : container.id ,
} ) ,
] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
Keyboard . undo ( ) ;
@ -2963,6 +2992,7 @@ describe("history", () => {
x : h.elements [ 1 ] . x + 10 ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -3005,6 +3035,7 @@ describe("history", () => {
// Initialize the scene
excalidrawAPI . updateScene ( {
elements : [ container , text ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
// Simulate local update
@ -3017,7 +3048,7 @@ describe("history", () => {
containerId : container.id ,
} ) ,
] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
Keyboard . undo ( ) ;
@ -3051,6 +3082,7 @@ describe("history", () => {
remoteText ,
h . elements [ 1 ] ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -3106,6 +3138,7 @@ describe("history", () => {
// Initialize the scene
excalidrawAPI . updateScene ( {
elements : [ container , text ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
// Simulate local update
@ -3118,7 +3151,7 @@ describe("history", () => {
containerId : container.id ,
} ) ,
] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
Keyboard . undo ( ) ;
@ -3155,6 +3188,7 @@ describe("history", () => {
containerId : remoteContainer.id ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -3212,7 +3246,7 @@ describe("history", () => {
// Simulate local update
excalidrawAPI . updateScene ( {
elements : [ container ] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
// Simulate remote update
@ -3223,6 +3257,7 @@ describe("history", () => {
} ) ,
newElementWith ( text , { containerId : container.id } ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -3272,7 +3307,7 @@ describe("history", () => {
// Simulate local update
excalidrawAPI . updateScene ( {
elements : [ text ] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
// Simulate remote update
@ -3283,6 +3318,7 @@ describe("history", () => {
} ) ,
newElementWith ( text , { containerId : container.id } ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -3331,7 +3367,7 @@ describe("history", () => {
// Simulate local update
excalidrawAPI . updateScene ( {
elements : [ container ] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
// Simulate remote update
@ -3344,6 +3380,7 @@ describe("history", () => {
containerId : container.id ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -3380,6 +3417,7 @@ describe("history", () => {
// rebinding the container with a new text element!
remoteText ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -3436,7 +3474,7 @@ describe("history", () => {
// Simulate local update
excalidrawAPI . updateScene ( {
elements : [ text ] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
// Simulate remote update
@ -3449,6 +3487,7 @@ describe("history", () => {
containerId : container.id ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . undo ( ) ;
@ -3485,6 +3524,7 @@ describe("history", () => {
containerId : container.id ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -3540,7 +3580,7 @@ describe("history", () => {
// Simulate local update
excalidrawAPI . updateScene ( {
elements : [ container ] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
// Simulate remote update
@ -3554,6 +3594,7 @@ describe("history", () => {
isDeleted : true ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -3596,7 +3637,7 @@ describe("history", () => {
// Simulate local update
excalidrawAPI . updateScene ( {
elements : [ text ] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
// Simulate remote update
@ -3610,6 +3651,7 @@ describe("history", () => {
containerId : container.id ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -3652,6 +3694,7 @@ describe("history", () => {
// Initialize the scene
excalidrawAPI . updateScene ( {
elements : [ container ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
// Simulate local update
@ -3663,7 +3706,7 @@ describe("history", () => {
angle : 90 ,
} ) ,
] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
Keyboard . undo ( ) ;
@ -3676,6 +3719,7 @@ describe("history", () => {
} ) ,
newElementWith ( text , { containerId : container.id } ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
expect ( h . elements ) . toEqual ( [
@ -3768,6 +3812,7 @@ describe("history", () => {
// Initialize the scene
excalidrawAPI . updateScene ( {
elements : [ text ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
// Simulate local update
@ -3779,7 +3824,7 @@ describe("history", () => {
angle : 90 ,
} ) ,
] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
Keyboard . undo ( ) ;
@ -3794,6 +3839,7 @@ describe("history", () => {
containerId : container.id ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
expect ( API . getUndoStack ( ) . length ) . toBe ( 0 ) ;
@ -3884,7 +3930,7 @@ describe("history", () => {
// Simulate local update
excalidrawAPI . updateScene ( {
elements : [ rect1 , rect2 ] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
mouse . reset ( ) ;
@ -3962,6 +4008,7 @@ describe("history", () => {
x : h.elements [ 1 ] . x + 50 ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -4082,6 +4129,7 @@ describe("history", () => {
} ) ,
remoteContainer ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -4166,6 +4214,7 @@ describe("history", () => {
boundElements : [ { id : arrow.id , type : "arrow" } ] ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -4230,7 +4279,10 @@ describe("history", () => {
} ) ;
// Simulate local update
excalidrawAPI . updateScene ( { elements : [ arrow ] , commitToStore : true } ) ;
excalidrawAPI . updateScene ( {
elements : [ arrow ] ,
storeAction : StoreAction.CAPTURE ,
} ) ;
// Simulate remote update
excalidrawAPI . updateScene ( {
@ -4246,6 +4298,7 @@ describe("history", () => {
boundElements : [ { id : arrow.id , type : "arrow" } ] ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
runTwice ( ( ) = > {
@ -4357,6 +4410,7 @@ describe("history", () => {
newElementWith ( h . elements [ 1 ] , { x : 500 , y : - 500 } ) ,
h . elements [ 2 ] ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . redo ( ) ;
@ -4424,12 +4478,13 @@ describe("history", () => {
// Initialize the scene
excalidrawAPI . updateScene ( {
elements : [ frame ] ,
storeAction : StoreAction.UPDATE ,
} ) ;
// Simulate local update
excalidrawAPI . updateScene ( {
elements : [ rect , h . elements [ 0 ] ] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
// Simulate local update
@ -4440,7 +4495,7 @@ describe("history", () => {
} ) ,
h . elements [ 1 ] ,
] ,
commitToStore: true ,
storeAction: StoreAction.CAPTURE ,
} ) ;
Keyboard . undo ( ) ;
@ -4484,6 +4539,7 @@ describe("history", () => {
isDeleted : true ,
} ) ,
] ,
storeAction : StoreAction.UPDATE ,
} ) ;
Keyboard . redo ( ) ;