11import json
2- from copy import copy
32from time import sleep
43
54import pytest
@@ -40,6 +39,7 @@ class TestRealTime(
4039 link_model = Link
4140 topology_model = Topology
4241 application = import_string (getattr (settings , "ASGI_APPLICATION" ))
42+ browser = "chrome"
4343
4444 def setUp (self ):
4545 org = self ._create_org ()
@@ -68,11 +68,47 @@ def setUp(self):
6868 topology = self .topology ,
6969 status = "up" ,
7070 )
71+ self .org = org
72+
73+ async def _prepare (self , admin = True ):
74+ communicator = await self ._get_communicator (self .admin_client , self .topology .pk )
75+ connected , _ = await communicator .connect ()
76+ assert connected is True
77+ if admin :
78+ path = reverse (f"{ self .prefix } _topology_change" , args = [self .topology .pk ])
79+ else :
80+ path = reverse ("topology_detail" , kwargs = {"pk" : self .topology .pk })
81+ self .login ()
82+ if admin :
83+ self .open (path )
84+ self .find_element (By .CSS_SELECTOR , "input.visualizelink" ).click ()
85+ else :
86+ # non admin visualizer doesn't need clicking to show the graph
87+ self .open (path , html_container = ".djnjg-overlay" )
88+ return communicator
7189
7290 def _snooze (self ):
7391 """Allows a bit of time for the UI to update, reduces flakyness"""
7492 sleep (0.25 )
7593
94+ def _create_node3 (self ):
95+ self .node3 = self ._create_node (
96+ label = "node3" ,
97+ addresses = ["192.168.0.3" ],
98+ topology = self .topology ,
99+ organization = self .org ,
100+ )
101+
102+ def _assert_no_js_errors (self ):
103+ browser_logs = []
104+ for log in self .get_browser_logs ():
105+ # ignore random 403 errors
106+ if log ["level" ] == "SEVERE" and "403" in log ["message" ]:
107+ continue
108+ else :
109+ browser_logs .append (log )
110+ self .assertEqual (browser_logs , [])
111+
76112 async def _get_communicator (self , admin_client , topology_id ):
77113 session_id = admin_client .cookies ["sessionid" ].value
78114 communicator = WebsocketCommunicator (
@@ -91,13 +127,7 @@ async def test_real_time_link_status_update(self):
91127 # preparation
92128 self .link .status = "down"
93129 await database_sync_to_async (self .link .save )()
94- communicator = await self ._get_communicator (self .admin_client , self .topology .pk )
95- connected , _ = await communicator .connect ()
96- assert connected is True
97- path = reverse (f"{ self .prefix } _topology_change" , args = [self .topology .pk ])
98- self .login ()
99- self .open (path )
100- self .find_element (By .CSS_SELECTOR , "input.visualizelink" ).click ()
130+ communicator = await self ._prepare ()
101131 # changing the status of a link will change it in the browser graph too
102132 self .link .status = "up"
103133 await database_sync_to_async (self .link .save )()
@@ -127,33 +157,28 @@ async def test_real_time_link_status_update(self):
127157 ]["status" ],
128158 "down" ,
129159 )
160+ self ._assert_no_js_errors ()
130161 await communicator .disconnect ()
131162
132163 async def test_node_status_update (self ):
133164 # preparation
134- communicator = await self ._get_communicator (self .admin_client , self .topology .pk )
135- connected , _ = await communicator .connect ()
136- assert connected is True
137- path = reverse (f"{ self .prefix } _topology_change" , args = [self .topology .pk ])
138- self .login ()
139- self .open (path )
140- self .find_element (By .CSS_SELECTOR , "input.visualizelink" ).click ()
165+ communicator = await self ._prepare ()
141166 # saving a new node will add it to the UI
142- new_node = copy (self .node1 )
143- new_node .pk = None
144- await database_sync_to_async (new_node .save )()
167+ await database_sync_to_async (self ._create_node3 )()
145168 message = await communicator .receive_json_from ()
146169 self .assertEqual (len (json .loads (message ["topology" ])["nodes" ]), 3 )
147170 self ._snooze ()
171+ self ._assert_no_js_errors ()
148172 self .assertEqual (
149173 len (self .web_driver .execute_script ("return graph.data;" )["nodes" ]),
150174 3 ,
151175 )
152176 # deleting the node from the DB will remove it from the UI
153- await database_sync_to_async (new_node .delete )()
177+ await database_sync_to_async (self . node3 .delete )()
154178 message = await communicator .receive_json_from ()
155179 self .assertEqual (len (json .loads (message ["topology" ])["nodes" ]), 2 )
156180 self ._snooze ()
181+ self ._assert_no_js_errors ()
157182 self .assertEqual (
158183 len (self .web_driver .execute_script ("return graph.data;" )["nodes" ]),
159184 2 ,
@@ -162,29 +187,23 @@ async def test_node_status_update(self):
162187
163188 async def test_node_link_update (self ):
164189 # preparation
165- communicator = await self ._get_communicator (self .admin_client , self .topology .pk )
166- connected , _ = await communicator .connect ()
167- assert connected is True
168- path = reverse (f"{ self .prefix } _topology_change" , args = [self .topology .pk ])
169- self .login ()
170- self .open (path )
171- self .find_element (By .CSS_SELECTOR , "input.visualizelink" ).click ()
190+ communicator = await self ._prepare ()
172191 # deleting the link from the DB will remove it from the UI
173192 await database_sync_to_async (self .link .delete )()
174193 message = await communicator .receive_json_from ()
175194 self .assertEqual (len (json .loads (message ["topology" ])["links" ]), 0 )
176195 self ._snooze ()
196+ self ._assert_no_js_errors ()
177197 self .assertEqual (
178198 len (self .web_driver .execute_script ("return graph.data;" )["links" ]),
179199 0 ,
180200 )
181201 # adding a link will add it to the UI
182- new_link = copy (self .link )
183- new_link .pk = None
184- await database_sync_to_async (new_link .save )()
202+ await database_sync_to_async (self .link .save )()
185203 message = await communicator .receive_json_from ()
186204 self .assertEqual (len (json .loads (message ["topology" ])["links" ]), 1 )
187205 self ._snooze ()
206+ self ._assert_no_js_errors ()
188207 self .assertEqual (
189208 len (self .web_driver .execute_script ("return graph.data;" )["links" ]),
190209 1 ,
@@ -193,44 +212,44 @@ async def test_node_link_update(self):
193212
194213 async def test_non_admin_visualizer (self ):
195214 # preparation
196- communicator = await self ._get_communicator (self .admin_client , self .topology .pk )
197- connected , _ = await communicator .connect ()
198- assert connected is True
199- path = reverse ("topology_detail" , kwargs = {"pk" : self .topology .pk })
200- self .login ()
201- self .open (path , html_container = ".djnjg-overlay" )
215+ communicator = await self ._prepare (admin = False )
202216 # changing the status of a link will change it in the browser graph too
203- self .link .status = "down"
204- await database_sync_to_async (self .link .save )()
205- message = await communicator .receive_json_from ()
206- assert (
207- json .loads (message ["topology" ])["links" ][0 ]["properties" ]["status" ]
208- == "down"
209- )
210- self ._snooze ()
211- self .assertEqual (
212- self .web_driver .execute_script ("return graph.data;" )["links" ][0 ][
213- "properties"
214- ]["status" ],
215- "down" ,
216- )
217+ with self .subTest ("change link status" ):
218+ self .link .status = "down"
219+ await database_sync_to_async (self .link .save )()
220+ message = await communicator .receive_json_from ()
221+ assert (
222+ json .loads (message ["topology" ])["links" ][0 ]["properties" ]["status" ]
223+ == "down"
224+ )
225+ self ._snooze ()
226+ self ._assert_no_js_errors ()
227+ self .assertEqual (
228+ self .web_driver .execute_script ("return graph.data;" )["links" ][0 ][
229+ "properties"
230+ ]["status" ],
231+ "down" ,
232+ )
217233 # removing a link from the DB will remove it from the UI
218- await database_sync_to_async (self .link .delete )()
219- message = await communicator .receive_json_from ()
220- self .assertEqual (len (json .loads (message ["topology" ])["links" ]), 0 )
221- self ._snooze ()
222- self .assertEqual (
223- len (self .web_driver .execute_script ("return graph.data;" )["links" ]),
224- 0 ,
225- )
234+ with self .subTest ("remove link" ):
235+ await database_sync_to_async (self .link .delete )()
236+ message = await communicator .receive_json_from ()
237+ self .assertEqual (len (json .loads (message ["topology" ])["links" ]), 0 )
238+ self ._snooze ()
239+ self ._assert_no_js_errors ()
240+ self .assertEqual (
241+ len (self .web_driver .execute_script ("return graph.data;" )["links" ]),
242+ 0 ,
243+ )
226244 # creating a new node will add it to the UI
227- new_node = copy (self .node1 )
228- new_node .pk = None
229- await database_sync_to_async (new_node .save )()
230- message = await communicator .receive_json_from ()
231- self .assertEqual (len (json .loads (message ["topology" ])["nodes" ]), 3 )
232- self ._snooze ()
233- self .assertEqual (
234- len (self .web_driver .execute_script ("return graph.data;" )["nodes" ]),
235- 3 ,
236- )
245+ with self .subTest ("add node" ):
246+ await database_sync_to_async (self ._create_node3 )()
247+ message = await communicator .receive_json_from ()
248+ self .assertEqual (len (json .loads (message ["topology" ])["nodes" ]), 3 )
249+ self ._assert_no_js_errors ()
250+ self ._snooze ()
251+ self .assertEqual (
252+ len (self .web_driver .execute_script ("return graph.data;" )["nodes" ]),
253+ 3 ,
254+ )
255+ await communicator .disconnect ()
0 commit comments