@@ -27,37 +27,180 @@ test.describe('Vue Nodes Canvas Pan', { tag: '@vue-nodes' }, () => {
2727 }
2828 )
2929
30- test . describe ( 'spacebar panning' , ( ) => {
31- test . beforeEach ( async ( { comfyPage } ) => {
32- await comfyPage . settings . setSetting (
33- 'Comfy.Canvas.NavigationMode' ,
34- 'standard'
35- )
36- await comfyPage . workflow . loadWorkflow ( 'vueNodes/simple-triple' )
37- } )
30+ test ( 'spacebar panning' , async ( { comfyPage, comfyMouse } ) => {
31+ await comfyPage . settings . setSetting (
32+ 'Comfy.Canvas.NavigationMode' ,
33+ 'standard'
34+ )
35+ await comfyPage . workflow . loadWorkflow ( 'vueNodes/simple-triple' )
36+ const node = await comfyPage . vueNodes . getFixtureByTitle ( 'KSampler' )
37+ const [ nodeRef ] = await comfyPage . nodeOps . getNodeRefsByTitle ( 'KSampler' )
38+ if ( ! nodeRef ) throw new Error ( 'KSampler is not rendered' )
39+ const softExpect = expect . configure ( { soft : true } )
3840
39- test ( 'Space + left-drag on a Vue node pans canvas' , async ( {
40- comfyPage,
41- comfyMouse
42- } ) => {
43- const node = comfyPage . vueNodes . getNodeByTitle ( 'KSampler' )
41+ await test . step ( 'Space + click on a node starts a pan' , async ( ) => {
4442 const offsetBefore = await comfyPage . canvasOps . getOffset ( )
4543
4644 await comfyPage . canvas . focus ( )
47- await comfyPage . page . keyboard . down ( 'Space' )
48- await expect . poll ( ( ) => comfyPage . canvasOps . isReadOnly ( ) ) . toBe ( true )
49- try {
50- await comfyMouse . dragElementBy ( node , { x : 140 , y : 90 } )
51- } finally {
52- await comfyPage . page . keyboard . up ( 'Space' )
53- }
45+ await using releaseSpace = await comfyPage . keyboard . hold ( 'Space' )
46+ await softExpect . poll ( ( ) => comfyPage . canvasOps . isReadOnly ( ) ) . toBe ( true )
47+ await comfyMouse . dragElementBy ( node . root , { x : - 300 , y : 0 } )
48+ await releaseSpace . disposeAsync ( )
5449
55- await expect
50+ await softExpect
5651 . poll ( ( ) => comfyPage . canvasOps . getOffset ( ) )
5752 . not . toEqual ( offsetBefore )
5853 } )
54+
55+ await test . step ( 'Space switches node dragging to canvas panning' , async ( ) => {
56+ await node . header . hover ( )
57+ await using mouseRelease = await comfyMouse . hold ( )
58+ await comfyPage . page . mouse . move ( 500 , 500 , { steps : 5 } )
59+ const offsetBeforePan = await comfyPage . canvasOps . getOffset ( )
60+
61+ await using spaceRelease = await comfyPage . keyboard . hold ( 'Space' )
62+ await comfyPage . page . mouse . move ( 400 , 400 , { steps : 5 } )
63+ await softExpect
64+ . poll ( ( ) => comfyPage . canvasOps . getOffset ( ) )
65+ . not . toEqual ( offsetBeforePan )
66+
67+ await test . step ( 'Releasing Space resumes node dragging' , async ( ) => {
68+ await spaceRelease . disposeAsync ( )
69+ const offsetAfterPan = await comfyPage . canvasOps . getOffset ( )
70+ const positionBeforeResume = [
71+ ...( await nodeRef . getProperty < [ number , number ] > ( 'pos' ) )
72+ ]
73+ await comfyPage . page . mouse . move ( 500 , 500 , { steps : 5 } )
74+ await comfyPage . nextFrame ( )
75+
76+ softExpect ( await comfyPage . canvasOps . getOffset ( ) ) . toEqual (
77+ offsetAfterPan
78+ )
79+ await softExpect
80+ . poll ( async ( ) => [
81+ ...( await nodeRef . getProperty < [ number , number ] > ( 'pos' ) )
82+ ] )
83+ . not . toEqual ( positionBeforeResume )
84+ await mouseRelease . disposeAsync ( )
85+ } )
86+ } )
5987 } )
6088
89+ test (
90+ 'Space in a focused text widget does not start canvas panning' ,
91+ { tag : [ '@canvas' , '@widget' ] } ,
92+ async ( { comfyPage } ) => {
93+ await comfyPage . workflow . loadWorkflow ( 'inputs/string_input' )
94+ const input = comfyPage . vueNodes
95+ . getWidgetByName ( 'Node With String Input' , 'string_input' )
96+ . first ( )
97+
98+ await input . focus ( )
99+ await input . press ( 'Space' )
100+
101+ await expect
102+ . poll ( async ( ) => [
103+ await input . inputValue ( ) ,
104+ await comfyPage . canvasOps . isReadOnly ( )
105+ ] )
106+ . toEqual ( [ ' ' , false ] )
107+ }
108+ )
109+
110+ test (
111+ 'Space in a focused native select does not start canvas panning' ,
112+ { tag : [ '@canvas' , '@widget' ] } ,
113+ async ( { comfyPage, comfyMouse } ) => {
114+ await comfyPage . workflow . loadWorkflow ( 'vueNodes/simple-triple' )
115+ const node = await comfyPage . vueNodes . getFixtureByTitle ( 'KSampler' )
116+ const [ nodeRef ] = await comfyPage . nodeOps . getNodeRefsByTitle ( 'KSampler' )
117+ if ( ! nodeRef ) throw new Error ( 'KSampler is not rendered' )
118+ const positionBeforeDrag = [
119+ ...( await nodeRef . getProperty < [ number , number ] > ( 'pos' ) )
120+ ]
121+ await node . root . evaluate ( ( element ) => {
122+ const select = document . createElement ( 'select' )
123+ select . ariaLabel = 'Native select'
124+ select . append ( document . createElement ( 'option' ) )
125+ element . append ( select )
126+ } )
127+ const select = node . root . getByRole ( 'combobox' , {
128+ name : 'Native select'
129+ } )
130+
131+ await test . step ( 'Hold and drag the node' , async ( ) => {
132+ await node . header . hover ( )
133+ await using mouseRelease = await comfyMouse . hold ( )
134+ await comfyPage . page . mouse . move ( 500 , 500 , { steps : 5 } )
135+ await expect
136+ . poll ( async ( ) => [
137+ ...( await nodeRef . getProperty < [ number , number ] > ( 'pos' ) )
138+ ] )
139+ . not . toEqual ( positionBeforeDrag )
140+
141+ await test . step ( 'Press Space in the focused native select' , async ( ) => {
142+ await select . focus ( )
143+ await using spaceRelease = await comfyPage . keyboard . hold ( 'Space' )
144+
145+ await expect ( select ) . toBeFocused ( )
146+ await expect . poll ( ( ) => comfyPage . canvasOps . isReadOnly ( ) ) . toBe ( false )
147+ await spaceRelease . disposeAsync ( )
148+ } )
149+
150+ await mouseRelease . disposeAsync ( )
151+ } )
152+ }
153+ )
154+
155+ test (
156+ 'releasing the pointer during Space-pan ends the node drag' ,
157+ { tag : [ '@canvas' , '@node' ] } ,
158+ async ( { comfyPage, comfyMouse } ) => {
159+ await comfyPage . workflow . loadWorkflow ( 'vueNodes/simple-triple' )
160+ const node = await comfyPage . vueNodes . getFixtureByTitle ( 'KSampler' )
161+ const [ nodeRef ] = await comfyPage . nodeOps . getNodeRefsByTitle ( 'KSampler' )
162+ const headerBox = await node . header . boundingBox ( )
163+ if ( ! nodeRef || ! headerBox ) throw new Error ( 'KSampler is not rendered' )
164+ const start = {
165+ x : headerBox . x + headerBox . width / 2 ,
166+ y : headerBox . y + headerBox . height / 2
167+ }
168+
169+ const positionAfterRelease =
170+ await test . step ( 'Release the pointer while Space-panning' , async ( ) => {
171+ await comfyPage . page . mouse . move ( start . x , start . y )
172+ await using mouseRelease = await comfyMouse . hold ( )
173+ await comfyPage . page . mouse . move ( start . x + 40 , start . y + 40 , {
174+ steps : 5
175+ } )
176+ await using spaceRelease = await comfyPage . keyboard . hold ( 'Space' )
177+ await comfyPage . page . mouse . move ( start . x + 80 , start . y + 80 , {
178+ steps : 5
179+ } )
180+ await mouseRelease . disposeAsync ( )
181+ await spaceRelease . disposeAsync ( )
182+
183+ return [ ...( await nodeRef . getProperty < [ number , number ] > ( 'pos' ) ) ]
184+ } )
185+
186+ await test . step ( 'Further pointer movement leaves the node in place' , async ( ) => {
187+ const headerAfterRelease = await node . header . boundingBox ( )
188+ if ( ! headerAfterRelease ) throw new Error ( 'KSampler is not rendered' )
189+ await comfyPage . page . mouse . move (
190+ headerAfterRelease . x + 5 ,
191+ headerAfterRelease . y + 5
192+ )
193+ await comfyPage . nextFrame ( )
194+
195+ await expect
196+ . poll ( async ( ) => [
197+ ...( await nodeRef . getProperty < [ number , number ] > ( 'pos' ) )
198+ ] )
199+ . toEqual ( positionAfterRelease )
200+ } )
201+ }
202+ )
203+
61204 test (
62205 '@mobile Can pan with touch' ,
63206 { tag : '@screenshot' } ,
0 commit comments