Class: Ace::Test::EndToEndRunner::Molecules::SuiteProgressDisplayManager

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/test/end_to_end_runner/molecules/suite_progress_display_manager.rb

Overview

Animated ANSI table display manager for suite-level E2E test output (–progress mode). Updates test rows in place using cursor movement escape codes. Modeled on ProgressDisplayManager for visual consistency.

Instance Method Summary collapse

Constructor Details

#initialize(test_queue, output:, use_color:, pkg_width:, name_width:) ⇒ SuiteProgressDisplayManager

Returns a new instance of SuiteProgressDisplayManager.

Parameters:

  • test_queue (Array<Hash>)

    flat list of test_file: items

  • output (IO)

    output stream

  • use_color (Boolean)

    enable ANSI color

  • pkg_width (Integer)

    column width for package names

  • name_width (Integer)

    column width for test names



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/ace/test/end_to_end_runner/molecules/suite_progress_display_manager.rb', line 16

def initialize(test_queue, output:, use_color:, pkg_width:, name_width:)
  @test_queue = test_queue
  @output = output
  @use_color = use_color
  @pkg_width = pkg_width
  @name_width = name_width
  @start_time = Time.now
  @last_refresh = Time.at(0)

  # Build row map: "package:test_file" => line number
  @rows = {}
  @states = {}      # key => :waiting | :running | :completed
  @results = {}     # key => result hash
  @started_at = {}  # key => Time

  @test_queue.each_with_index do |item, index|
    key = row_key(item[:package], item[:test_file])
    @rows[key] = index + 5  # account for header lines (sep + title + sep + blank)
    @states[key] = :waiting
  end
end

Instance Method Details

#refreshObject

Refresh running rows to update elapsed timers + footer Throttled to ~4Hz — the poll loop runs at 10Hz but redraws are expensive



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ace/test/end_to_end_runner/molecules/suite_progress_display_manager.rb', line 90

def refresh
  now = Time.now
  return if now - @last_refresh < REFRESH_INTERVAL

  @last_refresh = now

  @states.each do |key, state|
    next unless state == :running

    item = find_item(key)
    print_row(item[:package], item[:test_file]) if item
  end
  update_footer
end

#show_header(total_tests, pkg_count) ⇒ Object

Clear screen, print header, pre-render all rows as “waiting”, print footer

Parameters:

  • total_tests (Integer)
  • pkg_count (Integer)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/ace/test/end_to_end_runner/molecules/suite_progress_display_manager.rb', line 41

def show_header(total_tests, pkg_count)
  dh = Atoms::DisplayHelpers

  # Clear screen (preserves scrollback)
  @output.print "\033[H\033[J"

  @output.puts dh.double_separator
  @output.puts "  ACE E2E Test Suite - Running #{total_tests} tests across #{pkg_count} packages"
  @output.puts dh.double_separator
  @output.puts

  # Pre-render all rows in waiting state
  @test_queue.each do |item|
    print_row(item[:package], item[:test_file])
  end

  @output.puts
  @output.puts
  # Guard against empty queue: default to current line if no rows
  @footer_line = @rows.values.max + 3 if @rows.values.any?
  update_footer
end

#show_summary(results, duration) ⇒ Object

Move past the table area and print summary

Parameters:

  • results (Hash)

    with :total, :passed, :failed, :errors, :packages

  • duration (Numeric)

    total elapsed seconds



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/ace/test/end_to_end_runner/molecules/suite_progress_display_manager.rb', line 108

def show_summary(results, duration)
  move_to_line((@footer_line || 6) + 1)
  @output.puts

  failed_details = collect_failed_details(results)

  lines = Atoms::DisplayHelpers.format_suite_summary(
    {
      total: results[:total],
      passed: results[:passed],
      failed: results[:failed],
      errors: results[:errors],
      total_cases: results[:total_cases] || 0,
      passed_cases: results[:passed_cases] || 0,
      duration: duration,
      failed_details: failed_details
    },
    use_color: @use_color
  )

  lines.each { |line| @output.puts line }
end

#test_completed(result, package, test_file, elapsed) ⇒ Object

Update row to completed state with result

Parameters:

  • result (Hash)

    with :status, :passed_cases, :total_cases

  • package (String)
  • test_file (String)
  • elapsed (Numeric)

    seconds



80
81
82
83
84
85
86
# File 'lib/ace/test/end_to_end_runner/molecules/suite_progress_display_manager.rb', line 80

def test_completed(result, package, test_file, elapsed)
  key = row_key(package, test_file)
  @states[key] = :completed
  @results[key] = result.merge(elapsed: elapsed)
  print_row(package, test_file)
  update_footer
end

#test_started(package, test_file) ⇒ Object

Update row to “running” state

Parameters:

  • package (String)
  • test_file (String)


67
68
69
70
71
72
73
# File 'lib/ace/test/end_to_end_runner/molecules/suite_progress_display_manager.rb', line 67

def test_started(package, test_file)
  key = row_key(package, test_file)
  @states[key] = :running
  @started_at[key] = Time.now
  print_row(package, test_file)
  update_footer
end