11import json
22from copy import copy
3+ from time import sleep
34
45import pytest
56from asgiref .sync import sync_to_async
@@ -34,15 +35,11 @@ class TestRealTime(
3435 ChannelsLiveServerTestCase ,
3536):
3637 app_label = "topology"
38+ prefix = f"admin:{ app_label } "
3739 node_model = Node
3840 link_model = Link
3941 topology_model = Topology
4042 application = import_string (getattr (settings , "ASGI_APPLICATION" ))
41- browser = "chromium"
42-
43- @property
44- def prefix (self ):
45- return f"admin:{ self .app_label } "
4643
4744 def setUp (self ):
4845 org = self ._create_org ()
@@ -72,6 +69,10 @@ def setUp(self):
7269 status = "up" ,
7370 )
7471
72+ def _snooze (self ):
73+ """Allows a bit of time for the UI to update, reduces flakyness"""
74+ sleep (0.2 )
75+
7576 async def _get_communicator (self , admin_client , topology_id ):
7677 session_id = admin_client .cookies ["sessionid" ].value
7778 communicator = WebsocketCommunicator (
@@ -86,26 +87,20 @@ async def _get_communicator(self, admin_client, topology_id):
8687 )
8788 return communicator
8889
89- def update_topology_new_tab (self ):
90- current_url = self .web_driver .current_url
91- self .web_driver .execute_script ("window.open('');" )
92- self .web_driver .switch_to .window (self .web_driver .window_handles [- 1 ])
93- self .web_driver .get (current_url )
94- self .find_element ("name" , "_continue" ).click ()
95- self .web_driver .close ()
96- self .web_driver .switch_to .window (self .web_driver .window_handles [0 ])
97-
9890 async def test_real_time_link_status_update (self ):
91+ # preparation
92+ self .link .status = "down"
93+ await database_sync_to_async (self .link .save )()
9994 communicator = await self ._get_communicator (self .admin_client , self .topology .pk )
10095 connected , _ = await communicator .connect ()
10196 assert connected is True
102-
10397 path = reverse (f"{ self .prefix } _topology_change" , args = [self .topology .pk ])
10498 self .login ()
10599 self .open (path )
106100 self .find_element (By .CSS_SELECTOR , "input.visualizelink" ).click ()
101+ # changing the status of a link will change it in the browser graph too
102+ self .link .status = "up"
107103 await database_sync_to_async (self .link .save )()
108-
109104 message = await communicator .receive_json_from ()
110105 assert (
111106 json .loads (message ["topology" ])["links" ][0 ]["properties" ]["status" ] == "up"
@@ -116,18 +111,15 @@ async def test_real_time_link_status_update(self):
116111 ]["status" ],
117112 "up" ,
118113 )
119-
114+ # test status changing to down
120115 self .link .status = "down"
121116 await sync_to_async (self .link .save )()
122-
123- self .update_topology_new_tab ()
124-
125117 message = await communicator .receive_json_from ()
126118 assert (
127119 json .loads (message ["topology" ])["links" ][0 ]["properties" ]["status" ]
128120 == "down"
129121 )
130-
122+ self . _snooze ()
131123 self .assertEqual (
132124 self .web_driver .execute_script ("return graph.data;" )["links" ][0 ][
133125 "properties"
@@ -137,66 +129,61 @@ async def test_real_time_link_status_update(self):
137129 await communicator .disconnect ()
138130
139131 async def test_node_status_update (self ):
132+ # preparation
140133 communicator = await self ._get_communicator (self .admin_client , self .topology .pk )
141134 connected , _ = await communicator .connect ()
142135 assert connected is True
143-
144136 path = reverse (f"{ self .prefix } _topology_change" , args = [self .topology .pk ])
145137 self .login ()
146138 self .open (path )
147139 self .find_element (By .CSS_SELECTOR , "input.visualizelink" ).click ()
148-
140+ # saving a new node will add it to the UI
149141 new_node = copy (self .node1 )
150142 new_node .pk = None
151143 await database_sync_to_async (new_node .save )()
152- self .update_topology_new_tab ()
153-
154144 message = await communicator .receive_json_from ()
155145 self .assertEqual (len (json .loads (message ["topology" ])["nodes" ]), 3 )
146+ self ._snooze ()
156147 self .assertEqual (
157148 len (self .web_driver .execute_script ("return graph.data;" )["nodes" ]),
158149 3 ,
159150 )
160-
151+ # deleting the node from the DB will remove it from the UI
161152 await database_sync_to_async (new_node .delete )()
162- self .update_topology_new_tab ()
163-
164153 message = await communicator .receive_json_from ()
165154 self .assertEqual (len (json .loads (message ["topology" ])["nodes" ]), 2 )
155+ self ._snooze ()
166156 self .assertEqual (
167157 len (self .web_driver .execute_script ("return graph.data;" )["nodes" ]),
168158 2 ,
169159 )
170160 await communicator .disconnect ()
171161
172162 async def test_node_link_update (self ):
173- new_link = copy (self .link )
174- new_link .pk = None
175-
163+ # preparation
176164 communicator = await self ._get_communicator (self .admin_client , self .topology .pk )
177165 connected , _ = await communicator .connect ()
178166 assert connected is True
179-
180167 path = reverse (f"{ self .prefix } _topology_change" , args = [self .topology .pk ])
181168 self .login ()
182169 self .open (path )
183170 self .find_element (By .CSS_SELECTOR , "input.visualizelink" ).click ()
184-
171+ # deleting the link from the DB will remove it from the UI
185172 await database_sync_to_async (self .link .delete )()
186- self .update_topology_new_tab ()
187-
188173 message = await communicator .receive_json_from ()
189174 self .assertEqual (len (json .loads (message ["topology" ])["links" ]), 0 )
175+ self ._snooze ()
190176 self .assertEqual (
191177 len (self .web_driver .execute_script ("return graph.data;" )["links" ]),
192178 0 ,
193179 )
194-
180+ # adding a link will add it to the UI
181+ new_link = copy (self .link )
182+ new_link .pk = None
195183 await database_sync_to_async (new_link .save )()
196- self .update_topology_new_tab ()
197-
198184 message = await communicator .receive_json_from ()
199185 self .assertEqual (len (json .loads (message ["topology" ])["links" ]), 1 )
186+ self ._snooze ()
200187 self .assertEqual (
201188 len (self .web_driver .execute_script ("return graph.data;" )["links" ]),
202189 1 ,
0 commit comments