ruby_raider 3.0.0 → 3.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.
- checksums.yaml +4 -4
- data/.github/workflows/e2e_tests.yml +0 -17
- data/.github/workflows/system_tests.yml +0 -22
- data/README.md +8 -62
- data/lib/commands/scaffolding_commands.rb +22 -188
- data/lib/commands/utility_commands.rb +10 -44
- data/lib/generators/automation/templates/login.tt +1 -9
- data/lib/generators/automation/templates/page.tt +1 -7
- data/lib/generators/automation/templates/partials/initialize_selector.tt +1 -3
- data/lib/generators/automation/templates/partials/visit_method.tt +2 -6
- data/lib/generators/common_generator.rb +0 -6
- data/lib/generators/cucumber/cucumber_generator.rb +0 -24
- data/lib/generators/cucumber/templates/accessibility_steps.tt +2 -6
- data/lib/generators/cucumber/templates/cucumber.tt +0 -7
- data/lib/generators/cucumber/templates/env.tt +1 -3
- data/lib/generators/cucumber/templates/partials/appium_env.tt +1 -6
- data/lib/generators/cucumber/templates/partials/selenium_env.tt +0 -5
- data/lib/generators/cucumber/templates/partials/watir_env.tt +0 -5
- data/lib/generators/cucumber/templates/partials/web_steps.tt +4 -4
- data/lib/generators/cucumber/templates/world.tt +1 -3
- data/lib/generators/generator.rb +2 -46
- data/lib/generators/helper_generator.rb +4 -42
- data/lib/generators/infrastructure/templates/github.tt +2 -2
- data/lib/generators/infrastructure/templates/github_appium.tt +2 -6
- data/lib/generators/invoke_generators.rb +4 -25
- data/lib/generators/menu_generator.rb +10 -100
- data/lib/generators/rspec/rspec_generator.rb +0 -11
- data/lib/generators/rspec/templates/accessibility_spec.tt +2 -6
- data/lib/generators/rspec/templates/spec.tt +6 -8
- data/lib/generators/templates/common/gemfile.tt +0 -26
- data/lib/generators/templates/common/git_ignore.tt +0 -2
- data/lib/generators/templates/common/partials/mobile_config.tt +0 -4
- data/lib/generators/templates/common/partials/web_config.tt +0 -4
- data/lib/generators/templates/common/rakefile.tt +0 -9
- data/lib/generators/templates/common/read_me.tt +4 -10
- data/lib/generators/templates/helpers/allure_helper.tt +0 -10
- data/lib/generators/templates/helpers/browser_helper.tt +1 -1
- data/lib/generators/templates/helpers/partials/debug_diagnostics.tt +1 -3
- data/lib/generators/templates/helpers/partials/debug_start.tt +1 -3
- data/lib/generators/templates/helpers/partials/quit_driver.tt +1 -3
- data/lib/generators/templates/helpers/partials/screenshot.tt +1 -3
- data/lib/generators/templates/helpers/partials/selenium_driver.tt +1 -1
- data/lib/generators/templates/helpers/spec_helper.tt +2 -39
- data/lib/ruby_raider.rb +2 -50
- data/lib/scaffolding/project_detector.rb +30 -13
- data/lib/scaffolding/scaffolding.rb +0 -109
- data/lib/scaffolding/templates/component.tt +1 -4
- data/lib/scaffolding/templates/page_object.tt +0 -10
- data/lib/scaffolding/templates/spec.tt +2 -6
- data/lib/scaffolding/templates/steps.tt +0 -2
- data/lib/utilities/utilities.rb +26 -24
- data/lib/version +1 -1
- data/sig/commands/scaffolding_commands.rbs +0 -12
- data/sig/commands/utility_commands.rbs +0 -6
- data/sig/generators/cucumber/cucumber_generator.rbs +0 -4
- data/sig/generators/generator.rbs +0 -11
- data/sig/generators/helper_generator.rbs +1 -5
- data/sig/generators/invoke_generators.rbs +1 -2
- data/sig/generators/menu_generator.rbs +2 -6
- data/sig/generators/rspec/rspec_generator.rbs +0 -2
- data/sig/ruby_raider.rbs +1 -3
- data/sig/scaffolding/project_detector.rbs +0 -1
- data/sig/scaffolding/scaffolding.rbs +0 -23
- data/sig/utilities/utilities.rbs +0 -4
- data/spec/commands/raider_commands_spec.rb +0 -61
- data/spec/commands/scaffolding_commands_spec.rb +22 -0
- data/spec/integration/commands/browser_update_after_creation_spec.rb +123 -0
- data/spec/integration/commands/scaffolding_commands_spec.rb +0 -20
- data/spec/integration/commands/utility_commands_spec.rb +9 -9
- data/spec/integration/content/ci_content_spec.rb +6 -61
- data/spec/integration/content/common_content_spec.rb +0 -64
- data/spec/integration/content/config_content_spec.rb +1 -51
- data/spec/integration/content/content_helper.rb +2 -2
- data/spec/integration/content/gemfile_content_spec.rb +0 -71
- data/spec/integration/content/helper_content_spec.rb +4 -240
- data/spec/integration/content/page_content_spec.rb +0 -89
- data/spec/integration/content/syntax_validation_spec.rb +2 -2
- data/spec/integration/content/test_content_spec.rb +0 -119
- data/spec/integration/end_to_end_features_spec.rb +13 -411
- data/spec/integration/end_to_end_spec.rb +0 -96
- data/spec/integration/generators/axe_addon_spec.rb +2 -52
- data/spec/integration/generators/common_generator_spec.rb +1 -13
- data/spec/integration/generators/config_features_spec.rb +3 -81
- data/spec/integration/generators/debug_helper_spec.rb +0 -20
- data/spec/integration/generators/github_generator_spec.rb +5 -15
- data/spec/integration/generators/helpers_generator_spec.rb +0 -37
- data/spec/integration/scaffolding_e2e_spec.rb +540 -0
- data/spec/integration/settings_helper.rb +1 -3
- data/spec/integration/spec_helper.rb +6 -11
- data/spec/menus/menu_generator_spec.rb +4 -107
- data/spec/scaffolding/scaffold_project_detector_spec.rb +42 -26
- data/spec/scaffolding/scaffolding_features_spec.rb +0 -183
- data/spec/system/selenium_spec.rb +1 -4
- data/spec/system/support/system_test_helper.rb +0 -1
- data/spec/system/watir_spec.rb +1 -4
- data/spec/utilities/headless_config_spec.rb +82 -0
- data/spec/utilities/utilities_spec.rb +105 -0
- metadata +7 -97
- data/lib/adopter/adopt_menu.rb +0 -146
- data/lib/adopter/converters/base_converter.rb +0 -84
- data/lib/adopter/converters/identity_converter.rb +0 -53
- data/lib/adopter/migration_plan.rb +0 -74
- data/lib/adopter/migrator.rb +0 -96
- data/lib/adopter/plan_builder.rb +0 -275
- data/lib/adopter/project_analyzer.rb +0 -252
- data/lib/adopter/project_detector.rb +0 -157
- data/lib/generators/cucumber/templates/partials/capybara_env.tt +0 -38
- data/lib/generators/cucumber/templates/partials/capybara_world.tt +0 -6
- data/lib/generators/cucumber/templates/performance_feature.tt +0 -5
- data/lib/generators/cucumber/templates/performance_steps.tt +0 -17
- data/lib/generators/cucumber/templates/visual_feature.tt +0 -5
- data/lib/generators/cucumber/templates/visual_steps.tt +0 -19
- data/lib/generators/infrastructure/gitlab_generator.rb +0 -11
- data/lib/generators/infrastructure/templates/gitlab.tt +0 -46
- data/lib/generators/minitest/minitest_generator.rb +0 -35
- data/lib/generators/minitest/templates/accessibility_test.tt +0 -26
- data/lib/generators/minitest/templates/performance_test.tt +0 -18
- data/lib/generators/minitest/templates/test.tt +0 -64
- data/lib/generators/minitest/templates/visual_test.tt +0 -23
- data/lib/generators/rspec/templates/performance_spec.tt +0 -18
- data/lib/generators/rspec/templates/visual_spec.tt +0 -20
- data/lib/generators/templates/helpers/capybara_helper.tt +0 -32
- data/lib/generators/templates/helpers/performance_helper.tt +0 -57
- data/lib/generators/templates/helpers/visual_helper.tt +0 -58
- data/lib/llm/client.rb +0 -79
- data/lib/llm/config.rb +0 -57
- data/lib/llm/prompts.rb +0 -84
- data/lib/llm/provider.rb +0 -27
- data/lib/llm/providers/anthropic_provider.rb +0 -43
- data/lib/llm/providers/ollama_provider.rb +0 -56
- data/lib/llm/providers/openai_provider.rb +0 -42
- data/lib/llm/response_parser.rb +0 -67
- data/lib/plugin/plugin.rb +0 -111
- data/lib/plugin/plugin_exposer.rb +0 -55
- data/lib/scaffolding/crud_generator.rb +0 -94
- data/lib/scaffolding/dry_run_presenter.rb +0 -16
- data/lib/scaffolding/page_introspector.rb +0 -45
- data/lib/scaffolding/scaffold_menu.rb +0 -103
- data/lib/scaffolding/templates/page_from_url.tt +0 -75
- data/lib/scaffolding/templates/spec_from_page.tt +0 -31
- data/lib/scaffolding/templates/spec_from_url.tt +0 -46
- data/lib/scaffolding/url_analyzer.rb +0 -179
- data/sig/adopter/adopt_menu.rbs +0 -25
- data/sig/adopter/converters/base_converter.rbs +0 -23
- data/sig/adopter/converters/identity_converter.rbs +0 -16
- data/sig/adopter/migration_plan.rbs +0 -34
- data/sig/adopter/migrator.rbs +0 -21
- data/sig/adopter/plan_builder.rbs +0 -38
- data/sig/adopter/project_analyzer.rbs +0 -39
- data/sig/adopter/project_detector.rbs +0 -26
- data/sig/generators/infrastructure/gitlab_generator.rbs +0 -4
- data/sig/generators/minitest/minitest_generator.rbs +0 -8
- data/sig/llm/client.rbs +0 -15
- data/sig/llm/config.rbs +0 -20
- data/sig/llm/prompts.rbs +0 -8
- data/sig/llm/provider.rbs +0 -12
- data/sig/llm/providers/anthropic_provider.rbs +0 -16
- data/sig/llm/providers/ollama_provider.rbs +0 -18
- data/sig/llm/providers/openai_provider.rbs +0 -16
- data/sig/llm/response_parser.rbs +0 -13
- data/sig/plugin/plugin.rbs +0 -24
- data/sig/plugin/plugin_exposer.rbs +0 -20
- data/sig/scaffolding/crud_generator.rbs +0 -16
- data/sig/scaffolding/dry_run_presenter.rbs +0 -4
- data/sig/scaffolding/page_introspector.rbs +0 -14
- data/sig/scaffolding/scaffold_menu.rbs +0 -18
- data/sig/scaffolding/url_analyzer.rbs +0 -28
- data/spec/adopter/adopt_menu_spec.rb +0 -176
- data/spec/adopter/converters/identity_converter_spec.rb +0 -145
- data/spec/adopter/migration_plan_spec.rb +0 -113
- data/spec/adopter/migrator_spec.rb +0 -277
- data/spec/adopter/plan_builder_spec.rb +0 -298
- data/spec/adopter/project_analyzer_spec.rb +0 -337
- data/spec/adopter/project_detector_spec.rb +0 -295
- data/spec/generators/generator_spec.rb +0 -23
- data/spec/integration/content/reporter_content_spec.rb +0 -236
- data/spec/integration/content/skip_flags_content_spec.rb +0 -206
- data/spec/integration/generators/gitlab_generator_spec.rb +0 -38
- data/spec/integration/generators/lighthouse_addon_spec.rb +0 -132
- data/spec/integration/generators/minitest_generator_spec.rb +0 -64
- data/spec/integration/generators/reporter_spec.rb +0 -159
- data/spec/integration/generators/skip_flags_spec.rb +0 -134
- data/spec/integration/generators/visual_addon_spec.rb +0 -148
- data/spec/llm/client_spec.rb +0 -79
- data/spec/llm/config_spec.rb +0 -92
- data/spec/llm/prompts_spec.rb +0 -49
- data/spec/llm/response_parser_spec.rb +0 -92
- data/spec/menus/adopter_adopt_menu_spec.rb +0 -97
- data/spec/scaffolding/page_introspector_spec.rb +0 -82
- data/spec/scaffolding/url_analyzer_spec.rb +0 -110
- data/spec/system/adopt_matrix_spec.rb +0 -537
- data/spec/system/adopt_spec.rb +0 -225
- data/spec/system/capybara_spec.rb +0 -42
|
@@ -13,22 +13,10 @@ class Scaffolding < Thor::Group
|
|
|
13
13
|
|
|
14
14
|
attr_writer :uses
|
|
15
15
|
|
|
16
|
-
OVERRIDE_DIR = '.ruby_raider/templates'
|
|
17
|
-
|
|
18
16
|
def self.source_root
|
|
19
17
|
"#{File.dirname(__FILE__)}/templates"
|
|
20
18
|
end
|
|
21
19
|
|
|
22
|
-
# Check for user template override before using default
|
|
23
|
-
def template(source, *args, &block)
|
|
24
|
-
override = File.join(OVERRIDE_DIR, File.basename(source))
|
|
25
|
-
if File.exist?(override)
|
|
26
|
-
super(File.expand_path(override), *args, &block)
|
|
27
|
-
else
|
|
28
|
-
super
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
20
|
# --- Generation methods ---
|
|
33
21
|
|
|
34
22
|
def generate_page
|
|
@@ -60,68 +48,6 @@ class Scaffolding < Thor::Group
|
|
|
60
48
|
default_path('config/config.yml', '.yml'))
|
|
61
49
|
end
|
|
62
50
|
|
|
63
|
-
def generate_spec_from_page(source_file, ai: false) # rubocop:disable Naming/MethodParameterName
|
|
64
|
-
require_relative 'page_introspector'
|
|
65
|
-
@introspected = PageIntrospector.new(source_file)
|
|
66
|
-
enrich_with_ai_scenarios if ai
|
|
67
|
-
template('spec_from_page.tt', "spec/#{normalized_name}_spec.rb")
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def generate_page_from_url(analysis)
|
|
71
|
-
@url_data = analysis
|
|
72
|
-
template('page_from_url.tt', "page_objects/pages/#{normalized_name}.rb")
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def generate_spec_from_url(analysis)
|
|
76
|
-
@url_data = analysis
|
|
77
|
-
template('spec_from_url.tt', "spec/#{normalized_name}_spec.rb")
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# --- Deletion methods ---
|
|
81
|
-
|
|
82
|
-
def delete_page
|
|
83
|
-
remove_file(default_path("page_objects/pages/#{normalized_name}.rb", '_page.rb'))
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def delete_feature
|
|
87
|
-
remove_file(default_path("features/#{normalized_name}.feature", '.feature'))
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def delete_spec
|
|
91
|
-
remove_file(default_path("spec/#{normalized_name}_page_spec.rb", '_spec.rb'))
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def delete_helper
|
|
95
|
-
remove_file(default_path("helpers/#{normalized_name}_helper.rb", '_helper.rb'))
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def delete_steps
|
|
99
|
-
remove_file(default_path("features/step_definitions/#{normalized_name}_steps.rb", '_steps.rb'))
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def delete_component
|
|
103
|
-
remove_file(default_path("page_objects/components/#{normalized_name}.rb", '.rb'))
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def delete_config
|
|
107
|
-
remove_file(default_path('config/config.yml', '.yml'))
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# --- Path planning (for dry-run) ---
|
|
111
|
-
|
|
112
|
-
def self.planned_path(name, type, custom_path = nil)
|
|
113
|
-
n = NameNormalizer.normalize(name)
|
|
114
|
-
case type.to_s
|
|
115
|
-
when 'page' then custom_path ? "#{custom_path}/#{n}_page.rb" : "page_objects/pages/#{n}.rb"
|
|
116
|
-
when 'spec' then custom_path ? "#{custom_path}/#{n}_spec.rb" : "spec/#{n}_page_spec.rb"
|
|
117
|
-
when 'feature' then custom_path ? "#{custom_path}/#{n}.feature" : "features/#{n}.feature"
|
|
118
|
-
when 'steps' then custom_path ? "#{custom_path}/#{n}_steps.rb" : "features/step_definitions/#{n}_steps.rb"
|
|
119
|
-
when 'helper' then custom_path ? "#{custom_path}/#{n}_helper.rb" : "helpers/#{n}_helper.rb"
|
|
120
|
-
when 'component' then custom_path ? "#{custom_path}/#{n}.rb" : "page_objects/components/#{n}.rb"
|
|
121
|
-
when 'model' then "models/data/#{n}.yml"
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
51
|
# --- Template helpers (available in .tt files) ---
|
|
126
52
|
|
|
127
53
|
def class_name
|
|
@@ -164,10 +90,6 @@ class Scaffolding < Thor::Group
|
|
|
164
90
|
automation_type == 'selenium'
|
|
165
91
|
end
|
|
166
92
|
|
|
167
|
-
def capybara?
|
|
168
|
-
automation_type == 'capybara'
|
|
169
|
-
end
|
|
170
|
-
|
|
171
93
|
def watir?
|
|
172
94
|
automation_type == 'watir'
|
|
173
95
|
end
|
|
@@ -176,39 +98,8 @@ class Scaffolding < Thor::Group
|
|
|
176
98
|
Array(@uses).reject(&:empty?)
|
|
177
99
|
end
|
|
178
100
|
|
|
179
|
-
attr_reader :introspected, :url_data
|
|
180
|
-
|
|
181
|
-
def ai_scenarios
|
|
182
|
-
@ai_scenarios || {}
|
|
183
|
-
end
|
|
184
|
-
|
|
185
101
|
def default_path(standard_path, file_type)
|
|
186
102
|
path ? "#{path}/#{normalized_name}#{file_type}" : standard_path
|
|
187
103
|
end
|
|
188
104
|
|
|
189
|
-
private
|
|
190
|
-
|
|
191
|
-
def enrich_with_ai_scenarios
|
|
192
|
-
require_relative '../llm/client'
|
|
193
|
-
require_relative '../llm/prompts'
|
|
194
|
-
require_relative '../llm/response_parser'
|
|
195
|
-
|
|
196
|
-
return unless Llm::Client.available?
|
|
197
|
-
|
|
198
|
-
response = Llm::Client.complete(
|
|
199
|
-
Llm::Prompts.generate_test_scenarios(
|
|
200
|
-
@introspected.class_name,
|
|
201
|
-
@introspected.methods,
|
|
202
|
-
automation_type,
|
|
203
|
-
framework_type
|
|
204
|
-
),
|
|
205
|
-
system_prompt: Llm::Prompts.system_prompt
|
|
206
|
-
)
|
|
207
|
-
scenarios = Llm::ResponseParser.extract_scenarios(response)
|
|
208
|
-
return unless scenarios
|
|
209
|
-
|
|
210
|
-
@ai_scenarios = scenarios.each_with_object({}) do |s, hash|
|
|
211
|
-
hash[s[:method]] = s
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
105
|
end
|
|
@@ -16,10 +16,6 @@ require_relative '<%= dep %>'
|
|
|
16
16
|
<%- end -%>
|
|
17
17
|
|
|
18
18
|
<%= ' ' * module_parts.size %> # Actions
|
|
19
|
-
<%- if capybara? -%>
|
|
20
|
-
|
|
21
|
-
<%= ' ' * module_parts.size %> # Example: fill_in 'field_id', with: value
|
|
22
|
-
<%- else -%>
|
|
23
19
|
|
|
24
20
|
<%= ' ' * module_parts.size %> private
|
|
25
21
|
|
|
@@ -29,7 +25,6 @@ require_relative '<%= dep %>'
|
|
|
29
25
|
<%- elsif watir? -%>
|
|
30
26
|
<%= ' ' * module_parts.size %> # Example: browser.text_field(id: 'element_id')
|
|
31
27
|
<%- end -%>
|
|
32
|
-
<%- end -%>
|
|
33
28
|
<%= ' ' * module_parts.size %>end
|
|
34
29
|
<% module_parts.each_with_index do |_mod, i| -%>
|
|
35
30
|
<%= ' ' * (module_parts.size - i - 1) %>end
|
|
@@ -43,10 +38,6 @@ class <%= page_class_name %> < Page
|
|
|
43
38
|
<%- end -%>
|
|
44
39
|
|
|
45
40
|
# Actions
|
|
46
|
-
<%- if capybara? -%>
|
|
47
|
-
|
|
48
|
-
# Example: fill_in 'field_id', with: value
|
|
49
|
-
<%- else -%>
|
|
50
41
|
|
|
51
42
|
private
|
|
52
43
|
|
|
@@ -56,6 +47,5 @@ class <%= page_class_name %> < Page
|
|
|
56
47
|
<%- elsif watir? -%>
|
|
57
48
|
# Example: browser.text_field(id: 'element_id')
|
|
58
49
|
<%- end -%>
|
|
59
|
-
<%- end -%>
|
|
60
50
|
end
|
|
61
51
|
<% end -%>
|
|
@@ -10,18 +10,14 @@ describe '<%= page_class_name %>' do
|
|
|
10
10
|
let(:page) { <%= page_class_name %>.new(driver) }
|
|
11
11
|
<%- elsif watir? -%>
|
|
12
12
|
let(:page) { <%= page_class_name %>.new(browser) }
|
|
13
|
-
<%- elsif capybara? -%>
|
|
14
|
-
let(:page) { <%= page_class_name %>.new }
|
|
15
13
|
<%- end -%>
|
|
16
14
|
<%- uses_list.each do |dep| -%>
|
|
17
|
-
let(:<%= dep %>) { <%= NameNormalizer.to_page_class(dep) %>.new<%= selenium? ? '(driver)' :
|
|
15
|
+
let(:<%= dep %>) { <%= NameNormalizer.to_page_class(dep) %>.new<%= selenium? ? '(driver)' : '(browser)' %> }
|
|
18
16
|
<%- end -%>
|
|
19
17
|
<%- if project_config['url'] -%>
|
|
20
18
|
|
|
21
19
|
before do
|
|
22
|
-
<%- if
|
|
23
|
-
visit '<%= normalized_name %>'
|
|
24
|
-
<%- elsif selenium? -%>
|
|
20
|
+
<%- if selenium? -%>
|
|
25
21
|
driver.navigate.to "\#{project_config['url']}/<%= normalized_name %>"
|
|
26
22
|
<%- elsif watir? -%>
|
|
27
23
|
browser.goto "\#{project_config['url']}/<%= normalized_name %>"
|
|
@@ -10,8 +10,6 @@ Given('I am on the <%= normalized_name.tr("_", " ") %> page') do
|
|
|
10
10
|
@page = <%= page_class_name %>.new(driver)
|
|
11
11
|
<%- elsif watir? -%>
|
|
12
12
|
@page = <%= page_class_name %>.new(browser)
|
|
13
|
-
<%- elsif capybara? -%>
|
|
14
|
-
visit '<%= normalized_name %>'
|
|
15
13
|
<%- end -%>
|
|
16
14
|
end
|
|
17
15
|
|
data/lib/utilities/utilities.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Utilities
|
|
|
7
7
|
|
|
8
8
|
class << self
|
|
9
9
|
def browser=(browser)
|
|
10
|
-
set('browser', browser)
|
|
10
|
+
set('browser', browser.to_s.delete_prefix(':'))
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def page_path=(path)
|
|
@@ -44,40 +44,36 @@ module Utilities
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def browser_options=(opts)
|
|
47
|
-
|
|
47
|
+
reload_config
|
|
48
|
+
browser_name = @config['browser'] || 'chrome'
|
|
49
|
+
@config['browser_arguments'] ||= {}
|
|
50
|
+
@config['browser_arguments'][browser_name] = Array(opts).flatten
|
|
51
|
+
overwrite_yaml
|
|
48
52
|
end
|
|
49
53
|
|
|
50
54
|
def delete_browser_options
|
|
51
|
-
|
|
55
|
+
reload_config
|
|
56
|
+
browser_name = @config['browser'] || 'chrome'
|
|
57
|
+
@config['browser_arguments']&.delete(browser_name)
|
|
52
58
|
overwrite_yaml
|
|
53
59
|
end
|
|
54
60
|
|
|
55
|
-
def
|
|
56
|
-
set('
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def llm_api_key=(key)
|
|
60
|
-
set('llm_api_key', key)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def llm_model=(model)
|
|
64
|
-
set('llm_model', model)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def llm_url=(url)
|
|
68
|
-
set('llm_url', url)
|
|
61
|
+
def headless=(enabled)
|
|
62
|
+
set('headless', enabled)
|
|
69
63
|
end
|
|
70
64
|
|
|
71
65
|
def debug=(enabled)
|
|
72
|
-
|
|
73
|
-
config['debug']
|
|
66
|
+
reload_config
|
|
67
|
+
@config['debug'] ||= {}
|
|
68
|
+
@config['debug']['enabled'] = enabled
|
|
74
69
|
overwrite_yaml
|
|
75
70
|
end
|
|
76
71
|
|
|
77
72
|
# Set multiple config keys in a single YAML write.
|
|
78
73
|
# Usage: Utilities.batch_update(browser: 'chrome', timeout: 30)
|
|
79
74
|
def batch_update(**settings)
|
|
80
|
-
|
|
75
|
+
reload_config
|
|
76
|
+
settings.each { |key, value| @config[key.to_s] = value }
|
|
81
77
|
overwrite_yaml
|
|
82
78
|
end
|
|
83
79
|
|
|
@@ -93,18 +89,24 @@ module Utilities
|
|
|
93
89
|
|
|
94
90
|
private
|
|
95
91
|
|
|
96
|
-
# Single-key setter:
|
|
92
|
+
# Single-key setter: reloads from disk, updates, and writes back
|
|
97
93
|
def set(key, value)
|
|
98
|
-
|
|
94
|
+
reload_config
|
|
95
|
+
@config[key] = value
|
|
99
96
|
overwrite_yaml
|
|
100
97
|
end
|
|
101
98
|
|
|
102
99
|
def overwrite_yaml
|
|
103
|
-
File.open(@path, 'w') { |file| YAML.dump(config, file) }
|
|
100
|
+
File.open(@path, 'w') { |file| YAML.dump(@config, file) }
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Always reload from disk so external changes (e.g. desktop app) are picked up
|
|
104
|
+
def reload_config
|
|
105
|
+
@config = File.exist?(@path) ? YAML.load_file(@path) : {}
|
|
104
106
|
end
|
|
105
107
|
|
|
106
108
|
def config
|
|
107
|
-
@config
|
|
109
|
+
@config || reload_config
|
|
108
110
|
end
|
|
109
111
|
end
|
|
110
112
|
end
|
data/lib/version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.1.0
|
|
@@ -7,22 +7,10 @@ class ScaffoldingCommands < Thor
|
|
|
7
7
|
def steps: (String name) -> void
|
|
8
8
|
def component: (String name) -> void
|
|
9
9
|
def scaffold: (*String names) -> void
|
|
10
|
-
def destroy: (*String names) -> void
|
|
11
|
-
def from_url: (String url) -> void
|
|
12
10
|
|
|
13
11
|
private
|
|
14
12
|
|
|
15
13
|
def load_config_path: (String type) -> String?
|
|
16
|
-
def delete_scaffolding: (String name, String type) -> void
|
|
17
14
|
def generate_scaffolding: (String name, String type, String? path, ?uses: Array[String]?) -> void
|
|
18
|
-
def dry_run_preview: (String name, String type) -> void
|
|
19
15
|
def generate_default_scaffold: (String name) -> void
|
|
20
|
-
def generate_selected_components: (String name, Array[String] components) -> void
|
|
21
|
-
def generate_crud: (String name) -> void
|
|
22
|
-
def generate_spec_from_page: (String name, String source_file, ?ai: bool) -> void
|
|
23
|
-
def generate_model_data: (String name) -> void
|
|
24
|
-
def model_template: (String name) -> String
|
|
25
|
-
def destroy_scaffold: (String name, ?Array[String]? components) -> void
|
|
26
|
-
def detect_scaffold_types: () -> Array[String]
|
|
27
|
-
def interactive_scaffold: () -> void
|
|
28
16
|
end
|
|
@@ -12,10 +12,4 @@ class UtilityCommands < Thor
|
|
|
12
12
|
def debug: (String toggle) -> void
|
|
13
13
|
def start_appium: () -> void
|
|
14
14
|
def desktop: () -> void
|
|
15
|
-
def llm: (?String? provider) -> void
|
|
16
|
-
|
|
17
|
-
private
|
|
18
|
-
|
|
19
|
-
def configure_llm: (String provider) -> void
|
|
20
|
-
def show_llm_status: () -> void
|
|
21
15
|
end
|
|
@@ -6,11 +6,7 @@ class CucumberGenerator < Generator
|
|
|
6
6
|
def generate_env_file: () -> void
|
|
7
7
|
def generate_world: () -> void
|
|
8
8
|
def generate_cucumber_file: () -> void
|
|
9
|
-
def generate_visual_feature: () -> void
|
|
10
|
-
def generate_visual_steps: () -> void
|
|
11
9
|
def generate_accessibility_feature: () -> void
|
|
12
10
|
def generate_accessibility_steps: () -> void
|
|
13
|
-
def generate_performance_feature: () -> void
|
|
14
|
-
def generate_performance_steps: () -> void
|
|
15
11
|
def template_name: () -> String
|
|
16
12
|
end
|
|
@@ -15,24 +15,13 @@ class Generator < Thor::Group
|
|
|
15
15
|
def ios?: () -> bool
|
|
16
16
|
def android?: () -> bool
|
|
17
17
|
def rspec?: () -> bool
|
|
18
|
-
def minitest?: () -> bool
|
|
19
18
|
def selenium?: () -> bool
|
|
20
|
-
def capybara?: () -> bool
|
|
21
19
|
def watir?: () -> bool
|
|
22
20
|
def web?: () -> bool
|
|
23
21
|
def selenium_based?: () -> bool
|
|
24
22
|
|
|
25
23
|
# Add-on predicates
|
|
26
24
|
def axe_addon?: () -> bool
|
|
27
|
-
def visual_addon?: () -> bool
|
|
28
|
-
def lighthouse_addon?: () -> bool
|
|
29
|
-
|
|
30
|
-
# Skip/reporter predicates
|
|
31
|
-
def skip_allure?: () -> bool
|
|
32
|
-
def skip_video?: () -> bool
|
|
33
|
-
def allure_reporter?: () -> bool
|
|
34
|
-
def junit_reporter?: () -> bool
|
|
35
|
-
def json_reporter?: () -> bool
|
|
36
25
|
|
|
37
26
|
private
|
|
38
27
|
|
|
@@ -5,14 +5,10 @@ class HelpersGenerator < Generator
|
|
|
5
5
|
private
|
|
6
6
|
|
|
7
7
|
def generate_allure_helper: () -> void
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
def generate_browser_helper: () -> void
|
|
10
10
|
def generate_spec_helper: () -> void
|
|
11
11
|
def generate_driver_helper: () -> void
|
|
12
|
-
def generate_capybara_helper: () -> void
|
|
13
12
|
def generate_appium_helper: () -> void
|
|
14
|
-
def generate_test_helper: () -> void
|
|
15
13
|
def generate_debug_helper: () -> void
|
|
16
|
-
def generate_visual_helper: () -> void
|
|
17
|
-
def generate_performance_helper: () -> void
|
|
18
14
|
end
|
|
@@ -3,8 +3,7 @@ module InvokeGenerators
|
|
|
3
3
|
def self?.generate_framework: (?Hash[Symbol, untyped] structure) -> void
|
|
4
4
|
def self?.add_generator: (Array[String] generators, *String gens) -> void
|
|
5
5
|
def self?.invoke_generator: (?Hash[Symbol, untyped] structure) -> void
|
|
6
|
-
def self?.
|
|
7
|
-
def self?.reporter_flags: (String? reporter) -> Array[String]
|
|
6
|
+
def self?.collect_flags: (Hash[Symbol, untyped] structure) -> Array[String]
|
|
8
7
|
def self?.mobile_automation?: (String automation) -> bool
|
|
9
8
|
def self?.to_bool: (String? string) -> bool?
|
|
10
9
|
end
|
|
@@ -16,14 +16,10 @@ class MenuGenerator
|
|
|
16
16
|
def offer_desktop_download: () -> void
|
|
17
17
|
def select_test_framework: (String automation) -> void
|
|
18
18
|
def create_framework_options: (Hash[Symbol, untyped] params) -> untyped
|
|
19
|
-
def
|
|
20
|
-
def select_accessibility: (String framework, String automation_type, ?String? ci_platform, ?String? reporter) -> void
|
|
21
|
-
def select_visual: (String framework, String automation_type, ?String? ci_platform, ?String? reporter, ?bool accessibility) -> void
|
|
22
|
-
def select_performance: (String framework, String automation_type, ?String? ci_platform, ?String? reporter, ?bool accessibility, ?bool visual) -> void
|
|
19
|
+
def select_accessibility: (String framework, String automation_type) -> void
|
|
23
20
|
def mobile_automation?: (String automation_type) -> bool
|
|
24
|
-
def create_framework: (String framework, String automation_type, ?
|
|
21
|
+
def create_framework: (String framework, String automation_type, ?accessibility: bool) -> void
|
|
25
22
|
def yes_no_menu_choices: () -> Hash[Symbol, Proc]
|
|
26
23
|
def select_automation_framework: (untyped menu) -> void
|
|
27
24
|
def automation_options: (untyped menu) -> void
|
|
28
|
-
def select_ci_platform: (String framework, String automation) -> void
|
|
29
25
|
end
|
data/sig/ruby_raider.rbs
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
# Type definitions for main RubyRaider entry point
|
|
2
2
|
module RubyRaider
|
|
3
3
|
class Raider < Thor
|
|
4
|
-
def self.plugin_commands?: () -> bool
|
|
5
4
|
def current_version: () -> String
|
|
6
5
|
|
|
7
6
|
def new: (String project_name) -> void
|
|
8
7
|
def version: () -> void
|
|
9
|
-
def adopt: () -> void
|
|
10
8
|
|
|
11
9
|
private
|
|
12
10
|
|
|
13
|
-
def
|
|
11
|
+
def merge_flags: (Hash[Symbol, untyped] params) -> void
|
|
14
12
|
end
|
|
15
13
|
end
|
|
@@ -8,7 +8,6 @@ module ScaffoldProjectDetector
|
|
|
8
8
|
def self?.detect_framework: (?String? gemfile) -> String
|
|
9
9
|
def self?.read_gemfile: () -> String
|
|
10
10
|
def self?.selenium?: () -> bool
|
|
11
|
-
def self?.capybara?: () -> bool
|
|
12
11
|
def self?.watir?: () -> bool
|
|
13
12
|
def self?.config: () -> Hash[String, untyped]
|
|
14
13
|
end
|
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
class Scaffolding < Thor::Group
|
|
3
3
|
include Thor::Actions
|
|
4
4
|
|
|
5
|
-
OVERRIDE_DIR: String
|
|
6
|
-
|
|
7
5
|
attr_writer uses: Array[String]
|
|
8
6
|
|
|
9
7
|
def self.source_root: () -> String
|
|
10
|
-
def self.planned_path: (String name, String type, ?String? custom_path) -> String?
|
|
11
8
|
|
|
12
9
|
# Generation methods
|
|
13
10
|
def generate_page: () -> void
|
|
@@ -17,18 +14,6 @@ class Scaffolding < Thor::Group
|
|
|
17
14
|
def generate_steps: () -> void
|
|
18
15
|
def generate_component: () -> void
|
|
19
16
|
def generate_config: () -> void
|
|
20
|
-
def generate_spec_from_page: (String source_file, ?ai: bool) -> void
|
|
21
|
-
def generate_page_from_url: (Hash[Symbol, untyped] analysis) -> void
|
|
22
|
-
def generate_spec_from_url: (Hash[Symbol, untyped] analysis) -> void
|
|
23
|
-
|
|
24
|
-
# Deletion methods
|
|
25
|
-
def delete_page: () -> void
|
|
26
|
-
def delete_feature: () -> void
|
|
27
|
-
def delete_spec: () -> void
|
|
28
|
-
def delete_helper: () -> void
|
|
29
|
-
def delete_steps: () -> void
|
|
30
|
-
def delete_component: () -> void
|
|
31
|
-
def delete_config: () -> void
|
|
32
17
|
|
|
33
18
|
# Template helpers
|
|
34
19
|
def class_name: () -> String?
|
|
@@ -41,15 +26,7 @@ class Scaffolding < Thor::Group
|
|
|
41
26
|
def framework_type: () -> String
|
|
42
27
|
def project_config: () -> Hash[String, untyped]
|
|
43
28
|
def selenium?: () -> bool
|
|
44
|
-
def capybara?: () -> bool
|
|
45
29
|
def watir?: () -> bool
|
|
46
30
|
def uses_list: () -> Array[String]
|
|
47
|
-
def introspected: () -> PageIntrospector?
|
|
48
|
-
def url_data: () -> Hash[Symbol, untyped]?
|
|
49
|
-
def ai_scenarios: () -> Hash[Symbol, untyped]
|
|
50
31
|
def default_path: (String standard_path, String file_type) -> String
|
|
51
|
-
|
|
52
|
-
private
|
|
53
|
-
|
|
54
|
-
def enrich_with_ai_scenarios: () -> void
|
|
55
32
|
end
|
data/sig/utilities/utilities.rbs
CHANGED
|
@@ -13,10 +13,6 @@ module Utilities
|
|
|
13
13
|
def self?.platform=: (String platform) -> void
|
|
14
14
|
def self?.browser_options=: (Array[String] opts) -> void
|
|
15
15
|
def self?.delete_browser_options: () -> void
|
|
16
|
-
def self?.llm_provider=: (String provider) -> void
|
|
17
|
-
def self?.llm_api_key=: (String key) -> void
|
|
18
|
-
def self?.llm_model=: (String model) -> void
|
|
19
|
-
def self?.llm_url=: (String url) -> void
|
|
20
16
|
def self?.debug=: (bool enabled) -> void
|
|
21
17
|
def self?.batch_update: (**untyped settings) -> void
|
|
22
18
|
def self?.run: (?String? opts) -> void
|
|
@@ -45,10 +45,6 @@ RSpec.describe RubyRaider::Raider do
|
|
|
45
45
|
expect(described_class.map['v']).to eq('version')
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
it 'maps a to adopt' do
|
|
49
|
-
expect(described_class.map['a']).to eq('adopt')
|
|
50
|
-
end
|
|
51
|
-
|
|
52
48
|
it 'maps g to generate' do
|
|
53
49
|
expect(described_class.map['g']).to eq('generate')
|
|
54
50
|
end
|
|
@@ -56,19 +52,11 @@ RSpec.describe RubyRaider::Raider do
|
|
|
56
52
|
it 'maps u to utility' do
|
|
57
53
|
expect(described_class.map['u']).to eq('utility')
|
|
58
54
|
end
|
|
59
|
-
|
|
60
|
-
it 'maps pm to plugin_manager' do
|
|
61
|
-
expect(described_class.map['pm']).to eq('plugin_manager')
|
|
62
|
-
end
|
|
63
55
|
end
|
|
64
56
|
|
|
65
57
|
describe 'registered subcommands' do
|
|
66
58
|
let(:subcommands) { described_class.subcommands }
|
|
67
59
|
|
|
68
|
-
it 'includes adopt' do
|
|
69
|
-
expect(subcommands).to include('adopt')
|
|
70
|
-
end
|
|
71
|
-
|
|
72
60
|
it 'includes generate' do
|
|
73
61
|
expect(subcommands).to include('generate')
|
|
74
62
|
end
|
|
@@ -76,54 +64,5 @@ RSpec.describe RubyRaider::Raider do
|
|
|
76
64
|
it 'includes utility' do
|
|
77
65
|
expect(subcommands).to include('utility')
|
|
78
66
|
end
|
|
79
|
-
|
|
80
|
-
it 'includes plugin_manager' do
|
|
81
|
-
expect(subcommands).to include('plugin_manager')
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
RSpec.describe AdoptCommands do
|
|
87
|
-
let(:source_dir) { 'tmp_cmd_adopt_source' }
|
|
88
|
-
let(:output_dir) { 'tmp_cmd_adopt_output' }
|
|
89
|
-
|
|
90
|
-
before do
|
|
91
|
-
FileUtils.mkdir_p(source_dir)
|
|
92
|
-
File.write("#{source_dir}/Gemfile", "gem 'rspec'\ngem 'selenium-webdriver'\n")
|
|
93
|
-
FileUtils.mkdir_p("#{source_dir}/spec")
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
after do
|
|
97
|
-
FileUtils.rm_rf(source_dir)
|
|
98
|
-
FileUtils.rm_rf(output_dir)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
describe 'project command with parameters' do
|
|
102
|
-
it 'calls AdoptMenu.adopt with parsed params' do
|
|
103
|
-
result = { plan: double(warnings: [], output_path: output_dir), results: { pages: 0, tests: 0, features: 0, steps: 0, errors: [] } } # rubocop:disable RSpec/VerifiedDoubles
|
|
104
|
-
allow(Adopter::AdoptMenu).to receive(:adopt).and_return(result)
|
|
105
|
-
|
|
106
|
-
expect do
|
|
107
|
-
described_class.new.invoke(:project, nil, [source_dir, '-p',
|
|
108
|
-
"output_path:#{output_dir}",
|
|
109
|
-
'target_automation:selenium',
|
|
110
|
-
'target_framework:rspec'])
|
|
111
|
-
end.to output(/Adoption complete/).to_stdout
|
|
112
|
-
|
|
113
|
-
expect(Adopter::AdoptMenu).to have_received(:adopt).with(
|
|
114
|
-
hash_including(source_path: source_dir, target_automation: 'selenium', target_framework: 'rspec')
|
|
115
|
-
)
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
describe 'project command without parameters' do
|
|
120
|
-
it 'calls AdoptMenu#run' do
|
|
121
|
-
menu = instance_double(Adopter::AdoptMenu, run: nil)
|
|
122
|
-
allow(Adopter::AdoptMenu).to receive(:new).and_return(menu)
|
|
123
|
-
|
|
124
|
-
described_class.new.invoke(:project, nil, [source_dir])
|
|
125
|
-
|
|
126
|
-
expect(menu).to have_received(:run)
|
|
127
|
-
end
|
|
128
67
|
end
|
|
129
68
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'open3'
|
|
4
|
+
|
|
5
|
+
RSpec.describe 'ScaffoldingCommands' do
|
|
6
|
+
describe 'dependencies' do
|
|
7
|
+
it 'loads without relying on transitive requires for Pathname' do
|
|
8
|
+
# Loads the file in a clean Ruby process where nothing else has required 'pathname'.
|
|
9
|
+
# This catches the exact bug where Pathname is used but never explicitly required,
|
|
10
|
+
# which works in test suites (rspec loads pathname transitively) but crashes at runtime.
|
|
11
|
+
script = <<~RUBY
|
|
12
|
+
require_relative '../../lib/commands/scaffolding_commands'
|
|
13
|
+
puts 'OK'
|
|
14
|
+
RUBY
|
|
15
|
+
|
|
16
|
+
stdout, stderr, status = Open3.capture3('ruby', '-e', script, chdir: __dir__)
|
|
17
|
+
expect(status.success?).to be(true),
|
|
18
|
+
"ScaffoldingCommands failed to load in isolation:\n#{stderr}"
|
|
19
|
+
expect(stdout.strip).to eq('OK')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|