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.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/e2e_tests.yml +0 -17
  3. data/.github/workflows/system_tests.yml +0 -22
  4. data/README.md +8 -62
  5. data/lib/commands/scaffolding_commands.rb +22 -188
  6. data/lib/commands/utility_commands.rb +10 -44
  7. data/lib/generators/automation/templates/login.tt +1 -9
  8. data/lib/generators/automation/templates/page.tt +1 -7
  9. data/lib/generators/automation/templates/partials/initialize_selector.tt +1 -3
  10. data/lib/generators/automation/templates/partials/visit_method.tt +2 -6
  11. data/lib/generators/common_generator.rb +0 -6
  12. data/lib/generators/cucumber/cucumber_generator.rb +0 -24
  13. data/lib/generators/cucumber/templates/accessibility_steps.tt +2 -6
  14. data/lib/generators/cucumber/templates/cucumber.tt +0 -7
  15. data/lib/generators/cucumber/templates/env.tt +1 -3
  16. data/lib/generators/cucumber/templates/partials/appium_env.tt +1 -6
  17. data/lib/generators/cucumber/templates/partials/selenium_env.tt +0 -5
  18. data/lib/generators/cucumber/templates/partials/watir_env.tt +0 -5
  19. data/lib/generators/cucumber/templates/partials/web_steps.tt +4 -4
  20. data/lib/generators/cucumber/templates/world.tt +1 -3
  21. data/lib/generators/generator.rb +2 -46
  22. data/lib/generators/helper_generator.rb +4 -42
  23. data/lib/generators/infrastructure/templates/github.tt +2 -2
  24. data/lib/generators/infrastructure/templates/github_appium.tt +2 -6
  25. data/lib/generators/invoke_generators.rb +4 -25
  26. data/lib/generators/menu_generator.rb +10 -100
  27. data/lib/generators/rspec/rspec_generator.rb +0 -11
  28. data/lib/generators/rspec/templates/accessibility_spec.tt +2 -6
  29. data/lib/generators/rspec/templates/spec.tt +6 -8
  30. data/lib/generators/templates/common/gemfile.tt +0 -26
  31. data/lib/generators/templates/common/git_ignore.tt +0 -2
  32. data/lib/generators/templates/common/partials/mobile_config.tt +0 -4
  33. data/lib/generators/templates/common/partials/web_config.tt +0 -4
  34. data/lib/generators/templates/common/rakefile.tt +0 -9
  35. data/lib/generators/templates/common/read_me.tt +4 -10
  36. data/lib/generators/templates/helpers/allure_helper.tt +0 -10
  37. data/lib/generators/templates/helpers/browser_helper.tt +1 -1
  38. data/lib/generators/templates/helpers/partials/debug_diagnostics.tt +1 -3
  39. data/lib/generators/templates/helpers/partials/debug_start.tt +1 -3
  40. data/lib/generators/templates/helpers/partials/quit_driver.tt +1 -3
  41. data/lib/generators/templates/helpers/partials/screenshot.tt +1 -3
  42. data/lib/generators/templates/helpers/partials/selenium_driver.tt +1 -1
  43. data/lib/generators/templates/helpers/spec_helper.tt +2 -39
  44. data/lib/ruby_raider.rb +2 -50
  45. data/lib/scaffolding/project_detector.rb +30 -13
  46. data/lib/scaffolding/scaffolding.rb +0 -109
  47. data/lib/scaffolding/templates/component.tt +1 -4
  48. data/lib/scaffolding/templates/page_object.tt +0 -10
  49. data/lib/scaffolding/templates/spec.tt +2 -6
  50. data/lib/scaffolding/templates/steps.tt +0 -2
  51. data/lib/utilities/utilities.rb +26 -24
  52. data/lib/version +1 -1
  53. data/sig/commands/scaffolding_commands.rbs +0 -12
  54. data/sig/commands/utility_commands.rbs +0 -6
  55. data/sig/generators/cucumber/cucumber_generator.rbs +0 -4
  56. data/sig/generators/generator.rbs +0 -11
  57. data/sig/generators/helper_generator.rbs +1 -5
  58. data/sig/generators/invoke_generators.rbs +1 -2
  59. data/sig/generators/menu_generator.rbs +2 -6
  60. data/sig/generators/rspec/rspec_generator.rbs +0 -2
  61. data/sig/ruby_raider.rbs +1 -3
  62. data/sig/scaffolding/project_detector.rbs +0 -1
  63. data/sig/scaffolding/scaffolding.rbs +0 -23
  64. data/sig/utilities/utilities.rbs +0 -4
  65. data/spec/commands/raider_commands_spec.rb +0 -61
  66. data/spec/commands/scaffolding_commands_spec.rb +22 -0
  67. data/spec/integration/commands/browser_update_after_creation_spec.rb +123 -0
  68. data/spec/integration/commands/scaffolding_commands_spec.rb +0 -20
  69. data/spec/integration/commands/utility_commands_spec.rb +9 -9
  70. data/spec/integration/content/ci_content_spec.rb +6 -61
  71. data/spec/integration/content/common_content_spec.rb +0 -64
  72. data/spec/integration/content/config_content_spec.rb +1 -51
  73. data/spec/integration/content/content_helper.rb +2 -2
  74. data/spec/integration/content/gemfile_content_spec.rb +0 -71
  75. data/spec/integration/content/helper_content_spec.rb +4 -240
  76. data/spec/integration/content/page_content_spec.rb +0 -89
  77. data/spec/integration/content/syntax_validation_spec.rb +2 -2
  78. data/spec/integration/content/test_content_spec.rb +0 -119
  79. data/spec/integration/end_to_end_features_spec.rb +13 -411
  80. data/spec/integration/end_to_end_spec.rb +0 -96
  81. data/spec/integration/generators/axe_addon_spec.rb +2 -52
  82. data/spec/integration/generators/common_generator_spec.rb +1 -13
  83. data/spec/integration/generators/config_features_spec.rb +3 -81
  84. data/spec/integration/generators/debug_helper_spec.rb +0 -20
  85. data/spec/integration/generators/github_generator_spec.rb +5 -15
  86. data/spec/integration/generators/helpers_generator_spec.rb +0 -37
  87. data/spec/integration/scaffolding_e2e_spec.rb +540 -0
  88. data/spec/integration/settings_helper.rb +1 -3
  89. data/spec/integration/spec_helper.rb +6 -11
  90. data/spec/menus/menu_generator_spec.rb +4 -107
  91. data/spec/scaffolding/scaffold_project_detector_spec.rb +42 -26
  92. data/spec/scaffolding/scaffolding_features_spec.rb +0 -183
  93. data/spec/system/selenium_spec.rb +1 -4
  94. data/spec/system/support/system_test_helper.rb +0 -1
  95. data/spec/system/watir_spec.rb +1 -4
  96. data/spec/utilities/headless_config_spec.rb +82 -0
  97. data/spec/utilities/utilities_spec.rb +105 -0
  98. metadata +7 -97
  99. data/lib/adopter/adopt_menu.rb +0 -146
  100. data/lib/adopter/converters/base_converter.rb +0 -84
  101. data/lib/adopter/converters/identity_converter.rb +0 -53
  102. data/lib/adopter/migration_plan.rb +0 -74
  103. data/lib/adopter/migrator.rb +0 -96
  104. data/lib/adopter/plan_builder.rb +0 -275
  105. data/lib/adopter/project_analyzer.rb +0 -252
  106. data/lib/adopter/project_detector.rb +0 -157
  107. data/lib/generators/cucumber/templates/partials/capybara_env.tt +0 -38
  108. data/lib/generators/cucumber/templates/partials/capybara_world.tt +0 -6
  109. data/lib/generators/cucumber/templates/performance_feature.tt +0 -5
  110. data/lib/generators/cucumber/templates/performance_steps.tt +0 -17
  111. data/lib/generators/cucumber/templates/visual_feature.tt +0 -5
  112. data/lib/generators/cucumber/templates/visual_steps.tt +0 -19
  113. data/lib/generators/infrastructure/gitlab_generator.rb +0 -11
  114. data/lib/generators/infrastructure/templates/gitlab.tt +0 -46
  115. data/lib/generators/minitest/minitest_generator.rb +0 -35
  116. data/lib/generators/minitest/templates/accessibility_test.tt +0 -26
  117. data/lib/generators/minitest/templates/performance_test.tt +0 -18
  118. data/lib/generators/minitest/templates/test.tt +0 -64
  119. data/lib/generators/minitest/templates/visual_test.tt +0 -23
  120. data/lib/generators/rspec/templates/performance_spec.tt +0 -18
  121. data/lib/generators/rspec/templates/visual_spec.tt +0 -20
  122. data/lib/generators/templates/helpers/capybara_helper.tt +0 -32
  123. data/lib/generators/templates/helpers/performance_helper.tt +0 -57
  124. data/lib/generators/templates/helpers/visual_helper.tt +0 -58
  125. data/lib/llm/client.rb +0 -79
  126. data/lib/llm/config.rb +0 -57
  127. data/lib/llm/prompts.rb +0 -84
  128. data/lib/llm/provider.rb +0 -27
  129. data/lib/llm/providers/anthropic_provider.rb +0 -43
  130. data/lib/llm/providers/ollama_provider.rb +0 -56
  131. data/lib/llm/providers/openai_provider.rb +0 -42
  132. data/lib/llm/response_parser.rb +0 -67
  133. data/lib/plugin/plugin.rb +0 -111
  134. data/lib/plugin/plugin_exposer.rb +0 -55
  135. data/lib/scaffolding/crud_generator.rb +0 -94
  136. data/lib/scaffolding/dry_run_presenter.rb +0 -16
  137. data/lib/scaffolding/page_introspector.rb +0 -45
  138. data/lib/scaffolding/scaffold_menu.rb +0 -103
  139. data/lib/scaffolding/templates/page_from_url.tt +0 -75
  140. data/lib/scaffolding/templates/spec_from_page.tt +0 -31
  141. data/lib/scaffolding/templates/spec_from_url.tt +0 -46
  142. data/lib/scaffolding/url_analyzer.rb +0 -179
  143. data/sig/adopter/adopt_menu.rbs +0 -25
  144. data/sig/adopter/converters/base_converter.rbs +0 -23
  145. data/sig/adopter/converters/identity_converter.rbs +0 -16
  146. data/sig/adopter/migration_plan.rbs +0 -34
  147. data/sig/adopter/migrator.rbs +0 -21
  148. data/sig/adopter/plan_builder.rbs +0 -38
  149. data/sig/adopter/project_analyzer.rbs +0 -39
  150. data/sig/adopter/project_detector.rbs +0 -26
  151. data/sig/generators/infrastructure/gitlab_generator.rbs +0 -4
  152. data/sig/generators/minitest/minitest_generator.rbs +0 -8
  153. data/sig/llm/client.rbs +0 -15
  154. data/sig/llm/config.rbs +0 -20
  155. data/sig/llm/prompts.rbs +0 -8
  156. data/sig/llm/provider.rbs +0 -12
  157. data/sig/llm/providers/anthropic_provider.rbs +0 -16
  158. data/sig/llm/providers/ollama_provider.rbs +0 -18
  159. data/sig/llm/providers/openai_provider.rbs +0 -16
  160. data/sig/llm/response_parser.rbs +0 -13
  161. data/sig/plugin/plugin.rbs +0 -24
  162. data/sig/plugin/plugin_exposer.rbs +0 -20
  163. data/sig/scaffolding/crud_generator.rbs +0 -16
  164. data/sig/scaffolding/dry_run_presenter.rbs +0 -4
  165. data/sig/scaffolding/page_introspector.rbs +0 -14
  166. data/sig/scaffolding/scaffold_menu.rbs +0 -18
  167. data/sig/scaffolding/url_analyzer.rbs +0 -28
  168. data/spec/adopter/adopt_menu_spec.rb +0 -176
  169. data/spec/adopter/converters/identity_converter_spec.rb +0 -145
  170. data/spec/adopter/migration_plan_spec.rb +0 -113
  171. data/spec/adopter/migrator_spec.rb +0 -277
  172. data/spec/adopter/plan_builder_spec.rb +0 -298
  173. data/spec/adopter/project_analyzer_spec.rb +0 -337
  174. data/spec/adopter/project_detector_spec.rb +0 -295
  175. data/spec/generators/generator_spec.rb +0 -23
  176. data/spec/integration/content/reporter_content_spec.rb +0 -236
  177. data/spec/integration/content/skip_flags_content_spec.rb +0 -206
  178. data/spec/integration/generators/gitlab_generator_spec.rb +0 -38
  179. data/spec/integration/generators/lighthouse_addon_spec.rb +0 -132
  180. data/spec/integration/generators/minitest_generator_spec.rb +0 -64
  181. data/spec/integration/generators/reporter_spec.rb +0 -159
  182. data/spec/integration/generators/skip_flags_spec.rb +0 -134
  183. data/spec/integration/generators/visual_addon_spec.rb +0 -148
  184. data/spec/llm/client_spec.rb +0 -79
  185. data/spec/llm/config_spec.rb +0 -92
  186. data/spec/llm/prompts_spec.rb +0 -49
  187. data/spec/llm/response_parser_spec.rb +0 -92
  188. data/spec/menus/adopter_adopt_menu_spec.rb +0 -97
  189. data/spec/scaffolding/page_introspector_spec.rb +0 -82
  190. data/spec/scaffolding/url_analyzer_spec.rb +0 -110
  191. data/spec/system/adopt_matrix_spec.rb +0 -537
  192. data/spec/system/adopt_spec.rb +0 -225
  193. data/spec/system/capybara_spec.rb +0 -42
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d6b5fccbc2b3752d7f63391226d903a61a1368a404831ef10b1d0d230774fa5
4
- data.tar.gz: 7d4be1564e22cb7bf47e0d08ced4ae00868140bbd0c65833e733a904e634ecf4
3
+ metadata.gz: ce03b1ba3081d2259a481dc00f40b5bf95e7012784a593b187f3031fd9d0b33b
4
+ data.tar.gz: d42284c333748033d19c05231fb2da690896793745e93495382cafe1c6ccc4d0
5
5
  SHA512:
