44
55import logging
66import shutil
7- import time
87import typing as t
98
109import pytest
1514
1615if t .TYPE_CHECKING :
1716 from libtmux .session import Session
17+ from libtmux .window import Window
1818
1919logger = logging .getLogger (__name__ )
2020
2121
22+ def setup_shell_window (
23+ session : Session ,
24+ window_name : str ,
25+ environment : dict [str , str ] | None = None ,
26+ ) -> Window :
27+ """Set up a shell window with consistent environment and prompt.
28+
29+ Args:
30+ session: The tmux session to create the window in
31+ window_name: Name for the new window
32+ environment: Optional environment variables to set in the window
33+
34+ Returns
35+ -------
36+ The created Window object with shell ready
37+ """
38+ env = shutil .which ("env" )
39+ assert env is not None , "Cannot find usable `env` in PATH."
40+
41+ window = session .new_window (
42+ attach = True ,
43+ window_name = window_name ,
44+ window_shell = f"{ env } PROMPT_COMMAND='' PS1='READY>' sh" ,
45+ environment = environment ,
46+ )
47+
48+ pane = window .active_pane
49+ assert pane is not None
50+
51+ # Wait for shell to be ready
52+ def wait_for_prompt () -> bool :
53+ try :
54+ pane_contents = "\n " .join (pane .capture_pane ())
55+ return "READY>" in pane_contents and len (pane_contents .strip ()) > 0
56+ except Exception :
57+ return False
58+
59+ retry_until (wait_for_prompt , 2 , raises = True )
60+ return window
61+
62+
2263def test_send_keys (session : Session ) -> None :
2364 """Verify Pane.send_keys()."""
2465 pane = session .active_window .active_pane
@@ -66,35 +107,10 @@ def test_set_width(session: Session) -> None:
66107
67108def test_capture_pane (session : Session ) -> None :
68109 """Verify Pane.capture_pane()."""
69- env = shutil .which ("env" )
70- assert env is not None , "Cannot find usable `env` in PATH."
71-
72- # Use PROMPT_COMMAND/PS1 to set a consistent prompt across shells
73- session .new_window (
74- attach = True ,
75- window_name = "capture_pane" ,
76- window_shell = f"{ env } PROMPT_COMMAND='' PS1='READY>' sh" ,
77- )
78-
79- # Give tmux a moment to create the window and start the shell
80- time .sleep (0.1 )
81-
82- pane = session .active_window .active_pane
110+ window = setup_shell_window (session , "capture_pane" )
111+ pane = window .active_pane
83112 assert pane is not None
84113
85- def wait_for_prompt () -> bool :
86- try :
87- pane_contents = "\n " .join (pane .capture_pane ())
88- return "READY>" in pane_contents and len (pane_contents .strip ()) > 0
89- except Exception :
90- return False
91-
92- # Wait for shell to be ready with our custom prompt
93- retry_until (wait_for_prompt , 2 , raises = True )
94-
95- pane_contents = "\n " .join (pane .capture_pane ())
96- assert "READY>" in pane_contents
97-
98114 pane .send_keys (
99115 r'printf "\n%s\n" "Hello World !"' ,
100116 literal = True ,
@@ -123,21 +139,27 @@ def wait_for_output() -> bool:
123139
124140def test_capture_pane_start (session : Session ) -> None :
125141 """Assert Pane.capture_pane() with ``start`` param."""
126- env = shutil .which ("env" )
127- assert env is not None , "Cannot find usable `env` in PATH."
128-
129- session .new_window (
130- attach = True ,
131- window_name = "capture_pane_start" ,
132- window_shell = f"{ env } PS1='$ ' sh" ,
133- )
134- pane = session .active_window .active_pane
142+ window = setup_shell_window (session , "capture_pane_start" )
143+ pane = window .active_pane
135144 assert pane is not None
145+
136146 pane_contents = "\n " .join (pane .capture_pane ())
137- assert pane_contents == "$"
147+ assert "READY>" in pane_contents
148+
138149 pane .send_keys (r'printf "%s"' , literal = True , suppress_history = False )
139- pane_contents = "\n " .join (pane .capture_pane ())
140- assert pane_contents == '$ printf "%s"\n $'
150+
151+ def wait_for_command () -> bool :
152+ try :
153+ pane_contents = "\n " .join (pane .capture_pane ())
154+ except Exception :
155+ return False
156+ else :
157+ has_command = r'printf "%s"' in pane_contents
158+ has_prompts = pane_contents .count ("READY>" ) >= 2
159+ return has_command and has_prompts
160+
161+ retry_until (wait_for_command , 2 , raises = True )
162+
141163 pane .send_keys ("clear -x" , literal = True , suppress_history = False )
142164
143165 def wait_until_pane_cleared () -> bool :
@@ -148,45 +170,53 @@ def wait_until_pane_cleared() -> bool:
148170
149171 def pane_contents_shell_prompt () -> bool :
150172 pane_contents = "\n " .join (pane .capture_pane ())
151- return pane_contents == "$"
173+ return "READY>" in pane_contents and len ( pane_contents . strip ()) > 0
152174
153175 retry_until (pane_contents_shell_prompt , 1 , raises = True )
154176
155177 pane_contents_history_start = pane .capture_pane (start = - 2 )
156- assert pane_contents_history_start [ 0 ] == '$ printf "%s"'
157- assert pane_contents_history_start [ 1 ] == "$ clear -x"
158- assert pane_contents_history_start [- 1 ] == "$"
178+ assert r'READY> printf "%s"' in pane_contents_history_start [ 0 ]
179+ assert "READY> clear -x" in pane_contents_history_start [ 1 ]
180+ assert "READY>" in pane_contents_history_start [- 1 ]
159181
160182 pane .send_keys ("" )
161183
162184 def pane_contents_capture_visible_only_shows_prompt () -> bool :
163185 pane_contents = "\n " .join (pane .capture_pane (start = 1 ))
164- return pane_contents == "$"
186+ return "READY>" in pane_contents and len ( pane_contents . strip ()) > 0
165187
166188 assert retry_until (pane_contents_capture_visible_only_shows_prompt , 1 , raises = True )
167189
168190
169191def test_capture_pane_end (session : Session ) -> None :
170192 """Assert Pane.capture_pane() with ``end`` param."""
171- env = shutil .which ("env" )
172- assert env is not None , "Cannot find usable `env` in PATH."
173-
174- session .new_window (
175- attach = True ,
176- window_name = "capture_pane_end" ,
177- window_shell = f"{ env } PS1='$ ' sh" ,
178- )
179- pane = session .active_window .active_pane
193+ window = setup_shell_window (session , "capture_pane_end" )
194+ pane = window .active_pane
180195 assert pane is not None
196+
181197 pane_contents = "\n " .join (pane .capture_pane ())
182- assert pane_contents == "$"
198+ assert "READY>" in pane_contents
199+
183200 pane .send_keys (r'printf "%s"' , literal = True , suppress_history = False )
184- pane_contents = "\n " .join (pane .capture_pane ())
185- assert pane_contents == '$ printf "%s"\n $'
201+
202+ def wait_for_command () -> bool :
203+ try :
204+ pane_contents = "\n " .join (pane .capture_pane ())
205+ except Exception :
206+ return False
207+ else :
208+ has_command = r'printf "%s"' in pane_contents
209+ has_prompts = pane_contents .count ("READY>" ) >= 2
210+ return has_command and has_prompts
211+
212+ retry_until (wait_for_command , 2 , raises = True )
213+
186214 pane_contents = "\n " .join (pane .capture_pane (end = 0 ))
187- assert pane_contents == '$ printf "%s"'
215+ assert r'READY>printf "%s"' in pane_contents
216+
188217 pane_contents = "\n " .join (pane .capture_pane (end = "-" ))
189- assert pane_contents == '$ printf "%s"\n $'
218+ assert r'READY>printf "%s"' in pane_contents
219+ assert pane_contents .count ("READY>" ) >= 2
190220
191221
192222@pytest .mark .skipif (
0 commit comments