@@ -638,11 +638,18 @@ async def _press_keys(self, keys: Iterable[str]) -> None:
638638 await app ._animator .wait_for_idle ()
639639
640640 @asynccontextmanager
641- async def run_test (self , * , headless : bool = True ):
641+ async def run_test (
642+ self ,
643+ * ,
644+ headless : bool = True ,
645+ size : tuple [int , int ] | None = (80 , 24 ),
646+ ):
642647 """An asynchronous context manager for testing app.
643648
644649 Args:
645650 headless (bool, optional): Run in headless mode (no output or input). Defaults to True.
651+ size (tuple[int, int] | None, optional): Force terminal size to `(WIDTH, HEIGHT)`,
652+ or None to auto-detect. Defaults to None.
646653
647654 """
648655 from .pilot import Pilot
@@ -655,7 +662,11 @@ def on_app_ready() -> None:
655662 app_ready_event .set ()
656663
657664 async def run_app (app ) -> None :
658- await app ._process_messages (ready_callback = on_app_ready , headless = headless )
665+ await app ._process_messages (
666+ ready_callback = on_app_ready ,
667+ headless = headless ,
668+ terminal_size = size ,
669+ )
659670
660671 # Launch the app in the "background"
661672 app_task = asyncio .create_task (run_app (app ))
@@ -1135,24 +1146,30 @@ async def _process_messages(
11351146
11361147 async def run_process_messages ():
11371148 """The main message loop, invoke below."""
1149+
1150+ async def invoke_ready_callback () -> None :
1151+ if ready_callback is not None :
1152+ ready_result = ready_callback ()
1153+ if inspect .isawaitable (ready_result ):
1154+ await ready_result
1155+
11381156 try :
1139- await self ._dispatch_message (events .Compose (sender = self ))
1140- await self ._dispatch_message (events .Mount (sender = self ))
1141- finally :
1142- self ._mounted_event .set ()
1157+ try :
1158+ await self ._dispatch_message (events .Compose (sender = self ))
1159+ await self ._dispatch_message (events .Mount (sender = self ))
1160+ finally :
1161+ self ._mounted_event .set ()
11431162
1144- Reactive ._initialize_object (self )
1163+ Reactive ._initialize_object (self )
11451164
1146- self .stylesheet .update (self )
1147- self .refresh ()
1165+ self .stylesheet .update (self )
1166+ self .refresh ()
11481167
1149- await self .animator .start ()
1150- await self ._ready ()
1168+ await self .animator .start ()
11511169
1152- if ready_callback is not None :
1153- ready_result = ready_callback ()
1154- if inspect .isawaitable (ready_result ):
1155- await ready_result
1170+ finally :
1171+ await self ._ready ()
1172+ await invoke_ready_callback ()
11561173
11571174 self ._running = True
11581175
@@ -1356,7 +1373,7 @@ async def _shutdown(self) -> None:
13561373 await self ._close_all ()
13571374 await self ._close_messages ()
13581375
1359- await self ._dispatch_message (events .UnMount (sender = self ))
1376+ await self ._dispatch_message (events .Unmount (sender = self ))
13601377
13611378 self ._print_error_renderables ()
13621379 if self .devtools is not None and self .devtools .is_connected :
0 commit comments