Skip to content

Commit 0a4f2cb

Browse files
vladimirnanicarltongibson
authored andcommitted
Selenium waits on message to be handled
Removes flakiness on fast machine
1 parent 0ccef11 commit 0a4f2cb

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

tests/sample_project/sampleapp/static/sampleapp/js/scripts.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
const socket = new WebSocket(wsPath);
1313

1414
window.websocketConnected = false;
15+
window.messageHandled = false;
1516

1617
socket.onopen = () => {
1718
window.websocketConnected = true;
@@ -27,6 +28,7 @@
2728
function handleMessage(e) {
2829
const data = JSON.parse(e.data);
2930
renderState(data.count, data.messages);
31+
window.messageHandled = true;
3032
}
3133

3234
function renderState(count, messages) {

tests/sample_project/tests/selenium_mixin.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,21 @@ def wait_for_websocket_connection(self, substring="WebSocket connected", timeout
141141
f"Timed out waiting for window.websocketConnected after {timeout}s"
142142
)
143143

144+
def wait_for_websocket_message_handled(self, timeout=5):
145+
"""
146+
Wait until window.messageHandled is true, or fail after timeout.
147+
"""
148+
try:
149+
WebDriverWait(self.web_driver, timeout).until(
150+
lambda d: d.execute_script("return window.messageHandled === true")
151+
)
152+
except TimeoutException:
153+
logs = self.get_browser_logs()
154+
print("\n Browser logs on WS-flag timeout:")
155+
for entry in logs:
156+
print(f"[{entry['level']}] {entry['message']}")
157+
self.fail(f"Timed out waiting for window.messageHandled after {timeout}s")
158+
144159
def tearDown(self):
145160
logs = self.web_driver.get_log("browser")
146161
severe_logs = [entry for entry in logs if entry.get("level") == "SEVERE"]

tests/sample_project/tests/test_selenium.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ class TestSampleApp(SeleniumMixin, ChannelsLiveServerTestCase):
1313
def setUp(self):
1414
super().setUp()
1515
self.login()
16+
self.open_admin_message_page()
17+
18+
def open_admin_message_page(self):
1619
self.open("/admin/sampleapp/message/")
1720
self.wait_for_websocket_connection()
1821

@@ -29,7 +32,7 @@ def test_real_time_create_message(self):
2932
tabs = self.web_driver.window_handles
3033
self.web_driver.switch_to.window(tabs[1])
3134

32-
self.open("/admin/sampleapp/message/")
35+
self.open_admin_message_page()
3336
titleInput = self.find_element(By.ID, "msgTitle")
3437
self.assertIsNotNone(titleInput, "Title input should be present")
3538
messageInput = self.find_element(By.ID, "msgTextArea")
@@ -52,6 +55,7 @@ def test_real_time_create_message(self):
5255
def test_real_time_delete_message(self):
5356
self._create_message()
5457
self.web_driver.refresh()
58+
self.wait_for_websocket_message_handled()
5559

5660
messageCount = self.find_element(By.ID, "messageCount")
5761
self.assertIsNotNone(messageCount, "Message count should be present")
@@ -61,7 +65,7 @@ def test_real_time_delete_message(self):
6165
tabs = self.web_driver.window_handles
6266
self.web_driver.switch_to.window(tabs[1])
6367

64-
self.open("/admin/sampleapp/message/")
68+
self.open_admin_message_page()
6569
deleteButton = self.find_element(By.ID, "deleteBtn")
6670
self.assertIsNotNone(deleteButton, "Delete button should be present")
6771
deleteButton.click()

0 commit comments

Comments
 (0)