6
- metadata.gz: d9c67f3a57b7bfe7c3426ea0a5220af9b2623d9ce7003c1ebf2052bb19e23125a2f88ee277e89349dece675d13e07833818a93b25dbdbaf2a712dc8661fd0fa3
7
- data.tar.gz: 840873be251968d311b86e15586219fe402f433a7cf81f5eccd46e1b8227dfa52c95274099818d4eabf764b015e28cce116bcaac2334ba7e840be6a379a4d6d0
6
+ metadata.gz: 525f632e44410a8adff2addb4e7d60b2e9e9c8a48294672e2b6689898a0c7d88047ce5c0a908db4197595d2f85dabc2c589b93b75497b3e8df9d4001a7d179d5
7
+ data.tar.gz: 34862b92a99c1e1a743dbc3c6b4a48a3d0d8ebca5253b7c666078cb5acf957f5c4e7935167aa4556a4a119c03b928264014edda5dd58e357f4665b73f098c056
@@ -20,23 +20,6 @@ jobs:
20
20
  - name: Run content validation tests
21
21
  run: bundle exec rspec spec/integration/content/ --format documentation
22
22
 
23
- e2e-adopt:
24
- name: Adopt E2E tests
25
- runs-on: ubuntu-latest
26
-
27
- steps:
28
- - name: Checkout repository
29
- uses: actions/checkout@v4
30
-
31
- - name: Set up Ruby
32
- uses: ruby/setup-ruby@v1
33
- with:
34
- ruby-version: '3.3'
35
- bundler-cache: true
36
-
37
- - name: Run adopt system tests
38
- run: bundle exec rspec spec/system/adopt_spec.rb --format documentation
39
-
40
23
  command-and-menu-tests:
