Module: TUITD::Minitest::Assertions
- Defined in:
- lib/tui_td/minitest/assertions.rb
Overview
Assertions for TUI testing with Minitest.
Include this module in your Minitest test class:
require "tui_td/minitest/assertions"
class MyTUITest < Minitest::Test
include TUITD::Minitest::Assertions
def test_login_screen
driver = TUITD::Driver.new("my_tui", rows: 24, cols: 80)
driver.start
assert_text(driver, "Welcome")
(driver, "OK")
refute_text(driver, "Error")
ensure
driver&.close
end
end
Auto-wait: When given a Driver, assertions wait up to 3 seconds. When given a State, assertions check immediately.
Constant Summary collapse
- AUTO_WAIT_TIMEOUT =
3
Instance Method Summary collapse
- #assert_bg(actual, expected, row:, col:) ⇒ Object
-
#assert_button(actual, expected, min_confidence: nil) ⇒ Object
— Selector-based —.
- #assert_checkbox(actual, expected, checked: nil, unchecked: nil, min_confidence: nil) ⇒ Object
- #assert_dialog(actual, min_confidence: nil) ⇒ Object
- #assert_exit_status(actual, expected) ⇒ Object
- #assert_fg(actual, expected, row:, col:) ⇒ Object
- #assert_input(actual, expected = nil, min_confidence: nil) ⇒ Object
- #assert_label(actual, expected = nil, min_confidence: nil) ⇒ Object
- #assert_menu(actual, expected = nil, min_confidence: nil) ⇒ Object
- #assert_progress_bar(actual, expected = nil, min_confidence: nil) ⇒ Object
-
#assert_record_start(actual, path, framerate: 30, codec: "libx264", quality: "high") ⇒ Object
Start recording the TUI session as a video (requires ffmpeg).
-
#assert_record_stop(actual) ⇒ Object
Stop video recording and finalize the video file.
-
#assert_recording(actual) ⇒ Object
Verify that recording is currently active.
- #assert_regex(actual, pattern) ⇒ Object
- #assert_role(actual, role, text: nil, checked: nil, disabled: nil, min_confidence: nil) ⇒ Object
-
#assert_snapshot(actual, name, type: :text, wait: false, region: nil, ignore_rows: nil) ⇒ Object
— Snapshot —.
- #assert_statusbar(actual, expected = nil, min_confidence: nil) ⇒ Object
- #assert_style(actual, row:, col:, **expected_styles) ⇒ Object
- #assert_tab(actual, expected = nil, min_confidence: nil) ⇒ Object
-
#assert_text(actual, expected) ⇒ Object
— Text / Regex / Color / Style —.
- #refute_button(actual, expected) ⇒ Object
- #refute_dialog(actual) ⇒ Object
-
#refute_recording(actual) ⇒ Object
Verify that recording is NOT active.
- #refute_regex(actual, pattern) ⇒ Object
- #refute_text(actual, expected) ⇒ Object
Instance Method Details
#assert_bg(actual, expected, row:, col:) ⇒ Object
90 91 92 93 94 |
# File 'lib/tui_td/minitest/assertions.rb', line 90 def assert_bg(actual, expected, row:, col:) result = auto_wait(actual) { |s| s.background_at(row, col) == expected } actual_bg = state_from(actual).background_at(row, col) assert(result, "Expected BG at [#{row},#{col}] to be #{expected.inspect}, but was #{actual_bg.inspect}") end |
#assert_button(actual, expected, min_confidence: nil) ⇒ Object
— Selector-based —
113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/tui_td/minitest/assertions.rb', line 113 def (actual, expected, min_confidence: nil) result = auto_wait(actual) do |s| el = TUITD::Selector.new(s).(text: expected) if min_confidence && el el.confidence && el.confidence >= min_confidence else el end end msg = "Expected terminal to have a button #{expected.inspect}" msg += " (min_confidence: #{min_confidence})" if min_confidence assert(result, msg) end |
#assert_checkbox(actual, expected, checked: nil, unchecked: nil, min_confidence: nil) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/tui_td/minitest/assertions.rb', line 147 def assert_checkbox(actual, expected, checked: nil, unchecked: nil, min_confidence: nil) checked = false if unchecked result = auto_wait(actual) do |s| filters = { text: expected } filters[:checked] = checked unless checked.nil? el = TUITD::Selector.new(s).checkbox(**filters) if min_confidence && el el.confidence && el.confidence >= min_confidence else el end end msg = "Expected terminal to have checkbox #{expected.inspect}" msg += " (checked)" if checked == true msg += " (unchecked)" if checked == false msg += " (min_confidence: #{min_confidence})" if min_confidence assert(result, msg) end |
#assert_dialog(actual, min_confidence: nil) ⇒ Object
132 133 134 135 136 137 138 139 140 |
# File 'lib/tui_td/minitest/assertions.rb', line 132 def assert_dialog(actual, min_confidence: nil) result = auto_wait(actual) do |s| elements = TUITD::Selector.new(s).dialogs min_confidence ? elements.any? { |e| e.confidence && e.confidence >= min_confidence } : elements.any? end msg = "Expected terminal to have a dialog" msg += " (min_confidence: #{min_confidence})" if min_confidence assert(result, msg) end |
#assert_exit_status(actual, expected) ⇒ Object
106 107 108 109 |
# File 'lib/tui_td/minitest/assertions.rb', line 106 def assert_exit_status(actual, expected) status = actual.exitstatus assert(status == expected, "Expected exit status #{expected}, but was #{status}") end |
#assert_fg(actual, expected, row:, col:) ⇒ Object
84 85 86 87 88 |
# File 'lib/tui_td/minitest/assertions.rb', line 84 def assert_fg(actual, expected, row:, col:) result = auto_wait(actual) { |s| s.foreground_at(row, col) == expected } actual_fg = state_from(actual).foreground_at(row, col) assert(result, "Expected FG at [#{row},#{col}] to be #{expected.inspect}, but was #{actual_fg.inspect}") end |
#assert_input(actual, expected = nil, min_confidence: nil) ⇒ Object
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/tui_td/minitest/assertions.rb', line 185 def assert_input(actual, expected = nil, min_confidence: nil) result = auto_wait(actual) do |s| sel = TUITD::Selector.new(s) if expected el = sel.input(text: expected) min_confidence ? (el&.confidence && el.confidence >= min_confidence) : el else elements = sel.inputs min_confidence ? elements.any? { |e| e.confidence && e.confidence >= min_confidence } : elements.any? end end msg = "Expected terminal to have an input field" msg += " #{expected.inspect}" if expected msg += " (min_confidence: #{min_confidence})" if min_confidence assert(result, msg) end |
#assert_label(actual, expected = nil, min_confidence: nil) ⇒ Object
202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/tui_td/minitest/assertions.rb', line 202 def assert_label(actual, expected = nil, min_confidence: nil) result = auto_wait(actual) do |s| sel = TUITD::Selector.new(s) elements = expected ? [sel.label(text: expected)].compact : sel.labels min_confidence ? elements.any? { |e| e.confidence && e.confidence >= min_confidence } : elements.any? end msg = "Expected terminal to have a label" msg += " #{expected.inspect}" if expected msg += " (min_confidence: #{min_confidence})" if min_confidence assert(result, msg) end |
#assert_menu(actual, expected = nil, min_confidence: nil) ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/tui_td/minitest/assertions.rb', line 214 def (actual, expected = nil, min_confidence: nil) result = auto_wait(actual) do |s| sel = TUITD::Selector.new(s) elements = expected ? [sel.(text: expected)].compact : sel. min_confidence ? elements.any? { |e| e.confidence && e.confidence >= min_confidence } : elements.any? end msg = "Expected terminal to have a menu" msg += " #{expected.inspect}" if expected msg += " (min_confidence: #{min_confidence})" if min_confidence assert(result, msg) end |
#assert_progress_bar(actual, expected = nil, min_confidence: nil) ⇒ Object
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/tui_td/minitest/assertions.rb', line 250 def (actual, expected = nil, min_confidence: nil) result = auto_wait(actual) do |s| sel = TUITD::Selector.new(s) if expected el = sel.(text: expected) min_confidence ? (el&.confidence && el.confidence >= min_confidence) : el else elements = sel. min_confidence ? elements.any? { |e| e.confidence && e.confidence >= min_confidence } : elements.any? end end msg = "Expected terminal to have a progress bar" msg += " #{expected.inspect}" if expected msg += " (min_confidence: #{min_confidence})" if min_confidence assert(result, msg) end |
#assert_record_start(actual, path, framerate: 30, codec: "libx264", quality: "high") ⇒ Object
Start recording the TUI session as a video (requires ffmpeg). actual must be a Driver.
271 272 273 274 275 276 277 278 |
# File 'lib/tui_td/minitest/assertions.rb', line 271 def assert_record_start(actual, path, framerate: 30, codec: "libx264", quality: "high") unless actual.respond_to?(:start_recording) raise ArgumentError, "assert_record_start requires a Driver, got #{actual.class}" end result = actual.start_recording(path, framerate: framerate, codec: codec, quality: quality) assert(result, "Recording failed to start") end |
#assert_record_stop(actual) ⇒ Object
Stop video recording and finalize the video file. actual must be a Driver.
282 283 284 285 286 287 288 289 |
# File 'lib/tui_td/minitest/assertions.rb', line 282 def assert_record_stop(actual) unless actual.respond_to?(:stop_recording) raise ArgumentError, "assert_record_stop requires a Driver, got #{actual.class}" end path = actual.stop_recording assert(path, "No recording in progress") end |
#assert_recording(actual) ⇒ Object
Verify that recording is currently active.
292 293 294 295 296 297 298 |
# File 'lib/tui_td/minitest/assertions.rb', line 292 def assert_recording(actual) unless actual.respond_to?(:recording?) raise ArgumentError, "assert_recording requires a Driver, got #{actual.class}" end assert(actual.recording?, "Expected recording to be active") end |
#assert_regex(actual, pattern) ⇒ Object
72 73 74 75 76 |
# File 'lib/tui_td/minitest/assertions.rb', line 72 def assert_regex(actual, pattern) regex = pattern.is_a?(Regexp) ? pattern : Regexp.new(pattern.to_s) result = auto_wait(actual) { |s| s.find_text(regex).any? } assert(result, "Expected terminal to match #{pattern.inspect}") end |
#assert_role(actual, role, text: nil, checked: nil, disabled: nil, min_confidence: nil) ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/tui_td/minitest/assertions.rb', line 166 def assert_role(actual, role, text: nil, checked: nil, disabled: nil, min_confidence: nil) result = auto_wait(actual) do |s| filters = {} filters[:text] = text if text filters[:checked] = checked unless checked.nil? filters[:disabled] = disabled unless disabled.nil? elements = TUITD::Selector.new(s).get_by_role(role, **filters) if min_confidence elements.any? { |e| e.confidence && e.confidence >= min_confidence } else elements.any? end end msg = "Expected terminal to have role :#{role}" msg += " with text #{text.inspect}" if text msg += " (min_confidence: #{min_confidence})" if min_confidence assert(result, msg) end |
#assert_snapshot(actual, name, type: :text, wait: false, region: nil, ignore_rows: nil) ⇒ Object
— Snapshot —
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/tui_td/minitest/assertions.rb', line 311 def assert_snapshot(actual, name, type: :text, wait: false, region: nil, ignore_rows: nil) snap = TUITD::Snapshot.new(name.to_s, type: type) state_data = if actual.respond_to?(:state_data) actual.wait_for_stable if wait && actual.respond_to?(:wait_for_stable) actual.state_data elsif actual.respond_to?(:to_h) actual.to_h else actual end if TUITD.configuration.update_snapshots? || !snap.exists? snap.save(state_data) pass else result = snap.compare(state_data, ignore_rows: ignore_rows, region: region) msg = result.passed? ? nil : "Snapshot '#{name}' does not match.\n#{result.}" assert(result.passed?, msg) end end |
#assert_statusbar(actual, expected = nil, min_confidence: nil) ⇒ Object
238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/tui_td/minitest/assertions.rb', line 238 def (actual, expected = nil, min_confidence: nil) result = auto_wait(actual) do |s| sel = TUITD::Selector.new(s) elements = expected ? [sel.(text: expected)].compact : sel. min_confidence ? elements.any? { |e| e.confidence && e.confidence >= min_confidence } : elements.any? end msg = "Expected terminal to have a status bar" msg += " #{expected.inspect}" if expected msg += " (min_confidence: #{min_confidence})" if min_confidence assert(result, msg) end |
#assert_style(actual, row:, col:, **expected_styles) ⇒ Object
96 97 98 99 100 101 102 103 104 |
# File 'lib/tui_td/minitest/assertions.rb', line 96 def assert_style(actual, row:, col:, **expected_styles) result = auto_wait(actual) do |s| style = s.style_at(row, col) expected_styles.all? { |k, v| style[k] == v } end actual_style = state_from(actual).style_at(row, col) assert(result, "Expected style at [#{row},#{col}] to be #{expected_styles.inspect}, but was #{actual_style.inspect}",) end |
#assert_tab(actual, expected = nil, min_confidence: nil) ⇒ Object
226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/tui_td/minitest/assertions.rb', line 226 def assert_tab(actual, expected = nil, min_confidence: nil) result = auto_wait(actual) do |s| sel = TUITD::Selector.new(s) elements = expected ? [sel.tab(text: expected)].compact : sel.tabs min_confidence ? elements.any? { |e| e.confidence && e.confidence >= min_confidence } : elements.any? end msg = "Expected terminal to have a tab" msg += " #{expected.inspect}" if expected msg += " (min_confidence: #{min_confidence})" if min_confidence assert(result, msg) end |
#assert_text(actual, expected) ⇒ Object
— Text / Regex / Color / Style —
62 63 64 65 |
# File 'lib/tui_td/minitest/assertions.rb', line 62 def assert_text(actual, expected) result = auto_wait(actual) { |s| s.find_text(expected).any? } assert(result, "Expected terminal to contain #{expected.inspect}") end |
#refute_button(actual, expected) ⇒ Object
127 128 129 130 |
# File 'lib/tui_td/minitest/assertions.rb', line 127 def (actual, expected) result = auto_wait(actual) { |s| TUITD::Selector.new(s).(text: expected).nil? } assert(result, "Expected terminal NOT to have a button #{expected.inspect}") end |
#refute_dialog(actual) ⇒ Object
142 143 144 145 |
# File 'lib/tui_td/minitest/assertions.rb', line 142 def refute_dialog(actual) result = auto_wait(actual) { |s| TUITD::Selector.new(s).dialogs.empty? } assert(result, "Expected terminal NOT to have a dialog") end |
#refute_recording(actual) ⇒ Object
Verify that recording is NOT active.
301 302 303 304 305 306 307 |
# File 'lib/tui_td/minitest/assertions.rb', line 301 def refute_recording(actual) unless actual.respond_to?(:recording?) raise ArgumentError, "refute_recording requires a Driver, got #{actual.class}" end refute(actual.recording?, "Expected recording NOT to be active") end |
#refute_regex(actual, pattern) ⇒ Object
78 79 80 81 82 |
# File 'lib/tui_td/minitest/assertions.rb', line 78 def refute_regex(actual, pattern) regex = pattern.is_a?(Regexp) ? pattern : Regexp.new(pattern.to_s) result = auto_wait(actual) { |s| s.find_text(regex).empty? } assert(result, "Expected terminal NOT to match #{pattern.inspect}") end |
#refute_text(actual, expected) ⇒ Object
67 68 69 70 |
# File 'lib/tui_td/minitest/assertions.rb', line 67 def refute_text(actual, expected) result = auto_wait(actual) { |s| s.find_text(expected).empty? } assert(result, "Expected terminal NOT to contain #{expected.inspect}") end |