ttytest2 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba5f1abfa44480c3955c2c0ff48e724ea09f060aa90417caa72cdcf2b15a29bc
4
- data.tar.gz: 904200415a856ad8e9b077ea30f5bc9dea085f966ec896e5e19d328b39039000
3
+ metadata.gz: 360be4f6d7358f00c2462a247939072ab8e93e1b64f9465112c62b6f9a22a484
4
+ data.tar.gz: 7ede22ea96c9ce32546111761d730c008da042b997914e59b6d63bf1e4b06d69
5
5
  SHA512:
6
- metadata.gz: 8d117e8a03132b3a0dd0c93bc0c8a864ffce023d286c98e495a7b8ddafccbdff49d7f2db49c864ceae9f88fd4529322294ec7c7b2e925806e7af721d94ba12e0
7
- data.tar.gz: 1809000f0fea428a053449c07b7b94ca93028dfe3c91d815f0d903bb052c48736f542edb2493cd4fde39bed3c0fa495adca1bd14afccbe186c4cdf9735f54cf5
6
+ metadata.gz: 739fde4fb24d1a2a2a6179c5433be0191587f6e6f4aad92c495880991140569ad82821e8e3285bca1cd908f067adb3d404fd70c696b8cb1d973ee4d3fbb8349a
7
+ data.tar.gz: 7c4472bb3d2cebfbbcf29edb62cbee8f16c8ae84bcd59e8263c108f71e0db89da1ab7fdd1c9c8dfa06f2047b9bae8d7e9e0016718a9ddcfb2ac89d91407efe10
data/README.md CHANGED
@@ -4,13 +4,13 @@
4
4
  <img src="images/ttytest2.png" alt="ttytest2 logo" style="width:70%; height:auto;">
5
5
  </a>
6
6
 
7
- ttytest2 is a user acceptance test framework for CLI & shell applications.
7
+ ttytest2 is a integration test framework for CLI, TUI, & shell applications.
8
8
 
