capydash 0.1.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.
@@ -0,0 +1,139 @@
1
+ require 'json'
2
+ require 'fileutils'
3
+
4
+ module CapyDash
5
+ class Persistence
6
+ class << self
7
+ def save_test_run(test_run_data)
8
+ ensure_data_directory
9
+ file_path = test_run_file_path(test_run_data[:id] || generate_run_id)
10
+
11
+ begin
12
+ File.write(file_path, JSON.pretty_generate(test_run_data))
13
+ Logger.info("Test run saved", {
14
+ run_id: test_run_data[:id],
15
+ file_path: file_path,
16
+ test_count: test_run_data[:tests]&.length || 0
17
+ })
18
+ file_path
19
+ rescue => e
20
+ ErrorHandler.handle_error(e, {
21
+ error_type: 'persistence',
22
+ operation: 'save_test_run',
23
+ run_id: test_run_data[:id]
24
+ })
25
+ nil
26
+ end
27
+ end
28
+
29
+ def load_test_run(run_id)
30
+ file_path = test_run_file_path(run_id)
31
+ return nil unless File.exist?(file_path)
32
+
33
+ begin
34
+ JSON.parse(File.read(file_path), symbolize_names: true)
35
+ rescue => e
36
+ ErrorHandler.handle_error(e, {
37
+ error_type: 'persistence',
38
+ operation: 'load_test_run',
39
+ run_id: run_id
40
+ })
41
+ nil
42
+ end
43
+ end
44
+
45
+ def list_test_runs(limit = 50)
46
+ ensure_data_directory
47
+ data_dir = data_directory
48
+
49
+ begin
50
+ Dir.glob(File.join(data_dir, "test_run_*.json"))
51
+ .sort_by { |f| File.mtime(f) }
52
+ .reverse
53
+ .first(limit)
54
+ .map do |file_path|
55
+ run_id = File.basename(file_path, '.json').gsub('test_run_', '')
56
+ {
57
+ id: run_id,
58
+ file_path: file_path,
59
+ created_at: File.mtime(file_path),
60
+ size: File.size(file_path)
61
+ }
62
+ end
63
+ rescue => e
64
+ ErrorHandler.handle_error(e, {
65
+ error_type: 'persistence',
66
+ operation: 'list_test_runs'
67
+ })
68
+ []
69
+ end
70
+ end
71
+
72
+ def delete_test_run(run_id)
73
+ file_path = test_run_file_path(run_id)
74
+ return false unless File.exist?(file_path)
75
+
76
+ begin
77
+ File.delete(file_path)
78
+ Logger.info("Test run deleted", { run_id: run_id })
79
+ true
80
+ rescue => e
81
+ ErrorHandler.handle_error(e, {
82
+ error_type: 'persistence',
83
+ operation: 'delete_test_run',
84
+ run_id: run_id
85
+ })
86
+ false
87
+ end
88
+ end
89
+
90
+ def cleanup_old_runs(days_to_keep = 30)
91
+ ensure_data_directory
92
+ cutoff_time = Time.now - (days_to_keep * 24 * 60 * 60)
93
+ deleted_count = 0
94
+
95
+ begin
96
+ Dir.glob(File.join(data_directory, "test_run_*.json")).each do |file_path|
97
+ if File.mtime(file_path) < cutoff_time
98
+ run_id = File.basename(file_path, '.json').gsub('test_run_', '')
99
+ if delete_test_run(run_id)
100
+ deleted_count += 1
101
+ end
102
+ end
103
+ end
104
+
105
+ Logger.info("Cleanup completed", {
106
+ deleted_runs: deleted_count,
107
+ days_kept: days_to_keep
108
+ })
109
+
110
+ deleted_count
111
+ rescue => e
112
+ ErrorHandler.handle_error(e, {
113
+ error_type: 'persistence',
114
+ operation: 'cleanup_old_runs'
115
+ })
116
+ 0
117
+ end
118
+ end
119
+
120
+ private
121
+
122
+ def data_directory
123
+ @data_directory ||= File.join(Dir.pwd, "tmp", "capydash_data")
124
+ end
125
+
126
+ def ensure_data_directory
127
+ FileUtils.mkdir_p(data_directory) unless Dir.exist?(data_directory)
128
+ end
129
+
130
+ def test_run_file_path(run_id)
131
+ File.join(data_directory, "test_run_#{run_id}.json")
132
+ end
133
+
134
+ def generate_run_id
135
+ "#{Time.now.to_i}_#{SecureRandom.hex(4)}"
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,3 @@
1
+ module Capydash
2
+ VERSION = "0.1.0"
3
+ end
data/lib/capydash.rb ADDED
@@ -0,0 +1,54 @@
1
+ require 'ostruct'
2
+ require "capydash/engine"
3
+ require "capydash/instrumentation"
4
+ require "capydash/event_emitter"
5
+ require "capydash/dashboard_server"
6
+ require "capydash/configuration"
7
+ require "capydash/logger"
8
+ require "capydash/error_handler"
9
+ require "capydash/persistence"
10
+ require "capydash/auth"
11
+
12
+ module CapyDash
13
+ class << self
14
+ attr_accessor :configuration, :current_test, :config
15
+
16
+ def configure
17
+ self.configuration ||= OpenStruct.new
18
+ yield(configuration)
19
+ end
20
+
21
+ def config
22
+ @config ||= Configuration.load_from_file
23
+ end
24
+
25
+ def config=(new_config)
26
+ @config = new_config
27
+ end
28
+
29
+ # Convenience methods for common operations
30
+ def log_info(message, context = {})
31
+ Logger.info(message, context)
32
+ end
33
+
34
+ def log_error(message, context = {})
35
+ Logger.error(message, context)
36
+ end
37
+
38
+ def handle_error(error, context = {})
39
+ ErrorHandler.handle_error(error, context)
40
+ end
41
+
42
+ def save_test_run(data)
43
+ Persistence.save_test_run(data)
44
+ end
45
+
46
+ def load_test_run(run_id)
47
+ Persistence.load_test_run(run_id)
48
+ end
49
+
50
+ def list_test_runs(limit = 50)
51
+ Persistence.list_test_runs(limit)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,11 @@
1
+ namespace :capydash do
2
+ desc "Start CapyDash WebSocket server"
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
7
+
8
+ trap("INT") { puts "\n[CapyDash] Shutting down"; exit }
9
+ sleep
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capydash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Damon Clark
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: capybara
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '3.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '3.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: faye-websocket
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: eventmachine
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: em-websocket
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rspec
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: rails
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '7.0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '7.0'
96
+ description: CapyDash instruments Capybara tests and streams test steps, screenshots,
97
+ and DOM snapshots to a live dashboard.
98
+ email:
99
+ - dclark312@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - README.md
105
+ - capydash.gemspec
106
+ - lib/capydash.rb
107
+ - lib/capydash/auth.rb
108
+ - lib/capydash/configuration.rb
109
+ - lib/capydash/dashboard_server.rb
110
+ - lib/capydash/engine.rb
111
+ - lib/capydash/error_handler.rb
112
+ - lib/capydash/event_emitter.rb
113
+ - lib/capydash/forwarder.rb
114
+ - lib/capydash/instrumentation.rb
115
+ - lib/capydash/logger.rb
116
+ - lib/capydash/persistence.rb
117
+ - lib/capydash/version.rb
118
+ - lib/tasks/capydash.rake
119
+ homepage: https://github.com/damonclark/capydash
120
+ licenses:
121
+ - MIT
122
+ metadata:
123
+ allowed_push_host: https://rubygems.org
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubygems_version: 3.6.7
139
+ specification_version: 4
140
+ summary: Real-time Capybara test dashboard
141
+ test_files: []