88
99import asyncio
1010import logging
11+ from dataclasses import dataclass
1112from typing import TYPE_CHECKING
1213
1314import pytest
1617from libtmux .session import Session
1718from libtmux .window import Window
1819
20+
21+ @dataclass (slots = True )
22+ class ProjectSessionResult :
23+ """Summary of concurrently created project sessions."""
24+
25+ session_id : str
26+ name : str
27+ window_count : int
28+
29+
1930if TYPE_CHECKING :
2031 from libtmux .server import Server
2132
@@ -65,9 +76,15 @@ async def test_async_full_workflow(server: Server) -> None:
6576 assert any ("integration_test_complete" in line for line in result .stdout )
6677
6778 # Verify complete object hierarchy
68- assert session .session_id == session_id
69- assert window .window_id == window_id
70- assert pane .pane_id == pane_id
79+ session_obj_id = session .session_id
80+ assert session_obj_id is not None
81+ assert session_obj_id == session_id
82+ window_obj_id = window .window_id
83+ assert window_obj_id is not None
84+ assert window_obj_id == window_id
85+ pane_obj_id = pane .pane_id
86+ assert pane_obj_id is not None
87+ assert pane_obj_id == pane_id
7188
7289
7390@pytest .mark .asyncio
@@ -80,7 +97,7 @@ async def test_multi_session_parallel_automation(server: Server) -> None:
8097
8198 async def setup_project_session (
8299 name : str , num_windows : int
83- ) -> dict [ str , str | int ] :
100+ ) -> ProjectSessionResult :
84101 """Create session with multiple windows."""
85102 # Create session
86103 result = await server .acmd (
@@ -105,28 +122,29 @@ async def setup_project_session(
105122 result = await session .acmd ("list-windows" , "-F#{window_id}" )
106123 window_count = len (result .stdout )
107124
108- return {
109- " session_id" : session_id ,
110- " name" : name ,
111- " window_count" : window_count ,
112- }
125+ return ProjectSessionResult (
126+ session_id = session_id ,
127+ name = name ,
128+ window_count = window_count ,
129+ )
113130
114131 # Set up 3 project sessions concurrently
115- results = await asyncio .gather (
132+ results_tuple = await asyncio .gather (
116133 setup_project_session ("project_frontend" , 3 ),
117134 setup_project_session ("project_backend" , 4 ),
118135 setup_project_session ("project_infra" , 2 ),
119136 )
137+ results : list [ProjectSessionResult ] = list (results_tuple )
120138
121139 # Verify all sessions set up correctly
122140 assert len (results ) == 3
123- assert results [0 ][ " window_count" ] == 3
124- assert results [1 ][ " window_count" ] == 4
125- assert results [2 ][ " window_count" ] == 2
141+ assert results [0 ]. window_count == 3
142+ assert results [1 ]. window_count == 4
143+ assert results [2 ]. window_count == 2
126144
127145 # Verify all sessions exist
128146 for result in results :
129- assert server .has_session (result [ " name" ] )
147+ assert server .has_session (result . name )
130148
131149
132150@pytest .mark .asyncio
@@ -300,6 +318,8 @@ async def test_async_pane_workflow_complete(server: Server) -> None:
300318 # Get active pane
301319 pane1 = session .active_pane
302320 assert pane1 is not None
321+ pane1_id = pane1 .pane_id
322+ assert pane1_id is not None
303323
304324 # Send command using asend_keys
305325 await pane1 .asend_keys ('echo "workflow_step_1"' )
@@ -312,10 +332,12 @@ async def test_async_pane_workflow_complete(server: Server) -> None:
312332 # Split pane using asplit
313333 pane2 = await pane1 .asplit ()
314334 assert pane2 is not None
315- assert pane2 .pane_id != pane1 .pane_id
335+ assert pane2 .pane_id is not None
336+ assert pane2 .pane_id != pane1_id
316337
317338 # Verify both panes exist
318339 window = session .active_window
340+ assert window is not None
319341 assert len (window .panes ) == 2
320342
321343 # Send different commands to each pane concurrently
@@ -342,7 +364,7 @@ async def test_multi_window_pane_automation(server: Server) -> None:
342364
343365 Safety: All operations in isolated test server.
344366 Demonstrates: Large-scale concurrent pane manipulation.
345- Pattern: 3 windows × 3 panes = 9 panes, all managed concurrently.
367+ Pattern: 3 windows x 3 panes = 9 panes, all managed concurrently.
346368 """
347369 # Create session
348370 session = await server .anew_session ("multi_window_automation" )
@@ -355,11 +377,12 @@ async def test_multi_window_pane_automation(server: Server) -> None:
355377 )
356378
357379 # Each window should have 1 pane initially
358- all_panes = []
380+ all_panes : list [ Pane ] = []
359381
360382 # For each window, split into 3 panes total
361- for i , window in enumerate (windows_data ):
383+ for _idx , window in enumerate (windows_data ):
362384 base_pane = window .active_pane
385+ assert base_pane is not None
363386
364387 # Create 2 more panes (total 3 per window)
365388 from libtmux .pane import PaneDirection
@@ -370,23 +393,20 @@ async def test_multi_window_pane_automation(server: Server) -> None:
370393 )
371394
372395 # Collect all 3 panes from this window
373- all_panes .extend ([base_pane ] + list ( new_panes ) )
396+ all_panes .extend ([base_pane , * new_panes ] )
374397
375- # Verify we have 9 panes total (3 windows × 3 panes)
398+ # Verify we have 9 panes total (3 windows x 3 panes)
376399 assert len (all_panes ) == 9
377400
378401 # Send unique commands to all 9 panes concurrently
379402 send_tasks = [
380- pane .asend_keys (f'echo "pane_{ i } _output"' )
381- for i , pane in enumerate (all_panes )
403+ pane .asend_keys (f'echo "pane_{ i } _output"' ) for i , pane in enumerate (all_panes )
382404 ]
383405 await asyncio .gather (* send_tasks )
384406 await asyncio .sleep (0.4 )
385407
386408 # Capture output from all 9 panes concurrently
387- outputs = await asyncio .gather (
388- * [pane .acapture_pane () for pane in all_panes ]
389- )
409+ outputs = await asyncio .gather (* [pane .acapture_pane () for pane in all_panes ])
390410
391411 # Verify all panes have correct output
392412 assert len (outputs ) == 9
@@ -405,10 +425,12 @@ async def test_pane_monitoring_dashboard(server: Server) -> None:
405425 # Create session
406426 session = await server .anew_session ("monitoring_dashboard" )
407427 window = session .active_window
428+ assert window is not None
408429
409430 # Create 2x3 grid (6 panes total)
410431 # Start with 1 pane, split to make 6
411432 base_pane = window .active_pane
433+ assert base_pane is not None
412434
413435 from libtmux .pane import PaneDirection
414436
0 commit comments