Class: Ace::Test::EndToEndRunner::Organisms::SuiteOrchestrator
- Inherits:
-
Object
- Object
- Ace::Test::EndToEndRunner::Organisms::SuiteOrchestrator
- Defined in:
- lib/ace/test/end_to_end_runner/organisms/suite_orchestrator.rb
Overview
Orchestrates E2E test execution across multiple packages
Discovers all E2E tests across the monorepo and executes them either sequentially or in parallel using subprocess isolation. Supports filtering to affected packages based on git diff.
Instance Attribute Summary collapse
-
#base_dir ⇒ Object
readonly
Returns the value of attribute base_dir.
-
#max_parallel ⇒ Object
readonly
Returns the value of attribute max_parallel.
Instance Method Summary collapse
-
#initialize(max_parallel: 4, base_dir: nil, discoverer: nil, affected_detector: nil, failure_finder: nil, output: $stdout, use_color: nil, progress: false, suite_report_writer: nil, scenario_loader: nil, timestamp_generator: nil) ⇒ SuiteOrchestrator
constructor
A new instance of SuiteOrchestrator.
-
#run(options = {}) ⇒ Hash
Run E2E tests across all packages.
Constructor Details
#initialize(max_parallel: 4, base_dir: nil, discoverer: nil, affected_detector: nil, failure_finder: nil, output: $stdout, use_color: nil, progress: false, suite_report_writer: nil, scenario_loader: nil, timestamp_generator: nil) ⇒ SuiteOrchestrator
Returns a new instance of SuiteOrchestrator.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/ace/test/end_to_end_runner/organisms/suite_orchestrator.rb', line 32 def initialize(max_parallel: 4, base_dir: nil, discoverer: nil, affected_detector: nil, failure_finder: nil, output: $stdout, use_color: nil, progress: false, suite_report_writer: nil, scenario_loader: nil, timestamp_generator: nil) @max_parallel = max_parallel @base_dir = base_dir || Dir.pwd @discoverer = discoverer || Molecules::TestDiscoverer.new @affected_detector = affected_detector || Molecules::AffectedDetector.new @failure_finder = failure_finder || Molecules::FailureFinder.new @output = output @use_color = use_color.nil? ? output.respond_to?(:tty?) && output.tty? : use_color @progress = progress config = Molecules::ConfigLoader.load @suite_report_writer = suite_report_writer || Molecules::SuiteReportWriter.new(config: config) @loader = scenario_loader || Molecules::ScenarioLoader.new @timestamp_generator = || method(:default_timestamp) end |
Instance Attribute Details
#base_dir ⇒ Object (readonly)
Returns the value of attribute base_dir.
19 20 21 |
# File 'lib/ace/test/end_to_end_runner/organisms/suite_orchestrator.rb', line 19 def base_dir @base_dir end |
#max_parallel ⇒ Object (readonly)
Returns the value of attribute max_parallel.
19 20 21 |
# File 'lib/ace/test/end_to_end_runner/organisms/suite_orchestrator.rb', line 19 def max_parallel @max_parallel end |
Instance Method Details
#run(options = {}) ⇒ Hash
Run E2E tests across all packages
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/ace/test/end_to_end_runner/organisms/suite_orchestrator.rb', line 60 def run( = {}) pre_run_worktree = git_status_snapshot packages = @discoverer.list_packages(base_dir: @base_dir) if packages.empty? @output.puts "No packages with E2E tests found" return {total: 0, passed: 0, failed: 0, errors: 0, packages: {}} end # Filter to specific packages if requested if [:packages] requested = [:packages].split(",").map(&:strip) packages &= requested if packages.empty? @output.puts "No matching packages with E2E tests found" return {total: 0, passed: 0, failed: 0, errors: 0, packages: {}} end end # Filter to affected packages if requested if [:affected] affected = @affected_detector.detect(base_dir: @base_dir) packages &= affected if packages.empty? @output.puts "No affected packages with E2E tests" return {total: 0, passed: 0, failed: 0, errors: 0, packages: {}} end @output.puts "Affected packages: #{packages.join(", ")}" end # Collect failures by scenario if --only-failures requested scenario_failures = nil if [:only_failures] scenario_failures = @failure_finder.find_failures_by_scenario( packages: packages, base_dir: @base_dir ) if scenario_failures.empty? @output.puts "No failed test scenarios found in cache" return {total: 0, passed: 0, failed: 0, errors: 0, packages: {}} end # Filter packages to only those with failures packages &= scenario_failures.keys @output.puts "Packages with failed scenarios: #{packages.join(", ")}" packages.each do |pkg| scenario_failures[pkg].each_key do |test_id| @output.puts " #{pkg}/#{test_id}" end end end # Store scenario failures for test discovery filters @scenario_failures = scenario_failures @discovery_filters = { tags: [:tags], exclude_tags: [:exclude_tags] } # Discover tests in each package package_tests = discover_package_tests(packages) total_tests = package_tests.values.flatten.size pkg_count = package_tests.keys.size # Pre-compute column widths for aligned output compute_column_widths(package_tests) # Build display manager test_queue = build_test_queue(package_tests) @display = build_display_manager(test_queue) # Print suite header @display.show_header(total_tests, pkg_count) # Execute tests if [:parallel] run_parallel(package_tests, , pre_run_worktree) else run_sequential(package_tests, , pre_run_worktree) end end |