9
9
  ttytest2 is a fork and a drop-in replacement for [ttytest](https://github.com/jhawthorn/ttytest).
10
10
 
11
11
  It works by creating a tmux session behind the scenes, running the specified commands, capturing the pane, and then comparing the actual content to the expected content based on the assertions made.
12
12
 
13
- The assertions will wait a specified amount of time (configurable, default 2 seconds) for the expected content to appear.
13
+ The assertions will wait a configuable amount of time (default 2 seconds) for the expected content to appear before failing.
14
14
 
15
15
  [![Gem Version](https://badge.fury.io/rb/ttytest2.svg?icon=si%3Arubygems)](https://badge.fury.io/rb/ttytest2)
16
16
 
@@ -38,6 +38,8 @@ The assertions will wait a specified amount of time (configurable, default 2 sec
38
38
  * Download the [gem](https://rubygems.org/gems/ttytest2) here.
39
39
  * More documentation available at [ttytest2 docs](https://www.rubydoc.info/gems/ttytest2).
40
40
  * There are more examples in the examples folder.
41
+ * Synchronous example: [ncsh synchronous tests](https://github.com/a-eski/ncsh/blob/main/acceptance_tests/tests/acceptance_tests.rb)
42
+ * Concurrent & generated example: [ncsh concurrent tests](https://github.com/a-eski/ncsh/blob/main/acceptance_tests/minitest/tests.rb)
41
43
 
42
44
  ### Simple Example
43
45
 
@@ -77,11 +79,11 @@ TTY
77
79
 
78
80
  Call one of these methods to initialize an instance of ttytest2.
79
81
 
80
- * `new_terminal(cmd, width, height)`: initialize new tmux terminal instance and run cmd.
82
+ * `new_terminal(cmd, width, height, max_wait_time, use_return_for_newline)`: initialize new tmux terminal instance and run cmd.
81
83
 
82
84
  * `new_default_sh_terminal()`: intialize new tmux terminal instance using sh, width of 80, height of 24.
83
85
 
84
- * `new_sh_terminal(width, height)`: intialize new tmux terminal instance using sh and width and height parameters.
86
+ * `new_sh_terminal(width, height, max_wait_time, use_return_for_newline)`: intialize new tmux terminal instance using sh.
85
87
 
86
88
  ``` ruby
87
89
  require 'ttytest'
@@ -96,6 +98,8 @@ require 'ttytest'
96
98
  # you can also use other shells, like bash
97
99
  @tty = TTYtest.new_terminal('/bin/bash')
98
100
  @tty = TTYtest.new_terminal('/bin/bash', width: 80, height: 24)
101
+
102
+ # you can specify further options, see section Configurables.
99
103
  ```
100
104
 
101
105
  ## Assertions
@@ -128,6 +132,12 @@ If you are reading this on github, the ruby docs accessible from [RubyDoc.Info](
128
132
 
129
133
  * `assert_rows_each_match_regexp(row_start, row_end, regexp_str)`
130
134
 
135
+ * `assert_column(col_number, expected_text)`
136
+
137
+ * `assert_column_is_empty(col_number)`
138
+
139
+ * `assert_column_at(col_number, row_start, row_end, expected_str)`
140
+
131
141
  * `assert_cursor_position(x: x, y: y)`
132
142
 
133
143
  * `assert_cursor_visible`
@@ -162,17 +172,17 @@ Note: Most of the time send_line has the best ergonomics.
162
172
 
163
173
  ### Base Functions
164
174
 
165
- These functions form the basis of interacting with the tmux pane. They power all other functions, but you can use them directly when needed.
175
+ These functions form the basis of interacting with the tmux pane. Internally they power the other functions, but you can also use them directly.
166
176
 
167
- * `send_keys(output)`: for canonical shells/CLI's (or multi-character keys for noncanonical shells/CLI's).
177
+ * `send_keys(output)`: for canonical apps (or multi-character keys for noncanonical apps).
168
178
 
169
- * `send_keys_one_at_a_time(output)`: for noncanonical shells/CLI's.
179
+ * `send_keys_one_at_a_time(output)`: for noncanonical apps.
170
180
 
171
- * `send_keys_exact(output)`: sends keys as is, exactly. Also useful for sending tmux specific keys (any supported tmux send-keys arguments like: DC for delete, Escape for ESC, etc.)
181
+ * `send_keys_exact(output)`: sends keys as is, exactly. Also useful for sending tmux specific keys (any tmux send-keys arguments like: DC (delete), Escape (ESC), etc.)
172
182
 
173
183
  ### Ergonomic Functions
174
184
 
175
- The base functions work great, but these functions build upon the base functions to provide more functionality and better ergonomics in most cases.
185
+ The base functions work great, but these functions build upon the base functions to provide more functionalities and better ergonomics.
176
186
 
177
187
  For example, `send_line(line)` makes sure that the enter key (newline character) is sent after the `line` so you don't have to worry about adding it to `line` or calling send_newline after.
178
188
 
@@ -188,16 +198,23 @@ For example, `send_line(line)` makes sure that the enter key (newline character)
188
198
 
189
199
  * `send_line_exact`: send line exactly as is to tmux. Certain special characters may not work with send_line. You can also include tmux send-keys arguments like DC for delete, etc.
190
200
 
201
+ * `send_line_exact_then_sleep(line, sleep_time)`: simulate typing in a command in the terminal and hitting enter using send_line_exact semantics, then wait for sleep_time seconds.
202
+
191
203
  * `send_lines_exact`: send lines exactly are they are to tmux. Similar semantics to send_line_exact.
192
204
 
205
+ * `send_lines_exact_then_sleep(lines, sleep_time)`: for each line in lines, simulate sending the line and hitting enter using send_line_exact semantics. After sending all the lines, sleep for sleep_time.
206
+
207
+ * `send_line_exact_then_sleep_and_repeat(lines, sleep_time)`: for each line in lines, simulate sending the line and hitting enter using send_line_exact, then sleep before sending the next line.
208
+
193
209
  ### Output Helpers
194
210
 
195
211
  Helper functions to make sending output easier! They use the methods above under 'Sending Output' section under the hood.
196
212
 
197
213
  * `send_newline` # simulate hitting enter, equivalent to @tty.send_keys(%(\n))
198
214
  * `send_newlines(number_of_times)` # equivalent to calling send_newline number_of_times
199
- * `send_enter` # alias for send_newline
200
- * `send_enters(number_of_times)` # alias for send_newlines
215
+
216
+ * `send_return` # simulate hitting enter, equivalent to @tty.send_keys(%(\r))
217
+ * `send_returns(number_of_times)` # equivalent to calling send_return number_of_times
201
218
 
202
219
  * `send_backspace` # simulate hitting backspace, equivalent to @tty.send_keys(TTYtest::BACKSPACE)
203
220
  * `send_backspaces(number_of_times)` # equivalent to calling send_backspace number_of_times
@@ -225,6 +242,9 @@ Helper functions to make sending output easier! They use the methods above under
225
242
  * `send_escape`
226
243
  * `send_escapes(number_of_times)`
227
244
 
245
+ * `send_tab`
246
+ * `send_tab(number_of_times)`
247
+
228
248
  ### F keys?
229
249
 
230
250
  Send F keys like F1, F2, etc. as shown below:
@@ -241,9 +261,12 @@ Send F keys like F1, F2, etc. as shown below:
241
261
 
242
262
  ### Constants
243
263
 
244
- There are some commonly used keys available as constants to make interacting with your shell/CLI easy.
264
+ Commonly used keys are available as constants to simplify use.
245
265
 
246
266
  ``` ruby
267
+ # can use like:
268
+ send_keys_exact(TTYtest::CTRLA)
269
+
247
270
  TTYtest::CTRLA
248
271
  TTYtest::CTRLB
249
272
  TTYtest::CTRLC
@@ -258,7 +281,7 @@ There are some commonly used keys available as constants to make interacting wit
258
281
  TTYtest::SHIFT_ENTER # \v
259
282
  TTYtest::FORM_FEED # \f or New Page NP
260
283
  TTYtest::CTRLL
261
- TTYtest::CARRIAGE_RETURN # \r
284
+ TTYtest::RETURN # \r
262
285
  TTYtest::CTRLU
263
286
  TTYtest::CTRLW
264
287
  TTYtest::ESCAPE # 27 decimal or ^[ or /033
@@ -278,9 +301,11 @@ There are some commonly used keys available as constants to make interacting wit
278
301
 
279
302
  ## Configurables
280
303
 
281
- Currently the only configuration for ttytest2 is max wait time.
304
+ There are 2 main configurations for ttytest2: max_wait_time, and use_return_for_newline.
305
+
306
+ ### Max wait time
282
307
 
283
- Max wait time represents the amount of time in seconds that ttytest2 will keep retrying an assertion before failing.
308
+ Max wait time represents the amount of time in seconds that ttytest2 will keep retrying an assertion before failing that assertion.
284
309
 
285
310
  You can configure max wait time as shown below.
286
311
 
@@ -292,6 +317,24 @@ You can configure max wait time as shown below.
292
317
  @tty.assert_row(0, 'echo Hello, world') # this assertion would fail after 3 seconds
293
318
  ```
294
319
 
320
+ ### Use return for newline
321
+
322
+ Use return for newline tells ttytest2 to use return ('/r') instead of newline ('/n') for methods like send_line, send_line_exact, etc.
323
+
324
+ Some line readers may interpreter return and newline differently, so this can be useful in those cases.
325
+
326
+ You can still send newline via send_newline when this is enabled.
327
+
328
+ You can also send return by itself with send_return.
329
+
330
+ ``` ruby
331
+ @tty = TTYtest::new_terminal('', use_return_for_newline: true) # specified to use return in place of newline
332
+
333
+ @tty.send_line('hello, world!') # will have return sent after 'hello, world!'
334
+ @tty.use_return_for_newline = false
335
+ @tty.assert_row(0, 'echo Hello, world') # will have newline sent after 'echo Hello, world'
336
+ ```
337
+
295
338
  ## Troubleshooting
296
339
 
297
340
  You can use the method rows to get all rows of the terminal as an array, of use the method capture to get the contents of the terminal window. This can be useful when troubleshooting.
@@ -321,9 +364,11 @@ p "\n#{@tty.capture}" # this is equivalent to above statement @tty.print
321
364
 
322
365
  ## Tips
323
366
 
324
- If you are using ttyest2 to test your CLI, using sh is easier than bash because you don't have to worry about user, current working directory, etc. as shown in the examples.
367
+ If you are using ttyest2 to test your CLI, using sh can be easier than bash because you don't have to worry about user, current working directory, etc. as shown in the examples.
368
+
369
+ The assertions like `assert_row_like`, `assert_row_starts_with`, and `assert_row_ends_with` are usually extremely helpful, especially if trying to test your application in different environments or using a docker container with a shell that is not sh.
325
370
 
326
- If you are using ttytest2 to test your shell, using assertions like `assert_row_like`, `assert_row_starts_with`, and `assert_row_ends_with` are going to be extremely helpful, especially if trying to test your shell in different environments or using a docker container.
371
+ Most line readers use '\n' for newline, but some may interpret newline and return differently or expect '\r' for the enter key.
327
372
 
328
373
  ## Docker
329
374
 
@@ -37,5 +37,36 @@ module TTYtest
37
37
  "expected column #{col_number} to be empty\nEntire screen:\n#{self}"
38
38
  end
39
39
  end
40
+
41
+ # Asserts the contents of a column contain the expected string at the specified position
42
+ # @param [Integer] col_number the column (starting from 0) to test against
43
+ # @param [Integer] row_start the row position to start comparing expected against
44
+ # @param [Integer] row_end the row position to end comparing expected against (inclusive)
45
+ # @param [String] expected the expected value that the row starts with. Any trailing whitespace is ignored
46
+ # @raise [MatchError] if the column doesn't match
47
+ def assert_column_at(col_number, row_start, row_end, expected)
48
+ validate(col_number)
49
+ expected = expected.rstrip
50
+ actual = []
51
+
52
+ rows.each_with_index do |row, i|
53
+ next if i < row_start
54
+ break if i > row_end || row.nil? || row == ''
55
+
56
+ actual[i - row_start] = row[col_number]
57
+ next if row[col_number] == expected[i - row_start]
58
+
59
+ raise MatchError,
60
+ "expected column #{col_number} to be #{expected.inspect}\n
61
+ Entire screen:\n#{self}"
62
+ end
63
+
64
+ return if !actual.nil? && actual.join.eql?(expected)
65
+
66
+ inspection = get_inspection(actual.join)
67
+
68
+ raise MatchError,
69
+ "expected column #{col_number} to contain #{expected} at #{row_start}-#{row_end} and got #{inspection}\nEntire screen:\n#{self}"
70
+ end
40
71
  end
41
72
  end
@@ -34,7 +34,7 @@ module TTYtest
34
34
  end
35
35
  alias assert_line_is_empty assert_row_is_empty
36
36
 
37
- # Asserts the contents of a single row contains the expected string at a specific position
37
+ # Asserts the contents of a row contain the expected string at the specified position
38
38
  # @param [Integer] row_number the row (starting from 0) to test against
39
39
  # @param [Integer] column_start the column position to start comparing expected against
40
40
  # @param [Integer] columns_end the column position to end comparing expected against
@@ -51,8 +51,7 @@ module TTYtest
51
51
  inspection = get_inspection_bounded(actual, column_start, column_end)
52
52
 
53
53
  raise MatchError,
54
- "expected row #{row_number} to contain #{expected[column_start,
55
- column_end]} at #{column_start}-#{column_end} and got #{inspection}\nEntire screen:\n#{self}"
54
+ "expected row #{row_number} to contain #{expected} at #{column_start}-#{column_end} and got #{inspection}\nEntire screen:\n#{self}"
56
55
  end
57
56
  alias assert_line_at assert_row_at
58
57
 
@@ -9,7 +9,7 @@ module TTYtest
9
9
  class Capture
10
10
  include TTYtest::Assertions
11
11
 
12
- attr_reader :cursor_x, :cursor_y, :width, :height
12
+ attr_reader :cursor_x, :cursor_y, :width, :height, :max_wait_time, :use_return_for_newline
13
13
 
14
14
  # Used internally by drivers when called by {Terminal#capture}
15
15
  # @api private
@@ -16,7 +16,8 @@ module TTYtest
16
16
  SHIFT_ENTER = 11.chr # \v
17
17
  FORM_FEED = 12.chr # \f
18
18
  CTRLL = 12.chr
19
- CARRIAGE_RETURN = 13.chr # \r
19
+ CARRIAGE_RETURN = 13.chr # \r, left for backwards compat
20
+ RETURN = 13.chr # \r, same as CARRIAGE_RETURN
20
21
  CTRLU = 21.chr
21
22
  CTRLW = 23.chr
22
23
  ESCAPE = 27.chr # ^[ or /033 or /e
@@ -9,14 +9,15 @@ module TTYtest
9
9
  class Terminal
10
10
  extend Forwardable
11
11
 
12
- attr_accessor :max_wait_time
12
+ attr_accessor :max_wait_time, :use_return_for_newline
13
13
 
14
14
  # @api private
15
15
  # @see TTYtest.new_terminal, use this or other new_* methods instead.
16
16
  # Internal constructor.
17
- def initialize(driver_terminal)
17
+ def initialize(driver_terminal, max_wait_time, use_return_for_newline)
18
+ @max_wait_time = max_wait_time
19
+ @use_return_for_newline = use_return_for_newline
18
20
  @driver_terminal = driver_terminal
19
- @max_wait_time = TTYtest.default_max_wait_time
20
21
  end
21
22
 
22
23
  # @!method send_keys(*keys)
@@ -67,17 +68,21 @@ module TTYtest
67
68
  # @param [Integer] sleep_time the amount of time to sleep after sending the line
68
69
 
69
70
  # @!method send_newline
70
- # Simulate typing enter by sending newline character to the terminal.
71
+ # Simulate typing enter by sending newline (ALT + enter) character to the terminal.
72
+ # Many line readers interpreter newline as return, but in some cases you may have to use send_return.
71
73
 
72
74
  # @!method send_newlines(number_of_times)
73
- # Simulates sending newline the specified number of times.
75
+ # Simulates sending newline (ALT + enter) the specified number of times.
76
+ # Many line readers interpreter newline as return, but in some cases you may have to use send_return.
74
77
  # @param [Integer] number_of_times number of times to send newline
75
78
 
76
- # @!method send_enter
79
+ # @!method send_return
77
80
  # Simulate typing enter by sending newline character to the terminal.
81
+ # Many line readers interpreter newline as return, but in some cases you may have to use send_return.
78
82
 
79
- # @!method send_enters(number_of_times)
83
+ # @!method send_returns(number_of_times)
80
84
  # Simulates sending newline the specified number of times.
85
+ # Many line readers interpreter newline as return, but in some cases you may have to use send_return.
81
86
  # @param [Integer] number of times to send newline
82
87
 
83
88
  # @!method send_delete
@@ -142,6 +147,13 @@ module TTYtest
142
147
  # Simulates typing in the Escape (ESC) key in the terminal the specified number of times.
143
148
  # @param [Integer] number of times to send escape
144
149
 
150
+ # @!method send_tab
151
+ # Simulates typing in the Tab (\t) key in the terminal.
152
+
153
+ # @!method send_tabs(number_of_times)
154
+ # Simulates typing in the Tab (\t) key in the terminal the specified number of times.
155
+ # @param [Integer] number of times to send tab
156
+
145
157
  # @!method capture
146
158
  # Capture represents the current state of the terminal.
147
159
  # @return [Capture] The current state of the terminal when called
@@ -152,11 +164,13 @@ module TTYtest
152
164
  :send_line_exact, :send_lines_exact,
153
165
  :send_newline, :send_newlines,
154
166
  :send_enter, :send_enters,
167
+ :send_return, :send_returns,
155
168
  :send_delete, :send_deletes,
156
169
  :send_backspace, :send_backspaces,
157
170
  :send_left_arrow, :send_left_arrows, :send_right_arrow, :send_right_arrows,
158
171
  :send_down_arrow, :send_down_arrows, :send_up_arrow, :send_up_arrows,
159
172
  :send_keys_exact, :send_home, :send_end, :send_clear, :send_escape, :send_escapes,
173
+ :send_tab, :send_tabs,
160
174
  :capture
161
175
 
162
176
  # @!method print
@@ -31,21 +31,22 @@ module TTYtest
31
31
  @config_file_path = config_file_path
32
32
  end
33
33
 
34
- def new_terminal(cmd, width: 80, height: 24)
34
+ def new_terminal(cmd, width: 80, height: 24, max_wait_time: 2, use_return_for_newline: false)
35
35
  cmd = "#{cmd}\n#{SLEEP_INFINITY}"
36
36
 
37
37
  session_name = "ttytest-#{SecureRandom.uuid}"
38
38
  tmux(*%W[-f #{@config_file_path} new-session -s #{session_name} -d -x #{width} -y #{height} #{cmd}])
39
- session = Session.new(self, session_name)
40
- Terminal.new(session)
39
+ session = Session.new(self, session_name, use_return_for_newline)
40
+ Terminal.new(session, max_wait_time, use_return_for_newline)
41
41
  end
42
42
 
43
43
  def new_default_sh_terminal
44
- new_terminal(%(PS1='$ ' /bin/sh), width: 80, height: 24)
44
+ new_terminal(%(PS1='$ ' /bin/sh), width: 80, height: 24, max_wait_time: 2, use_return_for_newline: false)
45
45
  end
46
46
 
47
- def new_sh_terminal(width: 80, height: 24)
48
- new_terminal(%(PS1='$ ' /bin/sh), width: width, height: height)
47
+ def new_sh_terminal(width: 80, height: 24, max_wait_time: 2, use_return_for_newline: false)
48
+ new_terminal(%(PS1='$ ' /bin/sh), width: width, height: height, max_wait_time: max_wait_time,
49
+ use_return_for_newline: use_return_for_newline)
49
50
  end
50
51
 
51
52
  # @api private
@@ -5,10 +5,11 @@ module TTYtest
5
5
  # represents a tmux session and how to send output to the current tmux session
6
6
  class Session
7
7
  # @api private
8
- def initialize(driver, name)
8
+ def initialize(driver, name, use_return_for_newline)
9
9
  @id = SecureRandom.uuid
10
10
  @driver = driver
11
11
  @name = name
12
+ @use_return_for_newline = use_return_for_newline
12
13
 
13
14
  ObjectSpace.define_finalizer(@id, proc {
14
15
  begin
@@ -58,6 +59,10 @@ module TTYtest
58
59
  # Send line to tmux, no need to worry about newline character
59
60
  def send_line(line)
60
61
  send_keys_one_at_a_time(line)
62
+ if @use_return_for_newline
63
+ send_return unless ['\n', '\r'].include?(line[-1])
64
+ return
65
+ end
61
66
  send_newline unless line[-1] == '\n'
62
67
  end
63
68
 
@@ -73,34 +78,56 @@ module TTYtest
73
78
  end
74
79
  end
75
80
 
81
+ def send_lines_then_sleep(*lines, sleep_time)
82
+ lines.each do |line|
83
+ send_line(line)
84
+ end
85
+ sleep sleep_time
86
+ end
87
+
88
+ def send_line_then_sleep_and_repeat(*lines, sleep_time)
89
+ lines.each do |line|
90
+ send_line_then_sleep(line, sleep_time)
91
+ end
92
+ end
93
+
76
94
  def send_line_exact(line)
77
95
  send_keys_exact(line)
96
+ if @use_return_for_newline
97
+ send_return unless ['\n', '\r'].include?(line[-1])
98
+ return
99
+ end
78
100
  send_newline unless line[-1] == '\n'
79
101
  end
80
102
 
103
+ # Send line then sleep for sleep_time
104
+ def send_line_exact_then_sleep(line, sleep_time)
105
+ send_line_exact(line)
106
+ sleep sleep_time
107
+ end
108
+
81
109
  def send_lines_exact(*lines)
82
110
  lines.each do |line|
83
111
  send_line_exact(line)
84
112
  end
85
113
  end
86
114
 
87
- def send_lines_then_sleep(*lines, sleep_time)
115
+ def send_lines_exact_then_sleep(*lines, sleep_time)
88
116
  lines.each do |line|
89
- send_line(line)
117
+ send_line_exact(line)
90
118
  end
91
119
  sleep sleep_time
92
120
  end
93
121
 
94
- def send_line_then_sleep_and_repeat(*lines, sleep_time)
122
+ def send_line_exact_then_sleep_and_repeat(*lines, sleep_time)
95
123
  lines.each do |line|
96
- send_line_then_sleep(line, sleep_time)
124
+ send_line_exact_then_sleep(line, sleep_time)
97
125
  end
98
126
  end
99
127
 
100
128
  def send_newline
101
129
  driver.tmux(*%W[send-keys -t #{name} -l], %(\n))
102
130
  end
103
- alias send_enter send_newline
104
131
 
105
132
  def send_newlines(number_of_times)
106
133
  while number_of_times.positive?
@@ -108,7 +135,17 @@ module TTYtest
108
135
  number_of_times -= 1
109
136
  end
110
137
  end
111
- alias send_enters send_newlines
138
+
139
+ def send_return
140
+ driver.tmux(*%W[send-keys -t #{name} -l], %(\r))
141
+ end
142
+
143
+ def send_returns(number_of_times)
144
+ while number_of_times.positive?
145
+ send_return
146
+ number_of_times -= 1
147
+ end
148
+ end
112
149
 
113
150
  def send_delete
114
151
  send_keys_exact(%(DC))
@@ -194,6 +231,10 @@ module TTYtest
194
231
 
195
232
  def send_clear
196
233
  send_keys_one_at_a_time(TTYtest::CLEAR)
234
+ if @use_return_for_newline
235
+ send_return
236
+ return
237
+ end
197
238
  send_newline
198
239
  end
199
240
 
@@ -208,6 +249,17 @@ module TTYtest
208
249
  end
209
250
  end
210
251
 
252
+ def send_tab
253
+ send_keys_exact(TTYtest::TAB)
254
+ end
255
+
256
+ def send_tabs(number_of_times)
257
+ while number_of_times.positive?
258
+ send_tab
259
+ number_of_times -= 1
260
+ end
261
+ end
262
+
211
263
  private
212
264
 
213
265
  attr_reader :driver, :name
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTYtest
4
- VERSION = '1.2.0'
4
+ VERSION = '1.4.0'
5
5
  end
data/lib/ttytest.rb CHANGED
@@ -16,30 +16,36 @@ module TTYtest
16
16
  # @param [String] command a valid shell command to run
17
17
  # @param [Integer] width width of the new terminal
18
18
  # @param [Integer] height height of the new terminal
19
+ # @param [Integer] max_wait_time max time to wait for screen to update before an assertion fails
20
+ # @param [bool] use_return_for_newline use return instead of newline for functions like send_line
19
21
  # @return [Terminal] a new terminal running the specified command
20
22
 
21
23
  # @!method new_default_sh_terminal
22
24
  # Create a new terminal using '/bin/sh' with width: 80 and height: 24.
23
- # Useful for Unixes.
25
+ # Useful for applications like shells which may show user or the cwd.
26
+ # @return [Terminal] a new sh terminal
24
27
 
25
28
  # @!method new_sh_terminal(width: 80, height: 24)
26
29
  # Create a new terminal using '/bin/sh' with ability to set width and height.
27
- # Useful for Unixes.
30
+ # Useful for applications like shells which may show user or the cwd.
31
+ # @param [Integer] max_wait_time max time to wait for screen to update before an assertion fails
32
+ # @param [bool] use_return_for_newline use return instead of newline for functions like send_line
33
+ # @return [Terminal] a new sh terminal with specified width and height
34
+
28
35
  def_delegators :driver
29
36
 
30
- def new_terminal(cmd, width: 80, height: 24, max_wait_time: 2)
31
- @max_wait_time = max_wait_time
32
- driver.new_terminal(cmd, width: width, height: height)
37
+ def new_terminal(cmd, width: 80, height: 24, max_wait_time: 2, use_return_for_newline: false)
38
+ driver.new_terminal(cmd, width: width, height: height, max_wait_time: max_wait_time,
39
+ use_return_for_newline: use_return_for_newline)
33
40
  end
34
41
 
35
- def new_default_sh_terminal(max_wait_time: 2)
36
- @max_wait_time = max_wait_time
42
+ def new_default_sh_terminal
37
43
  driver.new_default_sh_terminal
38
44
  end
39
45
 
40
- def new_sh_terminal(width: 80, height: 24, max_wait_time: 2)
41
- @max_wait_time = max_wait_time
42
- driver.new_sh_terminal(width: width, height: height)
46
+ def new_sh_terminal(width: 80, height: 24, max_wait_time: 2, use_return_for_newline: false)
47
+ driver.new_sh_terminal(width: width, height: height, max_wait_time: max_wait_time,
48
+ use_return_for_newline: use_return_for_newline)
43
49
  end
44
50
  end
45
51
 
data/notes.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  to push new version to github
2
- git tag v1.2.0
2
+ git tag v1.4.0
3
3
  git push origin --tags
4
4
 
5
5
  to push new version to rubygems.org
6
6
  gem build ttytest2.gemspec
7
- gem push ttytest2-1.2.0.gem
7
+ gem push ttytest2-1.4.0.gem
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ttytest2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Eski
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-27 00:00:00.000000000 Z
11
+ date: 2025-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler