capydash 0.1.1 → 0.1.3

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.
@@ -0,0 +1,92 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>CapyDash - Test Dashboard Report</title>
7
+ <link rel="stylesheet" href="assets/dashboard.css">
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <div class="header">
12
+ <h1>CapyDash Test Report</h1>
13
+ <div class="subtitle">Generated on <%= created_at.strftime('%B %d, %Y at %I:%M %p') %></div>
14
+
15
+ <div class="search-container">
16
+ <div class="search-input-wrapper">
17
+ <input type="text" id="searchInput" placeholder="Search tests, steps, or errors..." class="search-input" autocomplete="off">
18
+ <div id="typeaheadDropdown" class="typeahead-dropdown"></div>
19
+ </div>
20
+ <div id="searchStats" class="search-stats"></div>
21
+ </div>
22
+ </div>
23
+
24
+ <div class="summary">
25
+ <div class="summary-card total">
26
+ <div class="number"><%= total_tests %></div>
27
+ <div class="label">Total Tests</div>
28
+ </div>
29
+ <div class="summary-card passed">
30
+ <div class="number"><%= passed_tests %></div>
31
+ <div class="label">Passed</div>
32
+ </div>
33
+ <div class="summary-card failed">
34
+ <div class="number"><%= failed_tests %></div>
35
+ <div class="label">Failed</div>
36
+ </div>
37
+ </div>
38
+
39
+ <div class="test-results">
40
+ <% processed_tests.each do |test_class| %>
41
+ <div class="test-class">
42
+ <h2><%= test_class[:class_name] %></h2>
43
+
44
+ <% test_class[:methods].each do |method| %>
45
+ <div class="test-method">
46
+ <div class="test-method-header">
47
+ <button class="expand-toggle" onclick="toggleTestMethod('<%= method[:name] %>')">
48
+ <span class="expand-icon">▶</span>
49
+ </button>
50
+ <h3><%= method[:name] %></h3>
51
+ </div>
52
+ <div class="steps collapsed" id="steps-<%= method[:name] %>">
53
+ <% method[:steps].each_with_index do |step, step_index| %>
54
+ <div class="step <%= step[:status] %>">
55
+ <div class="step-header">
56
+ <span class="step-name"><%= step[:name] %></span>
57
+ <span class="step-status"><%= step[:status] %></span>
58
+
59
+ <% if step[:screenshot] %>
60
+ <button class="screenshot-toggle" onclick="toggleScreenshot('<%= method[:name] %>-<%= step_index %>')">
61
+ 📸 Screenshot
62
+ </button>
63
+ <% end %>
64
+ </div>
65
+ <div class="step-detail"><%= step[:detail] %></div>
66
+
67
+ <% if step[:error] %>
68
+ <div class="error-log">
69
+ <h4>Error Details</h4>
70
+ <pre><%= step[:error] %></pre>
71
+ </div>
72
+ <% end %>
73
+
74
+ <% if step[:screenshot] %>
75
+ <div class="screenshot-container" id="screenshot-<%= method[:name] %>-<%= step_index %>" style="display: none;">
76
+ <div class="screenshot">
77
+ <img src="screenshots/<%= step[:screenshot] %>" alt="Screenshot">
78
+ </div>
79
+ </div>
80
+ <% end %>
81
+ </div>
82
+ <% end %>
83
+ </div>
84
+ </div>
85
+ <% end %>
86
+ </div>
87
+ <% end %>
88
+ </div>
89
+ </div>
90
+ <script src="assets/dashboard.js"></script>
91
+ </body>
92
+ </html>
@@ -0,0 +1,128 @@
1
+ require 'json'
2
+ require 'time'
3
+ require 'securerandom'
4
+
5
+ module CapyDash
6
+ class TestDataAggregator
7
+ class << self
8
+ def start_test_run
9
+ @current_run = {
10
+ id: generate_run_id,
11
+ created_at: Time.now.iso8601,
12
+ total_tests: 0,
13
+ passed_tests: 0,
14
+ failed_tests: 0,
15
+ tests: []
16
+ }
17
+ @current_test = nil
18
+ @test_steps = []
19
+ end
20
+
21
+ def finish_test_run
22
+ return unless @current_run
23
+
24
+ # Save the test run data
25
+ CapyDash.save_test_run(@current_run)
26
+
27
+ # Clear current state
28
+ @current_run = nil
29
+ @current_test = nil
30
+ @test_steps = nil
31
+ end
32
+
33
+ def handle_event(event)
34
+ return unless @current_run
35
+
36
+ case event[:step_name]
37
+ when 'test_start'
38
+ start_new_test(event)
39
+ when 'test_finish'
40
+ finish_current_test(event)
41
+ when 'test_result'
42
+ # This indicates the test is finished
43
+ finish_current_test(event)
44
+ else
45
+ # This is a test step (visit, click_button, fill_in, etc.)
46
+ # If we don't have a current test, start one
47
+ start_new_test(event) unless @current_test
48
+ add_test_step(event)
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def start_new_test(event)
55
+ # Extract test name from the current test context
56
+ test_name = event[:test_name] || CapyDash.current_test || "unknown_test"
57
+
58
+ @current_test = {
59
+ test_name: test_name,
60
+ steps: []
61
+ }
62
+ @test_steps = []
63
+
64
+ # Add the test_start step
65
+ add_test_step(event)
66
+ end
67
+
68
+ def finish_current_test(event)
69
+ return unless @current_test
70
+
71
+ # Add the test_finish step
72
+ add_test_step(event)
73
+
74
+ # Determine test status
75
+ test_status = determine_test_status(@test_steps)
76
+
77
+ # Update counters
78
+ @current_run[:total_tests] += 1
79
+ if test_status == 'passed'
80
+ @current_run[:passed_tests] += 1
81
+ elsif test_status == 'failed'
82
+ @current_run[:failed_tests] += 1
83
+ end
84
+
85
+ # Add test to current run
86
+ @current_run[:tests] << @current_test
87
+
88
+ # Clear current test
89
+ @current_test = nil
90
+ @test_steps = nil
91
+ end
92
+
93
+ def add_test_step(event)
94
+ return unless @current_test
95
+
96
+ step = {
97
+ step_name: event[:step_name],
98
+ detail: event[:detail],
99
+ status: event[:status],
100
+ test_name: event[:test_name] || CapyDash.current_test || @current_test[:test_name]
101
+ }
102
+
103
+ # Add screenshot if present
104
+ if event[:screenshot]
105
+ step[:screenshot] = event[:screenshot]
106
+ end
107
+
108
+ # Add error if present
109
+ if event[:error]
110
+ step[:error] = event[:error]
111
+ end
112
+
113
+ @current_test[:steps] << step
114
+ @test_steps << step
115
+ end
116
+
117
+ def determine_test_status(steps)
118
+ return 'failed' if steps.any? { |step| step[:status] == 'failed' }
119
+ return 'passed' if steps.any? { |step| step[:status] == 'passed' }
120
+ 'running'
121
+ end
122
+
123
+ def generate_run_id
124
+ "#{Time.now.to_i}_#{SecureRandom.hex(4)}"
125
+ end
126
+ end
127
+ end
128
+ end
@@ -4,7 +4,6 @@ module CapyDash
4
4
  class TestDataCollector
5
5
  class << self
6
6
  def start_test_run
7
- CapyDash::Logger.info("Starting test run data collection")
8
7
  @test_run_started = true
9
8
  @test_count = 0
10
9
  @passed_count = 0
@@ -14,12 +13,6 @@ module CapyDash
14
13
  def finish_test_run
15
14
  return unless @test_run_started
16
15
 
17
- CapyDash::Logger.info("Finishing test run data collection", {
18
- total_tests: @test_count,
19
- passed: @passed_count,
20
- failed: @failed_count
21
- })
22
-
23
16
  @test_run_started = false
24
17
  end
25
18
 
@@ -27,11 +20,6 @@ module CapyDash
27
20
  return unless @test_run_started
28
21
 
29
22
  @test_count += 1
30
- CapyDash::Logger.info("Starting test", {
31
- test_name: test_name,
32
- test_class: test_class,
33
- test_method: test_method
34
- })
35
23
 
36
24
  # Emit test start event
37
25
  CapyDash::EventEmitter.broadcast(
@@ -51,12 +39,6 @@ module CapyDash
51
39
  @failed_count += 1
52
40
  end
53
41
 
54
- CapyDash::Logger.info("Finishing test", {
55
- test_name: test_name,
56
- status: status,
57
- error_message: error_message
58
- })
59
-
60
42
  # Emit test finish event
61
43
  event_data = {
62
44
  step_name: "test_finish",
@@ -1,3 +1,3 @@
1
1
  module Capydash
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.3"
3
3
  end
data/lib/capydash.rb CHANGED
@@ -9,6 +9,8 @@ require "capydash/error_handler"
9
9
  require "capydash/persistence"
10
10
  require "capydash/auth"
11
11
  require "capydash/test_data_collector"
12
+ require "capydash/test_data_aggregator"
13
+ require "capydash/report_generator"
12
14
 
13
15
  module CapyDash
14
16
  class << self
@@ -1,11 +1,67 @@
1
1
  namespace :capydash do
2
- desc "Start CapyDash WebSocket server"
2
+ desc "Start local server to view static HTML report"
3
3
  task server: :environment do
4
- port = CapyDash.configuration&.port || 4000
5
- puts "[CapyDash] Starting WebSocket server on ws://localhost:#{port}"
6
- CapyDash::DashboardServer.instance(port: port).start
4
+ require 'webrick'
5
+ require 'capydash/report_generator'
7
6
 
8
- trap("INT") { puts "\n[CapyDash] Shutting down"; exit }
9
- sleep
7
+ report_dir = File.join(Dir.pwd, "capydash_report")
8
+
9
+ unless Dir.exist?(report_dir)
10
+ puts "No report directory found. Run 'bundle exec rake capydash:report' first."
11
+ exit 1
12
+ end
13
+
14
+ # Try different ports if 5173 is busy
15
+ port = 5173
16
+ begin
17
+ server = WEBrick::HTTPServer.new(
18
+ Port: port,
19
+ DocumentRoot: report_dir,
20
+ Logger: WEBrick::Log.new(nil, WEBrick::Log::ERROR),
21
+ AccessLog: [],
22
+ BindAddress: '127.0.0.1'
23
+ )
24
+ rescue Errno::EADDRINUSE
25
+ port = 8080
26
+ puts "Port 5173 is busy, trying port #{port}..."
27
+ server = WEBrick::HTTPServer.new(
28
+ Port: port,
29
+ DocumentRoot: report_dir,
30
+ Logger: WEBrick::Log.new(nil, WEBrick::Log::ERROR),
31
+ AccessLog: [],
32
+ BindAddress: '127.0.0.1'
33
+ )
34
+ end
35
+
36
+ puts "Starting static file server on http://localhost:#{port}"
37
+ puts "Report available at: http://localhost:#{port}/index.html"
38
+ puts "Press Ctrl+C to stop the server"
39
+
40
+ trap("INT") {
41
+ puts "\nShutting down server..."
42
+ server.shutdown
43
+ }
44
+
45
+ begin
46
+ server.start
47
+ rescue => e
48
+ puts "Error starting server: #{e.message}"
49
+ exit 1
50
+ end
10
51
  end
52
+
53
+ desc "Generate static HTML test report"
54
+ task report: :environment do
55
+ require 'capydash/report_generator'
56
+
57
+ report_path = CapyDash::ReportGenerator.generate_report
58
+
59
+ if report_path
60
+ puts "Report generated: file://#{File.absolute_path(report_path)}"
61
+ else
62
+ puts "No test data found. Run some tests first to generate a report."
63
+ exit 1
64
+ end
65
+ end
66
+
11
67
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capydash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damon Clark
@@ -114,6 +114,9 @@ files:
114
114
  - lib/capydash/instrumentation.rb
115
115
  - lib/capydash/logger.rb
116
116
  - lib/capydash/persistence.rb
117
+ - lib/capydash/report_generator.rb
118
+ - lib/capydash/templates/report.html.erb
119
+ - lib/capydash/test_data_aggregator.rb
117
120
  - lib/capydash/test_data_collector.rb
118
121
  - lib/capydash/version.rb
119
122
  - lib/tasks/capydash.rake