Skip to content

Commit 630065d

Browse files
committed
test: Add integration tests for async pane workflows (3 tests)
Add comprehensive integration tests demonstrating real-world async pane automation patterns. New tests in tests/asyncio/test_integration.py: 1. test_async_pane_workflow_complete - Complete pane lifecycle demonstration - Pattern: Create → send → capture → split → concurrent ops - Uses: asend_keys, acapture_pane, asplit - Verifies: Full async workflow end-to-end 2. test_multi_window_pane_automation - Complex workspace setup (3 windows × 3 panes = 9 panes) - Pattern: Concurrent window and pane creation - Uses: anew_window, asplit, asend_keys, acapture_pane - Verifies: Large-scale concurrent automation 3. test_pane_monitoring_dashboard - Monitoring dashboard pattern (2×3 grid = 6 panes) - Pattern: Periodic concurrent capture from multiple panes - Uses: asplit, asend_keys, acapture_pane (in monitoring loops) - Verifies: Real-world monitoring use case All tests: - Use isolated TestServer fixture - Demonstrate concurrent async patterns - Include comprehensive safety documentation - Test real-world automation scenarios Total: 3 new integration tests, all passing Test time: ~2 seconds for all 3 tests These tests demonstrate the practical value of async pane methods for real-world tmux automation workflows.
1 parent 11c2936 commit 630065d

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed

tests/asyncio/test_integration.py

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,188 @@ async def create_session_with_timeout(
279279
# All should succeed with reasonable timeout
280280
assert len(results) == 3
281281
assert all(success for _, success in results)
282+
283+
284+
# ============================================================================
285+
# Async Pane Method Integration Tests
286+
# ============================================================================
287+
288+
289+
@pytest.mark.asyncio
290+
async def test_async_pane_workflow_complete(server: Server) -> None:
291+
"""Test complete pane lifecycle with new async methods.
292+
293+
Safety: All operations in isolated test server.
294+
Demonstrates: Full async workflow using asend_keys, acapture_pane, asplit.
295+
Pattern: Create -> send -> capture -> split -> concurrent ops -> cleanup.
296+
"""
297+
# Create session
298+
session = await server.anew_session("pane_workflow_test")
299+
300+
# Get active pane
301+
pane1 = session.active_pane
302+
assert pane1 is not None
303+
304+
# Send command using asend_keys
305+
await pane1.asend_keys('echo "workflow_step_1"')
306+
await asyncio.sleep(0.2)
307+
308+
# Capture output using acapture_pane
309+
output1 = await pane1.acapture_pane()
310+
assert any("workflow_step_1" in line for line in output1)
311+
312+
# Split pane using asplit
313+
pane2 = await pane1.asplit()
314+
assert pane2 is not None
315+
assert pane2.pane_id != pane1.pane_id
316+
317+
# Verify both panes exist
318+
window = session.active_window
319+
assert len(window.panes) == 2
320+
321+
# Send different commands to each pane concurrently
322+
await asyncio.gather(
323+
pane1.asend_keys('echo "pane1_data"'),
324+
pane2.asend_keys('echo "pane2_data"'),
325+
)
326+
await asyncio.sleep(0.3)
327+
328+
# Capture outputs concurrently
329+
outputs = await asyncio.gather(
330+
pane1.acapture_pane(),
331+
pane2.acapture_pane(),
332+
)
333+
334+
# Verify both outputs
335+
assert any("pane1_data" in line for line in outputs[0])
336+
assert any("pane2_data" in line for line in outputs[1])
337+
338+
339+
@pytest.mark.asyncio
340+
async def test_multi_window_pane_automation(server: Server) -> None:
341+
"""Test complex multi-window, multi-pane async automation.
342+
343+
Safety: All operations in isolated test server.
344+
Demonstrates: Large-scale concurrent pane manipulation.
345+
Pattern: 3 windows × 3 panes = 9 panes, all managed concurrently.
346+
"""
347+
# Create session
348+
session = await server.anew_session("multi_window_automation")
349+
350+
# Create 3 windows concurrently
351+
windows_data = await asyncio.gather(
352+
session.anew_window(window_name="window1"),
353+
session.anew_window(window_name="window2"),
354+
session.anew_window(window_name="window3"),
355+
)
356+
357+
# Each window should have 1 pane initially
358+
all_panes = []
359+
360+
# For each window, split into 3 panes total
361+
for i, window in enumerate(windows_data):
362+
base_pane = window.active_pane
363+
364+
# Create 2 more panes (total 3 per window)
365+
from libtmux.pane import PaneDirection
366+
367+
new_panes = await asyncio.gather(
368+
base_pane.asplit(direction=PaneDirection.Right),
369+
base_pane.asplit(direction=PaneDirection.Below),
370+
)
371+
372+
# Collect all 3 panes from this window
373+
all_panes.extend([base_pane] + list(new_panes))
374+
375+
# Verify we have 9 panes total (3 windows × 3 panes)
376+
assert len(all_panes) == 9
377+
378+
# Send unique commands to all 9 panes concurrently
379+
send_tasks = [
380+
pane.asend_keys(f'echo "pane_{i}_output"')
381+
for i, pane in enumerate(all_panes)
382+
]
383+
await asyncio.gather(*send_tasks)
384+
await asyncio.sleep(0.4)
385+
386+
# Capture output from all 9 panes concurrently
387+
outputs = await asyncio.gather(
388+
*[pane.acapture_pane() for pane in all_panes]
389+
)
390+
391+
# Verify all panes have correct output
392+
assert len(outputs) == 9
393+
for i, output in enumerate(outputs):
394+
assert any(f"pane_{i}_output" in line for line in output)
395+
396+
397+
@pytest.mark.asyncio
398+
async def test_pane_monitoring_dashboard(server: Server) -> None:
399+
"""Test monitoring dashboard pattern with async pane methods.
400+
401+
Safety: All operations in isolated test server.
402+
Demonstrates: Real-world monitoring use case with periodic capture.
403+
Pattern: 2x3 grid of panes, periodic concurrent monitoring.
404+
"""
405+
# Create session
406+
session = await server.anew_session("monitoring_dashboard")
407+
window = session.active_window
408+
409+
# Create 2x3 grid (6 panes total)
410+
# Start with 1 pane, split to make 6
411+
base_pane = window.active_pane
412+
413+
from libtmux.pane import PaneDirection
414+
415+
# Create top row (3 panes)
416+
pane2 = await base_pane.asplit(direction=PaneDirection.Right)
417+
pane3 = await base_pane.asplit(direction=PaneDirection.Right)
418+
419+
# Create bottom row (3 more panes)
420+
pane4 = await base_pane.asplit(direction=PaneDirection.Below)
421+
pane5 = await pane2.asplit(direction=PaneDirection.Below)
422+
pane6 = await pane3.asplit(direction=PaneDirection.Below)
423+
424+
all_panes = [base_pane, pane2, pane3, pane4, pane5, pane6]
425+
426+
# Verify grid created
427+
assert len(window.panes) == 6
428+
429+
# Send "monitoring" commands to each pane
430+
monitor_commands = [
431+
'echo "CPU: 45%"',
432+
'echo "Memory: 60%"',
433+
'echo "Disk: 30%"',
434+
'echo "Network: 100Mbps"',
435+
'echo "Processes: 150"',
436+
'echo "Uptime: 5 days"',
437+
]
438+
439+
await asyncio.gather(
440+
*[
441+
pane.asend_keys(cmd)
442+
for pane, cmd in zip(all_panes, monitor_commands, strict=False)
443+
]
444+
)
445+
await asyncio.sleep(0.3)
446+
447+
# Periodically capture all panes (simulate 3 monitoring rounds)
448+
for round_num in range(3):
449+
# Capture all panes concurrently
450+
outputs = await asyncio.gather(*[pane.acapture_pane() for pane in all_panes])
451+
452+
# Verify all panes have output
453+
assert len(outputs) == 6
454+
455+
# Verify specific monitoring data appears
456+
assert any("CPU:" in line for line in outputs[0])
457+
assert any("Memory:" in line for line in outputs[1])
458+
assert any("Disk:" in line for line in outputs[2])
459+
460+
# Wait before next monitoring round
461+
if round_num < 2:
462+
await asyncio.sleep(0.2)
463+
464+
# Verify dashboard functional after 3 rounds
465+
final_outputs = await asyncio.gather(*[pane.acapture_pane() for pane in all_panes])
466+
assert all(len(output) > 0 for output in final_outputs)

0 commit comments

Comments
 (0)