41
24
  name: Command routing and menu tests
42
25
  runs-on: ubuntu-latest
@@ -59,25 +59,3 @@ jobs:
59
59
 
60
60
  - name: Run Watir system tests
61
61
  run: bundle exec rspec spec/system/watir_spec.rb --format documentation
62
-
63
- capybara:
64
- name: Capybara frameworks
65
- needs: setup
66
- runs-on: ubuntu-latest
67
- steps:
68
- - name: Checkout repository
69
- uses: actions/checkout@v4
70
-
71
- - name: Set up Ruby
72
- uses: ruby/setup-ruby@v1
73
- with:
74
- ruby-version: '3.4'
75
- bundler-cache: true
76
-
77
- - name: Set up Chrome
78
- uses: browser-actions/setup-chrome@v1
79
- with:
80
- chrome-version: stable
81
-
82
- - name: Run Capybara system tests
83
- run: bundle exec rspec spec/system/capybara_spec.rb --format documentation
data/README.md CHANGED
@@ -33,11 +33,10 @@ Ruby Raider is a CLI gem and API backend for scaffolding and generating UI test
33
33
 
34
34
  ### Web Testing
35
35
 
36
- | Test Framework | Selenium | Watir | Capybara |
37
- |----------------|----------|-------|----------|
38
- | RSpec | ✅ | ✅ | ✅ |
39
- | Cucumber | ✅ | ✅ | ✅ |
40
- | Minitest | ✅ | ✅ | ✅ |
36
+ | Test Framework | Selenium | Watir |
37
+ |----------------|----------|-------|
38
+ | RSpec | ✅ | ✅ |
39
+ | Cucumber | ✅ | ✅ |
41
40
 
