Test that the connection banner is displayed when the websocket drops. Args: connection_banner: AppHarness instance. redis: Redis instance used by the app, or None if not using Redis.
(connection_banner: AppHarness, redis: Redis | None)
| 212 | |
| 213 | @pytest.mark.asyncio |
| 214 | async def test_connection_banner(connection_banner: AppHarness, redis: Redis | None): |
| 215 | """Test that the connection banner is displayed when the websocket drops. |
| 216 | |
| 217 | Args: |
| 218 | connection_banner: AppHarness instance. |
| 219 | redis: Redis instance used by the app, or None if not using Redis. |
| 220 | """ |
| 221 | assert connection_banner.app_instance is not None |
| 222 | assert connection_banner.backend is not None |
| 223 | driver = connection_banner.frontend() |
| 224 | |
| 225 | token = _assert_token(connection_banner, driver) |
| 226 | AppHarness.expect(lambda: not has_error_modal(driver)) |
| 227 | |
| 228 | # Check that the token association was established. |
| 229 | app_token_manager = connection_banner.token_manager() |
| 230 | assert token in app_token_manager.token_to_sid |
| 231 | sid_before = app_token_manager.token_to_sid[token] |
| 232 | if redis is not None: |
| 233 | assert isinstance(app_token_manager, RedisTokenManager) |
| 234 | assert await redis.get(app_token_manager._get_redis_key(token)) == pickle.dumps( |
| 235 | SocketRecord(instance_id=app_token_manager.instance_id, sid=sid_before) |
| 236 | ) |
| 237 | |
| 238 | delay_button = driver.find_element(By.ID, "delay") |
| 239 | increment_button = driver.find_element(By.ID, "increment") |
| 240 | counter_element = driver.find_element(By.ID, "counter") |
| 241 | |
| 242 | # Increment the counter |
| 243 | increment_button.click() |
| 244 | assert connection_banner.poll_for_value(counter_element, exp_not_equal="0") == "1" |
| 245 | |
| 246 | # Start a long event before blocking the network, to mark event_processing=true |
| 247 | delay_button.click() |
| 248 | |
| 249 | with browser_offline(driver): |
| 250 | # Error modal should now be displayed |
| 251 | AppHarness.expect(lambda: has_error_modal(driver)) |
| 252 | |
| 253 | # The token association should be removed once the websocket closes on the server. |
| 254 | assert connection_banner._poll_for( |
| 255 | lambda: token not in app_token_manager.token_to_sid |
| 256 | ) |
| 257 | if redis is not None: |
| 258 | assert isinstance(app_token_manager, RedisTokenManager) |
| 259 | assert await redis.get(app_token_manager._get_redis_key(token)) is None |
| 260 | |
| 261 | # Increment the counter while disconnected |
| 262 | increment_button.click() |
| 263 | assert ( |
| 264 | connection_banner.poll_for_value(counter_element, exp_not_equal="0") == "1" |
| 265 | ) |
| 266 | |
| 267 | # Banner should be gone now (network restored on context manager exit) |
| 268 | AppHarness.expect(lambda: not has_error_modal(driver)) |
| 269 | |
| 270 | # After reconnecting, the token association should be re-established. |
| 271 | app_token_manager = connection_banner.token_manager() |
nothing calls this directly
no test coverage detected