@@ -174,6 +174,100 @@ class TestNetworkingCheckpoints(netlib.NetworkCase):
174174
175175 testlib .wait (checkpoint_was_destroyed )
176176
177+ def testCheckpointSessionStorageEventSuccess (self ):
178+ b = self .browser
179+ m = self .machine
180+
181+ self .login_and_go ("/network" )
182+ self .nm_checkpoints_enable ()
183+ b .wait_visible ("#networking" )
184+
185+ iface = 'cockpit1'
186+ self .add_veth (iface , dhcp_cidr = "10.111.114.2/20" )
187+ self .nm_activate_eth (iface )
188+ self .wait_for_iface (iface )
189+
190+ self .select_iface (iface )
191+ b .wait_visible ("#network-interface" )
192+
193+ # Verify sessionStorage is initially false or not set
194+ initial_value = b .call_js_func ("window.sessionStorage.getItem" , "cockpit_has_checkpoint" )
195+ self .assertIn (initial_value , [None , "false" ])
196+
197+ # Change IP settings which will trigger a checkpoint
198+ self .configure_iface_setting ('IPv4' )
199+ b .wait_visible ("#network-ip-settings-dialog" )
200+ b .select_from_dropdown ("#network-ip-settings-select-method" , "manual" )
201+ b .set_input_text ('#network-ip-settings-address-0' , "10.111.114.100" )
202+ b .set_input_text ('#network-ip-settings-netmask-0' , "20" )
203+
204+ # Click save, which triggers checkpoint creation
205+ b .click ("#network-ip-settings-save" )
206+
207+ # Verify sessionStorage becomes true during checkpoint operation
208+ def checkpoint_active ():
209+ value = b .call_js_func ("window.sessionStorage.getItem" , "cockpit_has_checkpoint" )
210+ return value == "true"
211+
212+ testlib .wait (checkpoint_active )
213+
214+ # Wait for operation to complete and sessionStorage to be cleared
215+ def checkpoint_cleared ():
216+ value = b .call_js_func ("window.sessionStorage.getItem" , "cockpit_has_checkpoint" )
217+ return value == "false"
218+
219+ testlib .wait (checkpoint_cleared )
220+
221+ def testCheckpointSessionStorageEventRollback (self ):
222+ b = self .browser
223+ m = self .machine
224+
225+ self .login_and_go ("/network" )
226+ self .nm_checkpoints_enable ()
227+ b .wait_visible ("#networking" )
228+
229+ iface = self .get_iface ("52:54:00:12:34:56" )
230+
231+ if "debian" in m .image :
232+ self .sed_file ("s/managed=false/managed=true/" , "/etc/NetworkManager/NetworkManager.conf" ,
233+ "systemctl restart NetworkManager" )
234+
235+ if m .image == "arch" :
236+ self .sed_file ("s/unmanaged-devices=interface-name:eth0//" , "/etc/NetworkManager/conf.d/noauto.conf" ,
237+ "systemctl restart NetworkManager" )
238+
239+ self .wait_for_iface (iface , prefix = "172." )
240+ self .select_iface (iface )
241+ b .wait_visible ("#network-interface" )
242+
243+ # Verify sessionStorage is initially false or not set
244+ initial_value = b .call_js_func ("window.sessionStorage.getItem" , "cockpit_has_checkpoint" )
245+ self .assertIn (initial_value , [None , "false" ])
246+
247+ # Disconnect interface which will trigger checkpoint and should cause rollback dialog
248+ self .wait_onoff ("label[for='interface-switch']" , val = True )
249+ self .toggle_onoff ("label[for='interface-switch']" )
250+
251+ # Verify sessionStorage becomes true during checkpoint operation
252+ def checkpoint_active ():
253+ value = b .call_js_func ("window.sessionStorage.getItem" , "cockpit_has_checkpoint" )
254+ return value == "true"
255+
256+ testlib .wait (checkpoint_active )
257+
258+ # Wait for dialog to appear (this happens when checkpoint_destroy fails)
259+ with b .wait_timeout (60 ):
260+ b .wait_visible ("#confirm-breaking-change-popup" )
261+
262+ # By the time dialog is visible, sessionStorage should already be cleared
263+ checkpoint_cleared_value = b .call_js_func ("window.sessionStorage.getItem" , "cockpit_has_checkpoint" )
264+ self .assertEqual (checkpoint_cleared_value , "false" )
265+
266+ # Keep the connection (rollback)
267+ b .click ("#confirm-breaking-change-popup button:contains('Keep connection')" )
268+
269+ b .wait_not_present ("#confirm-breaking-change-popup" )
270+
177271
178272if __name__ == '__main__' :
179273 testlib .test_main ()
0 commit comments