42
41
  ### Mobile Testing (Appium)
43
42
 
@@ -45,23 +44,14 @@ Ruby Raider is a CLI gem and API backend for scaffolding and generating UI test
45
44
  |----------------|-----|---------|----------------|
46
45
  | RSpec | ✅ | ✅ | ✅ |
47
46
  | Cucumber | ✅ | ✅ | ✅ |
48
- | Minitest | ✅ | ✅ | ✅ |
49
47
 
50
- ### Optional Add-ons (Web Only)
48
+ ### Optional Add-on (Web Only)
51
49
 
52
50
  | Add-on | Flag | Description |
53
51
  |--------|------|-------------|
54
52
  | Accessibility | `--accessibility` | Adds axe gem + example accessibility tests |
55
- | Visual Regression | `--visual` | Adds chunky_png + visual comparison helpers |
56
- | Performance | `--performance` | Adds Lighthouse auditing (requires `npm install -g lighthouse`) |
57
53
 
58
- ### CI/CD Platforms
59
-
60
- Projects can be generated with built-in CI/CD pipelines for **GitHub Actions** or **GitLab CI/CD**.
61
-
62
- ### Test Reporters
63
-
64
- Choose a reporter with `--reporter`: `allure`, `junit`, `json`, `both`, `all`, or `none`.
54
+ All generated projects include a **GitHub Actions** CI pipeline out of the box.
65
55
 
