@specsage/cli 0.1.2 → 0.1.5
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.
- package/lib/cli.rb +31 -8
- package/lib/results_uploader.rb +10 -3
- package/lib/runner.rb +9 -1
- package/package.json +4 -1
package/lib/cli.rb
CHANGED
|
@@ -93,21 +93,29 @@ class SpecSageCLI
|
|
|
93
93
|
publisher = ResultsUploader.new(api_key: api_key)
|
|
94
94
|
|
|
95
95
|
begin
|
|
96
|
-
|
|
96
|
+
scenarios_response = publisher.fetch_ci_scenarios(website)
|
|
97
|
+
scenarios = scenarios_response['scenarios']
|
|
97
98
|
rescue ResultsUploader::UploadError => e
|
|
98
|
-
puts "Error: #{e.message}"
|
|
99
|
+
puts "Error fetching scenarios: #{e.message}"
|
|
99
100
|
exit 1
|
|
100
101
|
end
|
|
101
102
|
|
|
102
|
-
server_run_id = response['server_run_id']
|
|
103
|
-
scenarios = response['scenarios']
|
|
104
|
-
|
|
105
|
-
puts "Server run ID: #{server_run_id}"
|
|
106
103
|
puts "Scenarios: #{scenarios.length}"
|
|
107
104
|
scenarios.each { |s| puts " - #{s['name']}" }
|
|
108
105
|
puts ""
|
|
109
106
|
|
|
110
|
-
|
|
107
|
+
begin
|
|
108
|
+
run_response = publisher.create_ci_run(website)
|
|
109
|
+
server_run_id = run_response['server_run_id']
|
|
110
|
+
rescue ResultsUploader::UploadError => e
|
|
111
|
+
puts "Error creating run: #{e.message}"
|
|
112
|
+
exit 1
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
puts "Server run ID: #{server_run_id}"
|
|
116
|
+
puts ""
|
|
117
|
+
|
|
118
|
+
results = []
|
|
111
119
|
|
|
112
120
|
scenarios.each do |scenario|
|
|
113
121
|
# Override base_url with CI_APP_URL
|
|
@@ -122,7 +130,7 @@ class SpecSageCLI
|
|
|
122
130
|
)
|
|
123
131
|
|
|
124
132
|
verdict = runner.run
|
|
125
|
-
|
|
133
|
+
results << { scenario: scenario, verdict: verdict }
|
|
126
134
|
puts "[#{scenario['name']}] Verdict: #{verdict}"
|
|
127
135
|
end
|
|
128
136
|
|
|
@@ -138,6 +146,8 @@ class SpecSageCLI
|
|
|
138
146
|
puts "SpecSage CI Run Complete"
|
|
139
147
|
puts "=" * 50
|
|
140
148
|
|
|
149
|
+
verdicts = results.map { |r| r[:verdict] }
|
|
150
|
+
|
|
141
151
|
# Overall verdict: ERROR > FAIL > PASS
|
|
142
152
|
overall = if verdicts.include?('ERROR')
|
|
143
153
|
'ERROR'
|
|
@@ -150,6 +160,19 @@ class SpecSageCLI
|
|
|
150
160
|
end
|
|
151
161
|
|
|
152
162
|
puts "Overall Verdict: #{overall}"
|
|
163
|
+
|
|
164
|
+
# Print links to failed scenarios
|
|
165
|
+
failed_results = results.select { |r| r[:verdict] != 'PASS' }
|
|
166
|
+
if failed_results.any?
|
|
167
|
+
puts ""
|
|
168
|
+
puts "Failed scenarios:"
|
|
169
|
+
failed_results.each do |result|
|
|
170
|
+
scenario_id = result[:scenario]['id']
|
|
171
|
+
url = "https://app.specsage.com/runs/#{server_run_id}/scenarios/#{scenario_id}"
|
|
172
|
+
puts " - #{result[:scenario]['name']}: #{url}"
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
153
176
|
puts ""
|
|
154
177
|
|
|
155
178
|
case overall
|
package/lib/results_uploader.rb
CHANGED
|
@@ -51,15 +51,22 @@ class ResultsUploader
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
# Fetch CI scenarios - returns scenario definitions tagged "ci" for local execution
|
|
54
|
-
# Returns hash with
|
|
54
|
+
# Returns hash with version and scenarios array
|
|
55
55
|
def fetch_ci_scenarios(website_identifier)
|
|
56
|
-
get("/api/v1/ci/scenarios
|
|
56
|
+
get("/api/v1/ci/scenarios", website: website_identifier)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Create a CI run on the server
|
|
60
|
+
# Returns hash with server_run_id and base_url
|
|
61
|
+
def create_ci_run(website_identifier)
|
|
62
|
+
post("/api/v1/ci/runs", { website: website_identifier })
|
|
57
63
|
end
|
|
58
64
|
|
|
59
65
|
private
|
|
60
66
|
|
|
61
|
-
def get(path)
|
|
67
|
+
def get(path, params = {})
|
|
62
68
|
uri = URI.parse("#{@base_url}#{path}")
|
|
69
|
+
uri.query = URI.encode_www_form(params) unless params.empty?
|
|
63
70
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
64
71
|
http.use_ssl = uri.scheme == 'https'
|
|
65
72
|
http.open_timeout = 10
|
package/lib/runner.rb
CHANGED
|
@@ -60,6 +60,7 @@ class Runner
|
|
|
60
60
|
interactive_elements_by_id = build_elements_by_id(interactive_elements)
|
|
61
61
|
previous_action = nil
|
|
62
62
|
action_result = nil
|
|
63
|
+
final_verdict = 'ERROR' # Default to ERROR if no verdict received
|
|
63
64
|
|
|
64
65
|
loop do
|
|
65
66
|
# Get next action from server
|
|
@@ -94,7 +95,10 @@ class Runner
|
|
|
94
95
|
# Log action with element details
|
|
95
96
|
safe_puts " [Step #{step_result[:step_number]}] #{action['action']}: #{action.reject { |k, _| k == 'action' }.to_json}"
|
|
96
97
|
|
|
97
|
-
|
|
98
|
+
if action['action'] == 'verdict'
|
|
99
|
+
final_verdict = action['status'] || 'ERROR'
|
|
100
|
+
break
|
|
101
|
+
end
|
|
98
102
|
|
|
99
103
|
# Skip browser execution for meta actions
|
|
100
104
|
unless BROWSER_ACTIONS.include?(action['action'])
|
|
@@ -125,6 +129,7 @@ class Runner
|
|
|
125
129
|
if @max_steps && step_number >= @max_steps
|
|
126
130
|
log "Step limit exceeded (#{@max_steps})."
|
|
127
131
|
send_client_verdict_if_needed('ERROR', "Step limit exceeded (#{@max_steps}).")
|
|
132
|
+
final_verdict = 'ERROR'
|
|
128
133
|
break
|
|
129
134
|
end
|
|
130
135
|
|
|
@@ -135,16 +140,19 @@ class Runner
|
|
|
135
140
|
stop_node_process
|
|
136
141
|
upload_video
|
|
137
142
|
cleanup_temp_dir
|
|
143
|
+
final_verdict
|
|
138
144
|
rescue StepClient::StepError => e
|
|
139
145
|
send_client_verdict_if_needed('ERROR', "Server error: #{e.message}")
|
|
140
146
|
stop_node_process
|
|
141
147
|
upload_video
|
|
142
148
|
cleanup_temp_dir
|
|
149
|
+
'ERROR'
|
|
143
150
|
rescue StandardError => e
|
|
144
151
|
send_client_verdict_if_needed('ERROR', e.message)
|
|
145
152
|
stop_node_process
|
|
146
153
|
upload_video
|
|
147
154
|
cleanup_temp_dir
|
|
155
|
+
'ERROR'
|
|
148
156
|
end
|
|
149
157
|
|
|
150
158
|
private
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@specsage/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "SpecSage CLI - AI-powered end-to-end testing automation (Node wrapper for Ruby CLI)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -29,5 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"engines": {
|
|
31
31
|
"node": ">=18.0.0"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"playwright": "^1.57.0"
|
|
32
35
|
}
|
|
33
36
|
}
|