66
56
  ***The web tests run against the [Raider Test Store](https://raider-test-site.onrender.com/).***
67
57
 
@@ -96,13 +86,7 @@ raider new [project_name] -p framework:rspec automation:selenium
96
86
  Add optional features:
97
87
 
98
88
  ```bash
99
- raider new my_project -p framework:rspec automation:selenium --accessibility --visual --performance
100
- ```
101
-
102
- Skip flags for leaner projects:
103
-
104
- ```bash
105
- raider new my_project -p framework:cucumber automation:watir --skip_ci --skip_video --reporter none
89
+ raider new my_project -p framework:rspec automation:selenium --accessibility
106
90
  ```
107
91
 
108
92
  ## Commands
@@ -113,15 +97,13 @@ raider new my_project -p framework:cucumber automation:watir --skip_ci --skip_vi
113
97
 
114
98
  ```
115
99
  raider new [PROJECT_NAME] # Create a new framework project
116
- raider adopt # Import an existing test project
117
100
  raider generate # Access scaffolding commands
118
101
  raider utility # Access utility commands
119
- raider plugin_manager # Manage plugins
120
102
  raider version # Show current version
121
103
  raider help [COMMAND] # Describe available commands
122
104
  ```
123
105
 
124
- Shortcuts: `n` (new), `a` (adopt), `g` (generate), `u` (utility), `pm` (plugin_manager), `v` (version)
106
+ Shortcuts: `n` (new), `g` (generate), `u` (utility), `v` (version)
125
107
 
126
108
  ### Scaffolding Commands
127
109
 
@@ -133,18 +115,12 @@ raider g steps [NAME] # Create step definitions
133
115
  raider g helper [NAME] # Create a helper class
134
116
  raider g component [NAME] # Create a component class
135
117
  raider g scaffold [NAME(S)] # Create page + test + steps
136
- raider g destroy [NAME(S)] # Delete scaffolded files
137
- raider g from_url [URL] # Generate page & spec from a live URL
138
118
  ```
139
119
 
140
120
  Options:
141
121
 
142
- * `--from [FILE]` — Generate spec from an existing page object
143
- * `--ai` — Use LLM for intelligent test scenario generation
144
- * `--dry_run` — Preview files without creating them
145
122
  * `--uses [PAGES]` — Specify page dependencies
146
123
  * `--path [PATH]` — Custom output path
147
- * `--crud` — Generate full CRUD scaffold (list, create, detail, edit + tests)
148
124
 
149
125
  ### Utility Commands
150
126
 
@@ -160,38 +136,8 @@ raider u platform [PLATFORM] # Set platform for cross-platform tests
160
136
  raider u debug [on/off] # Toggle debug mode
161
137
  raider u start_appium # Start Appium server
162
138
  raider u desktop # Download Raider Desktop
163
- raider u llm [PROVIDER] # Configure LLM provider (openai, anthropic, ollama)
164
- ```
165
-
166
- ### Plugin Commands
167
-
168
- ```
169
- raider pm add [NAME] # Add a plugin to your project
170
- raider pm delete [NAME] # Remove a plugin
171
- raider pm list # List available plugins
172
- raider pm local # List installed plugins
173
139
  ```
174
140
 
175
- ### Adopt Command
176
-
177
- Import an existing test project into Ruby Raider conventions:
178
-
179
- ```bash
180
- raider adopt project [SOURCE_PATH]
181
- ```
182
-
183
- ## LLM Integration
184
-
185
- Ruby Raider supports optional LLM-powered features for intelligent test generation. Configure a provider:
186
-
187
- ```bash
188
- raider u llm openai # Configure OpenAI
189
- raider u llm anthropic # Configure Anthropic
190
- raider u llm ollama # Configure Ollama (local, no API key needed)
191
- ```
192
-
193
- Then use the `--ai` flag with scaffolding commands for smarter code generation.
194
-
195
141
  ## Development
196
142
 
197
143
  ```bash
@@ -2,174 +2,97 @@
2
2
 
3
3
  require 'thor'
4
4
  require 'fileutils'
5
+ require 'pathname'
5
6
  require_relative '../generators/menu_generator'
6
7
  require_relative '../scaffolding/scaffolding'
7
8
  require_relative '../scaffolding/name_normalizer'
8
- require_relative '../scaffolding/dry_run_presenter'
9
9
  require_relative '../scaffolding/project_detector'
10
10
  require_relative '../commands/utility_commands'
11
11
 
12
12
  class ScaffoldingCommands < Thor
13
- class_option :dry_run, type: :boolean, default: false,
14
- desc: 'Preview files without creating them', banner: ''
15
-
16
13
  desc 'page [PAGE_NAME]', 'Creates a new page object'
17
14
  option :path, type: :string, required: false,
18
15
  desc: 'The path where your page will be created', aliases: '-p'
19
- option :delete, type: :boolean, required: false,
20
- desc: 'This will delete the selected page', aliases: '-d'
21
16
  option :uses, type: :array, required: false,
22
17
  desc: 'Dependent pages to require', aliases: '-u'
23
18
 
24
19
  def page(name)
25
- return delete_scaffolding(name, 'page') if options[:delete]
26
- return dry_run_preview(name, 'page') if options[:dry_run]
27
-
28
20
  generate_scaffolding(name, 'page', options[:path], uses: options[:uses])
29
21
  end
30
22
 
31
23
  desc 'feature [NAME]', 'Creates a new feature'
32
24
  option :path, type: :string, required: false,
33
25
  desc: 'The path where your feature will be created', aliases: '-p'
34
- option :delete, type: :boolean, required: false,
35
- desc: 'This will delete the selected feature', aliases: '-d'
36
26
 
37
27
  def feature(name)
38
- return delete_scaffolding(name, 'feature') if options[:delete]
39
- return dry_run_preview(name, 'feature') if options[:dry_run]
40
-
41
28
  generate_scaffolding(name, 'feature', options[:path])
42
29
  end
43
30
 
44
31
  desc 'spec [SPEC_NAME]', 'Creates a new spec'
45
32
  option :path, type: :string, required: false,
46
33
  desc: 'The path where your spec will be created', aliases: '-p'
47
- option :delete, type: :boolean, required: false,
48
- desc: 'This will delete the selected spec', aliases: '-d'
49
- option :from, type: :string, required: false,
50
- desc: 'Generate spec stubs from an existing page object file', aliases: '-f'
51
34
  option :uses, type: :array, required: false,
52
35
  desc: 'Dependent pages to require', aliases: '-u'
53
- option :ai, type: :boolean, default: false,
54
- desc: 'Use LLM to generate meaningful test scenarios'
55
36
 
56
37
  def spec(name)
57
- return delete_scaffolding(name, 'spec') if options[:delete]
58
- return dry_run_preview(name, 'spec') if options[:dry_run]
59
- return generate_spec_from_page(name, options[:from], ai: options[:ai]) if options[:from]
60
-
61
38
  generate_scaffolding(name, 'spec', options[:path], uses: options[:uses])
62
39
  end
63
40
 
64
41
  desc 'helper [HELPER_NAME]', 'Creates a new helper'
65
42
  option :path, type: :string, required: false,
66
43
  desc: 'The path where your helper will be created', aliases: '-p'
67
- option :delete, type: :boolean, required: false,
68
- desc: 'This will delete the selected helper', aliases: '-d'
69
44
 
70
45
  def helper(name)
71
- return delete_scaffolding(name, 'helper') if options[:delete]
72
- return dry_run_preview(name, 'helper') if options[:dry_run]
73
-
74
46
  generate_scaffolding(name, 'helper', options[:path])
75
47
  end
76
48
 
77
49
  desc 'steps [STEPS_NAME]', 'Creates a new steps definition'
78
50
  option :path, type: :string, required: false,
79
51
  desc: 'The path where your steps will be created', aliases: '-p'
80
- option :delete, type: :boolean, required: false,
81
- desc: 'This will delete the selected steps', aliases: '-d'
82
52
 
83
53
  def steps(name)
84
- return delete_scaffolding(name, 'steps') if options[:delete]
85
- return dry_run_preview(name, 'steps') if options[:dry_run]
86
-
87
54
  generate_scaffolding(name, 'steps', options[:path])
88
55
  end
89
56
 
90
57
  desc 'component [NAME]', 'Creates a component inheriting from Component'
91
58
  option :path, type: :string, required: false,
92
59
  desc: 'The path where your component will be created', aliases: '-p'
93
- option :delete, type: :boolean, required: false,
94
- desc: 'This will delete the selected component', aliases: '-d'
95
60
 
96
61
  def component(name)
97
- return delete_scaffolding(name, 'component') if options[:delete]
98
- return dry_run_preview(name, 'component') if options[:dry_run]
99
-
100
62
  generate_scaffolding(name, 'component', options[:path])
101
63
  end
102
64
 
103
65
  desc 'scaffold [NAMES...]', 'Generates pages, specs/features, and helpers for one or more names'
104
- option :with, type: :array, required: false,
105
- desc: 'Components to generate (page,spec,feature,steps,helper,component,model)', aliases: '-w'
106
- option :crud, type: :boolean, required: false,
107
- desc: 'Generate CRUD pages (list, create, detail, edit) + tests + model'
108
66
  option :uses, type: :array, required: false,
109
67
  desc: 'Dependent pages to require', aliases: '-u'
110
68
 
111
69
  def scaffold(*names)
112
- return interactive_scaffold if names.empty?
113
-
114
- names.each do |name|
115
- if options[:crud]
116
- generate_crud(name)
117
- elsif options[:with]
118
- generate_selected_components(name, options[:with])
119
- else
120
- generate_default_scaffold(name)
121
- end
122
- end
123
- end
124
-
125
- desc 'destroy [NAMES...]', 'Removes all scaffolded files for the given names (page, spec/feature, steps)'
126
- option :with, type: :array, required: false,
127
- desc: 'Components to destroy (page,spec,feature,steps,helper,component)', aliases: '-w'
128
-
129
- def destroy(*names)
130
- if names.empty?
131
- say 'Please provide at least one name to destroy', :red
132
- return
133
- end
134
-
135
- names.each { |name| destroy_scaffold(name, options[:with]) }
136
- end
137
-
138
- map 'd' => 'destroy'
139
-
140
- desc 'from_url [URL]', 'Generates page object and spec from a live URL'
141
- option :name, type: :string, required: false,
142
- desc: 'Override the page object name', aliases: '-n'
143
- option :ai, type: :boolean, default: false,
144
- desc: 'Use LLM for intelligent page analysis'
145
-
146
- def from_url(url)
147
- require_relative '../scaffolding/url_analyzer'
148
- analyzer = UrlAnalyzer.new(url, name_override: options[:name], ai: options[:ai])
149
- analysis = analyzer.analyze.to_h
150
-
151
- page_name = analysis[:page_name]
152
-
153
- if options[:dry_run]
154
- DryRunPresenter.preview([
155
- "page_objects/pages/#{page_name}.rb",
156
- "spec/#{page_name}_spec.rb"
157
- ])
158
- return
159
- end
160
-
161
- Scaffolding.new([page_name]).generate_page_from_url(analysis)
162
- Scaffolding.new([page_name]).generate_spec_from_url(analysis)
163
- say "Generated page object and spec for #{url}"
70
+ names.each { |name| generate_default_scaffold(name) }
164
71
  end
165
72
 
166
73
  no_commands do
167
74
  def load_config_path(type)
168
- YAML.load_file('config/config.yml')["#{type}_path"] if Pathname.new('config/config.yml').exist?
75
+ ScaffoldProjectDetector.config_path(type)
169
76
  end
170
77
 
171
- def delete_scaffolding(name, type)
172
- Scaffolding.new([name]).send("delete_#{type}")
78
+ def validate_project!
79
+ warnings = ScaffoldProjectDetector.validate_project
80
+ warnings.each { |w| say "Warning: #{w}", :yellow }
81
+ show_detection_defaults
82
+ end
83
+
84
+ def show_detection_defaults
85
+ gemfile = ScaffoldProjectDetector.read_gemfile
86
+ if gemfile.empty?
87
+ say 'Warning: No Gemfile found, defaulting to selenium + rspec templates.', :yellow
88
+ else
89
+ automation = ScaffoldProjectDetector.detect_automation(gemfile)
90
+ framework = ScaffoldProjectDetector.detect_framework(gemfile)
91
+ if automation.nil?
92
+ say 'Warning: Could not detect automation library from Gemfile, defaulting to selenium.', :yellow
93
+ end
94
+ say 'Warning: Could not detect test framework from Gemfile, defaulting to rspec.', :yellow if framework.nil?
95
+ end
173
96
  end
174
97
 
175
98
  def generate_scaffolding(name, type, path, uses: nil)
@@ -179,13 +102,8 @@ class ScaffoldingCommands < Thor
179
102
  scaffolding.send("generate_#{type}")
180
103
  end
181
104
 
182
- def dry_run_preview(name, type)
183
- path = options[:path] || load_config_path(type)
184
- file = Scaffolding.planned_path(name, type, path)
185
- DryRunPresenter.preview([file])
186
- end
187
-
188
105
  def generate_default_scaffold(name)
106
+ validate_project!
189
107
  uses = options[:uses]
190
108
  if Pathname.new('spec').exist? && !Pathname.new('features').exist?
191
109
  generate_scaffolding(name, 'spec', load_config_path('spec'), uses:)
@@ -195,89 +113,5 @@ class ScaffoldingCommands < Thor
195
113
  end
196
114
  generate_scaffolding(name, 'page', load_config_path('page'), uses:)
197
115
  end
198
-
199
- def generate_selected_components(name, components)
200
- uses = options[:uses]
201
- components.each do |comp|
202
- comp = comp.downcase.strip
203
- case comp
204
- when 'model'
205
- generate_model_data(name)
206
- else
207
- generate_scaffolding(name, comp, load_config_path(comp), uses:)
208
- end
209
- end
210
- end
211
-
212
- def generate_crud(name)
213
- require_relative '../scaffolding/crud_generator'
214
- if options[:dry_run]
215
- crud = CrudGenerator.new(name, Scaffolding, method(:load_config_path))
216
- DryRunPresenter.preview(crud.planned_files)
217
- return
218
- end
219
- crud = CrudGenerator.new(name, Scaffolding, method(:load_config_path))
220
- generated = crud.generate
221
- say "Generated CRUD scaffold for: #{generated.join(', ')}"
222
- end
223
-
224
- def generate_spec_from_page(name, source_file, ai: false) # rubocop:disable Naming/MethodParameterName
225
- Scaffolding.new([name]).generate_spec_from_page(source_file, ai:)
226
- end
227
-
228
- def generate_model_data(name)
229
- normalized = NameNormalizer.normalize(name)
230
- path = "models/data/#{normalized}.yml"
231
- return if File.exist?(path)
232
-
233
- FileUtils.mkdir_p(File.dirname(path))
234
- File.write(path, model_template(normalized))
235
- end
236
-
237
- def model_template(name)
238
- <<~YAML
239
- # Data model for #{name}
240
- default:
241
- name: 'Test #{name.capitalize}'
242
- email: 'test@example.com'
243
-
244
- valid:
245
- name: 'Valid #{name.capitalize}'
246
- email: 'valid@example.com'
247
-
248
- invalid:
249
- name: ''
250
- email: 'invalid'
251
- YAML
252
- end
253
-
254
- def destroy_scaffold(name, components = nil)
255
- types = components ? components.map { |c| c.downcase.strip } : detect_scaffold_types
256
- types.each { |type| delete_scaffolding(name, type) }
257
- end
258
-
259
- def detect_scaffold_types
260
- if Pathname.new('spec').exist? && !Pathname.new('features').exist?
261
- %w[page spec]
262
- else
263
- %w[page feature steps]
264
- end
265
- end
266
-
267
- def interactive_scaffold
268
- require_relative '../scaffolding/scaffold_menu'
269
- result = ScaffoldMenu.new.run
270
- return unless result
271
-
272
- result[:names].each do |name|
273
- result[:components].each do |comp|
274
- if comp == :model
275
- generate_model_data(name)
276
- else
277
- generate_scaffolding(name, comp.to_s, load_config_path(comp.to_s), uses: result[:uses])
278
- end
279
- end
280
- end
281
- end
282
116
  end
283
117
  end
@@ -35,7 +35,7 @@ class UtilityCommands < Thor
35
35
  browser_options(selected_options) if selected_options || options[:delete]
36
36
  end
37
37
 
38
- desc 'browser_options [OPTIONS]', 'Sets the browser options for the project'
38
+ desc 'browser_options [OPTIONS]', 'Sets the browser arguments for the current browser (e.g. no-sandbox, headless)'
39
39
  option :delete,
40
40
  type: :boolean, required: false, desc: 'This will delete your browser options', aliases: '-d'
41
41
 
@@ -44,6 +44,15 @@ class UtilityCommands < Thor
44
44
  Utilities.delete_browser_options if options[:delete]
45
45
  end
46
46
 
47
+ desc 'headless [on/off]', 'Toggles headless mode for browser tests'
48
+
49
+ def headless(toggle)
50
+ enabled = %w[on true 1 yes].include?(toggle.downcase)
51
+ Utilities.headless = enabled
52
+ state = enabled ? 'enabled' : 'disabled'
53
+ say "Headless mode #{state}", :green
54
+ end
55
+
47
56
  desc 'raid', 'It runs all the tests in a project'
48
57
  option :parallel,
49
58
  type: :boolean, required: false, desc: 'It runs the tests in parallel', aliases: '-p'
@@ -114,47 +123,4 @@ class UtilityCommands < Thor
114
123
  say 'Raider Desktop downloaded successfully!', :green
115
124
  end
116
125
 
117
- desc 'llm [PROVIDER]', 'Configures the LLM provider (openai, anthropic, ollama)'
118
- option :key, type: :string, required: false, desc: 'API key for the provider', aliases: '-k'
119
- option :model, type: :string, required: false, desc: 'Model name to use', aliases: '-m'
120
- option :url, type: :string, required: false, desc: 'API URL (for ollama)', aliases: '-u'
121
- option :status, type: :boolean, required: false, desc: 'Show current LLM configuration', aliases: '-s'
122
-
123
- def llm(provider = nil)
124
- if options[:status] || provider.nil?
125
- show_llm_status
126
- return
127
- end
128
- configure_llm(provider)
129
- end
130
-
131
- no_commands do
132
- def configure_llm(provider)
133
- unless %w[openai anthropic ollama].include?(provider)
134
- say "Unknown provider '#{provider}'. Choose: openai, anthropic, ollama", :red
135
- return
136
- end
137
-
138
- Utilities.llm_provider = provider
139
- Utilities.llm_api_key = options[:key] if options[:key]
140
- Utilities.llm_model = options[:model] if options[:model]
141
- Utilities.llm_url = options[:url] if options[:url]
142
- say "LLM configured: #{provider}", :green
143
- end
144
-
145
- def show_llm_status
146
- require_relative '../llm/client'
147
- status = Llm::Client.status
148
- if status[:configured]
149
- say "Provider: #{status[:provider]}"
150
- say "Model: #{status[:model] || 'default'}"
151
- say "Available: #{status[:available] ? 'yes' : 'no'}"
152
- else
153
- say 'No LLM configured. Use: raider u llm <provider>', :yellow
154
- say ' Providers: openai, anthropic, ollama'
155
- say ' Example: raider u llm ollama'
156
- say ' Example: raider u llm openai -k sk-...'
157
- end
158
- end
159
- end
160
126
  end
@@ -9,13 +9,7 @@ class Login < Page
9
9
 
10
10
  # Actions
11
11
 
12
- <%- if capybara? -%>
13
- def login(username, password)
14
- fill_in 'loginFrm_loginname', with: username
15
- fill_in 'loginFrm_password', with: password
16
- click_button 'Login'
17
- end
18
- <%- elsif selenium_based? -%>
12
+ <%- if selenium_based? -%>
19
13
  def login(username, password)
20
14
  username_field.send_keys username
21
15
  password_field.send_keys password
@@ -29,7 +23,6 @@ class Login < Page
29
23
  login_button.click
30
24
  end
31
25
  <%- end -%>
32
- <%- unless capybara? -%>
33
26
 
34
27
  private
35
28
 
@@ -58,5 +51,4 @@ class Login < Page
58
51
  browser.button(xpath: "//button[@title='Login']")
59
52
  <%- end -%>
60
53
  end
61
- <%- end -%>
62
54
  end
@@ -14,13 +14,7 @@ class Page
14
14
  self.class.to_s.sub('Page', ' Page')
15
15
  end
16
16
 
17
- <%- if capybara? -%>
18
- # Components
19
-
20
- def header
21
- Header.new(find('.welcome-msg'))
22
- end
23
- <%- elsif selenium_based? -%>
17
+ <%- if selenium_based? -%>
24
18
  # Components
25
19
 
26
20
  def header
@@ -1,6 +1,4 @@
1
- <% if capybara? %>
2
- include Capybara::DSL
3
- <% elsif watir? %>
1
+ <% if watir? %>
4
2
  attr_reader :browser
5
3
 
6
4
  def initialize(browser)
@@ -1,9 +1,5 @@
1
1
  <% if web? %>
2
- <% if capybara? %>
3
- def visit_page(*page)
4
- Capybara.visit full_url(page.first)
5
- end
6
- <% elsif selenium_based? %>
2
+ <% if selenium_based? %>
7
3
  def visit(*page)
8
4
  @driver.navigate.to full_url(page.first)
9
5
  end
@@ -12,4 +8,4 @@
12
8
  @browser.goto full_url(page.first)
13
9
  end
14
10
  <% end %>
15
- <% end %>
11
+ <% end %>
@@ -17,10 +17,6 @@ class CommonGenerator < Generator
17
17
  template('common/rakefile.tt', "#{name}/Rakefile")
18
18
  end
19
19
 
20
- def generate_ruby_version_file
21
- template('common/ruby_version.tt', "#{name}/.ruby-version")
22
- end
23
-
24
20
  def generate_gemfile
25
21
  template('common/gemfile.tt', "#{name}/Gemfile")
26
22
  end
@@ -44,8 +40,6 @@ class CommonGenerator < Generator
44
40
  end
45
41
 
46
42
  def create_allure_folder
47
- return unless allure_reporter?
48
-
49
43
  empty_directory "#{name}/allure-results"
50
44
  end
51
45
  end