ruby_raider 2.0.0 → 3.0.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 (224) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/e2e_tests.yml +58 -0
  3. data/.github/workflows/steep.yml +21 -0
  4. data/.gitignore +1 -1
  5. data/.reek.yml +46 -4
  6. data/.ruby-version +1 -1
  7. data/README.md +138 -77
  8. data/Steepfile +22 -0
  9. data/assets/ruby_raider_logo.svg +51 -0
  10. data/lib/adopter/adopt_menu.rb +11 -15
  11. data/lib/adopter/converters/base_converter.rb +1 -2
  12. data/lib/adopter/converters/identity_converter.rb +3 -6
  13. data/lib/adopter/migration_plan.rb +0 -1
  14. data/lib/adopter/plan_builder.rb +2 -5
  15. data/lib/adopter/project_analyzer.rb +1 -5
  16. data/lib/adopter/project_detector.rb +3 -5
  17. data/lib/commands/adopt_commands.rb +0 -1
  18. data/lib/commands/plugin_commands.rb +0 -2
  19. data/lib/commands/scaffolding_commands.rb +220 -37
  20. data/lib/commands/utility_commands.rb +82 -2
  21. data/lib/generators/automation/automation_generator.rb +0 -7
  22. data/lib/generators/automation/templates/partials/element.tt +1 -1
  23. data/lib/generators/automation/templates/partials/initialize_selector.tt +0 -7
  24. data/lib/generators/automation/templates/partials/url_methods.tt +0 -1
  25. data/lib/generators/common_generator.rb +12 -0
  26. data/lib/generators/cucumber/cucumber_generator.rb +36 -0
  27. data/lib/generators/cucumber/templates/accessibility_feature.tt +5 -0
  28. data/lib/generators/cucumber/templates/accessibility_steps.tt +21 -0
  29. data/lib/generators/cucumber/templates/cucumber.tt +8 -1
  30. data/lib/generators/cucumber/templates/feature.tt +0 -4
  31. data/lib/generators/cucumber/templates/partials/appium_env.tt +5 -0
  32. data/lib/generators/cucumber/templates/partials/capybara_env.tt +19 -1
  33. data/lib/generators/cucumber/templates/partials/driver_world.tt +1 -4
  34. data/lib/generators/cucumber/templates/partials/selenium_env.tt +22 -35
  35. data/lib/generators/cucumber/templates/partials/watir_env.tt +20 -1
  36. data/lib/generators/cucumber/templates/partials/web_steps.tt +6 -12
  37. data/lib/generators/cucumber/templates/performance_feature.tt +5 -0
  38. data/lib/generators/cucumber/templates/performance_steps.tt +17 -0
  39. data/lib/generators/cucumber/templates/visual_feature.tt +5 -0
  40. data/lib/generators/cucumber/templates/visual_steps.tt +19 -0
  41. data/lib/generators/generator.rb +38 -7
  42. data/lib/generators/helper_generator.rb +24 -7
  43. data/lib/generators/infrastructure/templates/github.tt +1 -1
  44. data/lib/generators/infrastructure/templates/github_appium.tt +2 -2
  45. data/lib/generators/infrastructure/templates/gitlab.tt +1 -1
  46. data/lib/generators/invoke_generators.rb +42 -9
  47. data/lib/generators/menu_generator.rb +120 -11
  48. data/lib/generators/minitest/minitest_generator.rb +16 -4
  49. data/lib/generators/minitest/templates/accessibility_test.tt +26 -0
  50. data/lib/generators/minitest/templates/performance_test.tt +18 -0
  51. data/lib/generators/minitest/templates/test.tt +5 -34
  52. data/lib/generators/minitest/templates/visual_test.tt +23 -0
  53. data/lib/generators/rspec/rspec_generator.rb +16 -4
  54. data/lib/generators/rspec/templates/accessibility_spec.tt +25 -0
  55. data/lib/generators/rspec/templates/performance_spec.tt +18 -0
  56. data/lib/generators/rspec/templates/spec.tt +5 -35
  57. data/lib/generators/rspec/templates/visual_spec.tt +20 -0
  58. data/lib/generators/template_renderer/partial_cache.rb +11 -1
  59. data/lib/generators/template_renderer/partial_resolver.rb +17 -10
  60. data/lib/generators/template_renderer.rb +17 -1
  61. data/lib/generators/templates/common/gemfile.tt +21 -6
  62. data/lib/generators/templates/common/git_ignore.tt +6 -1
  63. data/lib/generators/templates/common/partials/mobile_config.tt +5 -1
  64. data/lib/generators/templates/common/partials/web_config.tt +16 -7
  65. data/lib/generators/templates/common/rakefile.tt +36 -0
  66. data/lib/generators/templates/common/read_me.tt +41 -91
  67. data/lib/generators/templates/common/rspec.tt +3 -0
  68. data/lib/generators/templates/common/ruby_version.tt +1 -0
  69. data/lib/generators/templates/helpers/allure_helper.tt +11 -0
  70. data/lib/generators/templates/helpers/browser_helper.tt +12 -2
  71. data/lib/generators/templates/helpers/capybara_helper.tt +5 -1
  72. data/lib/generators/templates/helpers/debug_helper.tt +190 -0
  73. data/lib/generators/templates/helpers/driver_helper.tt +2 -10
  74. data/lib/generators/templates/helpers/partials/appium_driver.tt +0 -2
  75. data/lib/generators/templates/helpers/partials/debug_diagnostics.tt +7 -0
  76. data/lib/generators/templates/helpers/partials/debug_start.tt +7 -0
  77. data/lib/generators/templates/helpers/partials/driver_and_options.tt +1 -3
  78. data/lib/generators/templates/helpers/partials/selenium_driver.tt +8 -7
  79. data/lib/generators/templates/helpers/partials/video_start.tt +9 -0
  80. data/lib/generators/templates/helpers/partials/video_stop.tt +4 -0
  81. data/lib/generators/templates/helpers/performance_helper.tt +57 -0
  82. data/lib/generators/templates/helpers/spec_helper.tt +57 -8
  83. data/lib/generators/templates/helpers/test_helper.tt +69 -1
  84. data/lib/generators/templates/helpers/video_helper.tt +270 -0
  85. data/lib/generators/templates/helpers/visual_helper.tt +39 -46
  86. data/lib/llm/client.rb +79 -0
  87. data/lib/llm/config.rb +57 -0
  88. data/lib/llm/prompts.rb +84 -0
  89. data/lib/llm/provider.rb +27 -0
  90. data/lib/llm/providers/anthropic_provider.rb +43 -0
  91. data/lib/llm/providers/ollama_provider.rb +56 -0
  92. data/lib/llm/providers/openai_provider.rb +42 -0
  93. data/lib/llm/response_parser.rb +67 -0
  94. data/lib/plugin/plugin.rb +22 -20
  95. data/lib/plugin/plugin_exposer.rb +16 -38
  96. data/lib/ruby_raider.rb +47 -12
  97. data/lib/scaffolding/crud_generator.rb +94 -0
  98. data/lib/scaffolding/dry_run_presenter.rb +16 -0
  99. data/lib/scaffolding/name_normalizer.rb +63 -0
  100. data/lib/scaffolding/page_introspector.rb +45 -0
  101. data/lib/scaffolding/project_detector.rb +72 -0
  102. data/lib/scaffolding/scaffold_menu.rb +103 -0
  103. data/lib/scaffolding/scaffolding.rb +158 -11
  104. data/lib/scaffolding/templates/component.tt +30 -0
  105. data/lib/scaffolding/templates/feature.tt +4 -4
  106. data/lib/scaffolding/templates/helper.tt +15 -1
  107. data/lib/scaffolding/templates/page_from_url.tt +75 -0
  108. data/lib/scaffolding/templates/page_object.tt +50 -1
  109. data/lib/scaffolding/templates/spec.tt +33 -2
  110. data/lib/scaffolding/templates/spec_from_page.tt +31 -0
  111. data/lib/scaffolding/templates/spec_from_url.tt +46 -0
  112. data/lib/scaffolding/templates/steps.tt +17 -5
  113. data/lib/scaffolding/url_analyzer.rb +179 -0
  114. data/lib/utilities/desktop_downloader.rb +177 -0
  115. data/lib/utilities/logo.rb +83 -0
  116. data/lib/utilities/utilities.rb +53 -20
  117. data/lib/version +1 -1
  118. data/ruby_raider.gemspec +1 -0
  119. data/sig/adopter/adopt_menu.rbs +25 -0
  120. data/sig/adopter/converters/base_converter.rbs +23 -0
  121. data/sig/adopter/converters/identity_converter.rbs +16 -0
  122. data/sig/adopter/migration_plan.rbs +34 -0
  123. data/sig/adopter/migrator.rbs +21 -0
  124. data/sig/adopter/plan_builder.rbs +38 -0
  125. data/sig/adopter/project_analyzer.rbs +39 -0
  126. data/sig/adopter/project_detector.rbs +26 -0
  127. data/sig/commands/adopt_commands.rbs +8 -0
  128. data/sig/commands/loaded_commands.rbs +5 -0
  129. data/sig/commands/plugin_commands.rbs +9 -0
  130. data/sig/commands/scaffolding_commands.rbs +28 -0
  131. data/sig/commands/utility_commands.rbs +21 -0
  132. data/sig/generators/automation/automation_generator.rbs +20 -0
  133. data/sig/generators/common_generator.rbs +12 -0
  134. data/sig/generators/cucumber/cucumber_generator.rbs +16 -0
  135. data/sig/generators/generator.rbs +40 -0
  136. data/sig/generators/helper_generator.rbs +18 -0
  137. data/sig/generators/infrastructure/github_generator.rbs +5 -0
  138. data/sig/generators/infrastructure/gitlab_generator.rbs +4 -0
  139. data/sig/generators/invoke_generators.rbs +10 -0
  140. data/sig/generators/menu_generator.rbs +29 -0
  141. data/sig/generators/minitest/minitest_generator.rbs +8 -0
  142. data/sig/generators/rspec/rspec_generator.rbs +8 -0
  143. data/sig/generators/template_renderer/partial_cache.rbs +20 -0
  144. data/sig/generators/template_renderer/partial_resolver.rbs +20 -0
  145. data/sig/generators/template_renderer/template_error.rbs +19 -0
  146. data/sig/generators/template_renderer.rbs +10 -0
  147. data/sig/llm/client.rbs +15 -0
  148. data/sig/llm/config.rbs +20 -0
  149. data/sig/llm/prompts.rbs +8 -0
  150. data/sig/llm/provider.rbs +12 -0
  151. data/sig/llm/providers/anthropic_provider.rbs +16 -0
  152. data/sig/llm/providers/ollama_provider.rbs +18 -0
  153. data/sig/llm/providers/openai_provider.rbs +16 -0
  154. data/sig/llm/response_parser.rbs +13 -0
  155. data/sig/plugin/plugin.rbs +24 -0
  156. data/sig/plugin/plugin_exposer.rbs +20 -0
  157. data/sig/ruby_raider.rbs +15 -0
  158. data/sig/scaffolding/crud_generator.rbs +16 -0
  159. data/sig/scaffolding/dry_run_presenter.rbs +4 -0
  160. data/sig/scaffolding/name_normalizer.rbs +17 -0
  161. data/sig/scaffolding/page_introspector.rbs +14 -0
  162. data/sig/scaffolding/project_detector.rbs +14 -0
  163. data/sig/scaffolding/scaffold_menu.rbs +18 -0
  164. data/sig/scaffolding/scaffolding.rbs +55 -0
  165. data/sig/scaffolding/url_analyzer.rbs +28 -0
  166. data/sig/utilities/desktop_downloader.rbs +23 -0
  167. data/sig/utilities/logger.rbs +13 -0
  168. data/sig/utilities/logo.rbs +16 -0
  169. data/sig/utilities/utilities.rbs +30 -0
  170. data/sig/vendor/thor.rbs +34 -0
  171. data/sig/vendor/tty_prompt.rbs +15 -0
  172. data/spec/adopter/adopt_menu_spec.rb +12 -12
  173. data/spec/adopter/migration_plan_spec.rb +1 -1
  174. data/spec/adopter/migrator_spec.rb +2 -2
  175. data/spec/adopter/project_detector_spec.rb +1 -1
  176. data/spec/commands/raider_commands_spec.rb +129 -0
  177. data/spec/generators/generator_spec.rb +23 -0
  178. data/spec/integration/commands/scaffolding_commands_spec.rb +1 -1
  179. data/spec/integration/commands/utility_commands_spec.rb +23 -3
  180. data/spec/integration/content/ci_content_spec.rb +119 -0
  181. data/spec/integration/content/common_content_spec.rb +288 -0
  182. data/spec/integration/content/config_content_spec.rb +175 -0
  183. data/spec/integration/content/content_helper.rb +32 -0
  184. data/spec/integration/content/gemfile_content_spec.rb +209 -0
  185. data/spec/integration/content/helper_content_spec.rb +485 -0
  186. data/spec/integration/content/page_content_spec.rb +259 -0
  187. data/spec/integration/content/reporter_content_spec.rb +236 -0
  188. data/spec/integration/content/skip_flags_content_spec.rb +206 -0
  189. data/spec/integration/content/syntax_validation_spec.rb +30 -0
  190. data/spec/integration/content/test_content_spec.rb +266 -0
  191. data/spec/integration/end_to_end_features_spec.rb +690 -0
  192. data/spec/integration/end_to_end_spec.rb +52 -16
  193. data/spec/integration/generators/automation_generator_spec.rb +0 -12
  194. data/spec/integration/generators/axe_addon_spec.rb +150 -0
  195. data/spec/integration/generators/common_generator_spec.rb +12 -13
  196. data/spec/integration/generators/config_features_spec.rb +155 -0
  197. data/spec/integration/generators/debug_helper_spec.rb +68 -0
  198. data/spec/integration/generators/helpers_generator_spec.rb +0 -12
  199. data/spec/integration/generators/lighthouse_addon_spec.rb +132 -0
  200. data/spec/integration/generators/minitest_generator_spec.rb +0 -6
  201. data/spec/integration/generators/reporter_spec.rb +159 -0
  202. data/spec/integration/generators/skip_flags_spec.rb +134 -0
  203. data/spec/integration/generators/visual_addon_spec.rb +148 -0
  204. data/spec/integration/settings_helper.rb +0 -3
  205. data/spec/integration/spec_helper.rb +30 -13
  206. data/spec/llm/client_spec.rb +79 -0
  207. data/spec/llm/config_spec.rb +92 -0
  208. data/spec/llm/prompts_spec.rb +49 -0
  209. data/spec/llm/response_parser_spec.rb +92 -0
  210. data/spec/menus/adopter_adopt_menu_spec.rb +97 -0
  211. data/spec/menus/menu_generator_spec.rb +263 -0
  212. data/spec/scaffolding/name_normalizer_spec.rb +113 -0
  213. data/spec/scaffolding/page_introspector_spec.rb +82 -0
  214. data/spec/scaffolding/scaffold_project_detector_spec.rb +104 -0
  215. data/spec/scaffolding/scaffolding_features_spec.rb +311 -0
  216. data/spec/scaffolding/url_analyzer_spec.rb +110 -0
  217. data/spec/system/adopt_matrix_spec.rb +537 -0
  218. data/spec/system/adopt_spec.rb +225 -0
  219. data/spec/system/support/system_test_helper.rb +0 -2
  220. data/spec/utilities/desktop_downloader_spec.rb +92 -0
  221. metadata +150 -5
  222. data/lib/generators/automation/templates/visual_options.tt +0 -16
  223. data/lib/generators/templates/helpers/partials/axe_driver.tt +0 -10
  224. data/lib/generators/templates/helpers/visual_spec_helper.tt +0 -35
@@ -0,0 +1,209 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'content_helper'
4
+
5
+ describe 'Gemfile content' do
6
+ shared_examples 'contains common gems' do |project_name|
7
+ subject(:gemfile) { read_generated(project_name, 'Gemfile') }
8
+
9
+ it 'includes rubygems source' do
10
+ expect(gemfile).to include("source 'https://rubygems.org'")
11
+ end
12
+
13
+ it 'includes rake' do
14
+ expect(gemfile).to include("gem 'rake'")
15
+ end
16
+
17
+ it 'includes reek' do
18
+ expect(gemfile).to include("gem 'reek'")
19
+ end
20
+
21
+ it 'includes rubocop' do
22
+ expect(gemfile).to include("gem 'rubocop'")
23
+ end
24
+
25
+ it 'includes activesupport' do
26
+ expect(gemfile).to include("gem 'activesupport'")
27
+ end
28
+ end
29
+
30
+ shared_examples 'contains rspec gems' do |project_name|
31
+ subject(:gemfile) { read_generated(project_name, 'Gemfile') }
32
+
33
+ it 'includes rspec' do
34
+ expect(gemfile).to include("gem 'rspec'")
35
+ end
36
+
37
+ it 'includes allure-rspec' do
38
+ expect(gemfile).to include("gem 'allure-rspec'")
39
+ end
40
+
41
+ it 'includes rubocop-rspec' do
42
+ expect(gemfile).to include("gem 'rubocop-rspec'")
43
+ end
44
+
45
+ it 'does not include cucumber' do
46
+ expect(gemfile).not_to include("gem 'cucumber'")
47
+ end
48
+
49
+ it 'does not include minitest' do
50
+ expect(gemfile).not_to include("gem 'minitest'\n")
51
+ end
52
+ end
53
+
54
+ shared_examples 'contains cucumber gems' do |project_name|
55
+ subject(:gemfile) { read_generated(project_name, 'Gemfile') }
56
+
57
+ it 'includes cucumber' do
58
+ expect(gemfile).to include("gem 'cucumber'")
59
+ end
60
+
61
+ it 'includes allure-cucumber' do
62
+ expect(gemfile).to include("gem 'allure-cucumber'")
63
+ end
64
+
65
+ it 'includes rspec as cucumber dependency' do
66
+ expect(gemfile).to include("gem 'rspec'")
67
+ end
68
+ end
69
+
70
+ shared_examples 'contains minitest gems' do |project_name|
71
+ subject(:gemfile) { read_generated(project_name, 'Gemfile') }
72
+
73
+ it 'includes minitest' do
74
+ expect(gemfile).to include("gem 'minitest'")
75
+ end
76
+
77
+ it 'includes minitest-reporters' do
78
+ expect(gemfile).to include("gem 'minitest-reporters'")
79
+ end
80
+
81
+ it 'includes rubocop-minitest' do
82
+ expect(gemfile).to include("gem 'rubocop-minitest'")
83
+ end
84
+ end
85
+
86
+ shared_examples 'contains selenium gems' do |project_name|
87
+ subject(:gemfile) { read_generated(project_name, 'Gemfile') }
88
+
89
+ it 'includes selenium-webdriver' do
90
+ expect(gemfile).to include("gem 'selenium-webdriver'")
91
+ end
92
+
93
+ it 'does not include watir' do
94
+ expect(gemfile).not_to include("gem 'watir'")
95
+ end
96
+ end
97
+
98
+ shared_examples 'contains watir gems' do |project_name|
99
+ subject(:gemfile) { read_generated(project_name, 'Gemfile') }
100
+
101
+ it 'includes watir' do
102
+ expect(gemfile).to include("gem 'watir'")
103
+ end
104
+
105
+ it 'does not include selenium-webdriver' do
106
+ expect(gemfile).not_to include("gem 'selenium-webdriver'")
107
+ end
108
+ end
109
+
110
+ shared_examples 'contains capybara gems' do |project_name|
111
+ subject(:gemfile) { read_generated(project_name, 'Gemfile') }
112
+
113
+ it 'includes capybara' do
114
+ expect(gemfile).to include("gem 'capybara'")
115
+ end
116
+
117
+ it 'includes selenium-webdriver as capybara driver' do
118
+ expect(gemfile).to include("gem 'selenium-webdriver'")
119
+ end
120
+
121
+ it 'does not include watir' do
122
+ expect(gemfile).not_to include("gem 'watir'")
123
+ end
124
+ end
125
+
126
+ shared_examples 'contains debug gems' do |project_name|
127
+ subject(:gemfile) { read_generated(project_name, 'Gemfile') }
128
+
129
+ it 'includes debug gem' do
130
+ expect(gemfile).to include("gem 'debug'")
131
+ end
132
+
133
+ it 'includes pry gem' do
134
+ expect(gemfile).to include("gem 'pry'")
135
+ end
136
+ end
137
+
138
+ context 'with rspec and selenium' do
139
+ name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::SELENIUM}"
140
+ include_examples 'contains common gems', name
141
+ include_examples 'contains rspec gems', name
142
+ include_examples 'contains selenium gems', name
143
+ include_examples 'contains debug gems', name
144
+ end
145
+
146
+ context 'with rspec and watir' do
147
+ name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::WATIR}"
148
+ include_examples 'contains common gems', name
149
+ include_examples 'contains rspec gems', name
150
+ include_examples 'contains watir gems', name
151
+ include_examples 'contains debug gems', name
152
+ end
153
+
154
+ context 'with rspec and capybara' do
155
+ name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::CAPYBARA}"
156
+ include_examples 'contains common gems', name
157
+ include_examples 'contains rspec gems', name
158
+ include_examples 'contains capybara gems', name
159
+ include_examples 'contains debug gems', name
160
+ end
161
+
162
+ context 'with cucumber and selenium' do
163
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::SELENIUM}"
164
+ include_examples 'contains common gems', name
165
+ include_examples 'contains cucumber gems', name
166
+ include_examples 'contains selenium gems', name
167
+ include_examples 'contains debug gems', name
168
+ end
169
+
170
+ context 'with cucumber and watir' do
171
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::WATIR}"
172
+ include_examples 'contains common gems', name
173
+ include_examples 'contains cucumber gems', name
174
+ include_examples 'contains watir gems', name
175
+ include_examples 'contains debug gems', name
176
+ end
177
+
178
+ context 'with cucumber and capybara' do
179
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::CAPYBARA}"
180
+ include_examples 'contains common gems', name
181
+ include_examples 'contains cucumber gems', name
182
+ include_examples 'contains capybara gems', name
183
+ include_examples 'contains debug gems', name
184
+ end
185
+
186
+ context 'with minitest and selenium' do
187
+ name = "#{FrameworkIndex::MINITEST}_#{AutomationIndex::SELENIUM}"
188
+ include_examples 'contains common gems', name
189
+ include_examples 'contains minitest gems', name
190
+ include_examples 'contains selenium gems', name
191
+ include_examples 'contains debug gems', name
192
+ end
193
+
194
+ context 'with minitest and watir' do
195
+ name = "#{FrameworkIndex::MINITEST}_#{AutomationIndex::WATIR}"
196
+ include_examples 'contains common gems', name
197
+ include_examples 'contains minitest gems', name
198
+ include_examples 'contains watir gems', name
199
+ include_examples 'contains debug gems', name
200
+ end
201
+
202
+ context 'with minitest and capybara' do
203
+ name = "#{FrameworkIndex::MINITEST}_#{AutomationIndex::CAPYBARA}"
204
+ include_examples 'contains common gems', name
205
+ include_examples 'contains minitest gems', name
206
+ include_examples 'contains capybara gems', name
207
+ include_examples 'contains debug gems', name
208
+ end
209
+ end
@@ -0,0 +1,485 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'content_helper'
4
+
5
+ describe 'Helper file content' do
6
+ # --- Driver helper ---
7
+
8
+ shared_examples 'valid driver helper' do |project_name|
9
+ subject(:helper) { read_generated(project_name, 'helpers/driver_helper.rb') }
10
+
11
+ it 'has frozen_string_literal' do
12
+ expect(helper).to have_frozen_string_literal
13
+ end
14
+
15
+ it 'has valid Ruby syntax' do
16
+ expect(helper).to have_valid_ruby_syntax
17
+ end
18
+
19
+ it 'defines DriverHelper module' do
20
+ expect(helper).to match(/module DriverHelper/)
21
+ end
22
+
23
+ it 'defines driver method' do
24
+ expect(helper).to match(/def driver/)
25
+ end
26
+
27
+ it 'requires yaml' do
28
+ expect(helper).to include("require 'yaml'")
29
+ end
30
+ end
31
+
32
+ shared_examples 'selenium driver helper' do |project_name|
33
+ subject(:helper) { read_generated(project_name, 'helpers/driver_helper.rb') }
34
+
35
+ it 'requires selenium-webdriver' do
36
+ expect(helper).to include("require 'selenium-webdriver'")
37
+ end
38
+
39
+ it 'does not require watir' do
40
+ expect(helper).not_to include("require 'watir'")
41
+ end
42
+
43
+ it 'does not reference Capybara' do
44
+ expect(helper).not_to include('Capybara')
45
+ end
46
+ end
47
+
48
+ # --- Browser helper ---
49
+
50
+ shared_examples 'valid browser helper' do |project_name|
51
+ subject(:helper) { read_generated(project_name, 'helpers/browser_helper.rb') }
52
+
53
+ it 'has frozen_string_literal' do
54
+ expect(helper).to have_frozen_string_literal
55
+ end
56
+
57
+ it 'has valid Ruby syntax' do
58
+ expect(helper).to have_valid_ruby_syntax
59
+ end
60
+
61
+ it 'defines BrowserHelper module' do
62
+ expect(helper).to match(/module BrowserHelper/)
63
+ end
64
+
65
+ it 'requires watir' do
66
+ expect(helper).to include("require 'watir'")
67
+ end
68
+
69
+ it 'defines browser method' do
70
+ expect(helper).to match(/def browser/)
71
+ end
72
+
73
+ it 'creates Watir::Browser' do
74
+ expect(helper).to include('Watir::Browser.new')
75
+ end
76
+
77
+ it 'does not require selenium-webdriver' do
78
+ expect(helper).not_to include("require 'selenium-webdriver'")
79
+ end
80
+ end
81
+
82
+ # --- Capybara helper ---
83
+
84
+ shared_examples 'valid capybara helper' do |project_name|
85
+ subject(:helper) { read_generated(project_name, 'helpers/capybara_helper.rb') }
86
+
87
+ it 'has frozen_string_literal' do
88
+ expect(helper).to have_frozen_string_literal
89
+ end
90
+
91
+ it 'has valid Ruby syntax' do
92
+ expect(helper).to have_valid_ruby_syntax
93
+ end
94
+
95
+ it 'defines CapybaraHelper module' do
96
+ expect(helper).to match(/module CapybaraHelper/)
97
+ end
98
+
99
+ it 'requires capybara' do
100
+ expect(helper).to include("require 'capybara'")
101
+ end
102
+
103
+ it 'configures Capybara' do
104
+ expect(helper).to include('Capybara.configure')
105
+ end
106
+
107
+ it 'registers Selenium driver' do
108
+ expect(helper).to include('Capybara.register_driver')
109
+ end
110
+
111
+ it 'reads from config.yml' do
112
+ expect(helper).to include("YAML.load_file('config/config.yml')")
113
+ end
114
+
115
+ it 'does not require watir' do
116
+ expect(helper).not_to include("require 'watir'")
117
+ end
118
+ end
119
+
120
+ # --- Spec helper ---
121
+
122
+ shared_examples 'valid spec helper' do |project_name|
123
+ subject(:helper) { read_generated(project_name, 'helpers/spec_helper.rb') }
124
+
125
+ it 'has frozen_string_literal' do
126
+ expect(helper).to have_frozen_string_literal
127
+ end
128
+
129
+ it 'has valid Ruby syntax' do
130
+ expect(helper).to have_valid_ruby_syntax
131
+ end
132
+
133
+ it 'requires rspec' do
134
+ expect(helper).to include("require 'rspec'")
135
+ end
136
+
137
+ it 'defines SpecHelper module' do
138
+ expect(helper).to match(/module SpecHelper/)
139
+ end
140
+
141
+ it 'configures RSpec' do
142
+ expect(helper).to include('RSpec.configure')
143
+ end
144
+
145
+ it 'requires allure_helper' do
146
+ expect(helper).to include("require_relative 'allure_helper'")
147
+ end
148
+ end
149
+
150
+ shared_examples 'selenium spec helper' do |project_name|
151
+ subject(:helper) { read_generated(project_name, 'helpers/spec_helper.rb') }
152
+
153
+ it 'includes DriverHelper' do
154
+ expect(helper).to include('include(DriverHelper)')
155
+ end
156
+
157
+ it 'requires driver_helper' do
158
+ expect(helper).to include("require_relative 'driver_helper'")
159
+ end
160
+
161
+ it 'maximizes window via driver' do
162
+ expect(helper).to include('driver.manage.window.maximize')
163
+ end
164
+ end
165
+
166
+ shared_examples 'watir spec helper' do |project_name|
167
+ subject(:helper) { read_generated(project_name, 'helpers/spec_helper.rb') }
168
+
169
+ it 'includes BrowserHelper' do
170
+ expect(helper).to include('include(BrowserHelper)')
171
+ end
172
+
173
+ it 'requires browser_helper' do
174
+ expect(helper).to include("require_relative 'browser_helper'")
175
+ end
176
+
177
+ it 'maximizes window via browser' do
178
+ expect(helper).to include('browser.window.maximize')
179
+ end
180
+ end
181
+
182
+ shared_examples 'capybara spec helper' do |project_name|
183
+ subject(:helper) { read_generated(project_name, 'helpers/spec_helper.rb') }
184
+
185
+ it 'includes Capybara::DSL' do
186
+ expect(helper).to include('include(Capybara::DSL)')
187
+ end
188
+
189
+ it 'requires capybara_helper' do
190
+ expect(helper).to include("require_relative 'capybara_helper'")
191
+ end
192
+
193
+ it 'calls CapybaraHelper.configure' do
194
+ expect(helper).to include('CapybaraHelper.configure')
195
+ end
196
+ end
197
+
198
+ # --- Test helper (Minitest) ---
199
+
200
+ shared_examples 'valid test helper' do |project_name|
201
+ subject(:helper) { read_generated(project_name, 'helpers/test_helper.rb') }
202
+
203
+ it 'has frozen_string_literal' do
204
+ expect(helper).to have_frozen_string_literal
205
+ end
206
+
207
+ it 'has valid Ruby syntax' do
208
+ expect(helper).to have_valid_ruby_syntax
209
+ end
210
+
211
+ it 'requires minitest/autorun' do
212
+ expect(helper).to include("require 'minitest/autorun'")
213
+ end
214
+
215
+ it 'defines TestHelper module' do
216
+ expect(helper).to match(/module TestHelper/)
217
+ end
218
+
219
+ it 'includes TestHelper into Minitest::Test' do
220
+ expect(helper).to include('Minitest::Test.include(TestHelper)')
221
+ end
222
+ end
223
+
224
+ shared_examples 'selenium test helper' do |project_name|
225
+ subject(:helper) { read_generated(project_name, 'helpers/test_helper.rb') }
226
+
227
+ it 'includes DriverHelper' do
228
+ expect(helper).to include('include DriverHelper')
229
+ end
230
+
231
+ it 'requires driver_helper' do
232
+ expect(helper).to include("require_relative 'driver_helper'")
233
+ end
234
+ end
235
+
236
+ shared_examples 'watir test helper' do |project_name|
237
+ subject(:helper) { read_generated(project_name, 'helpers/test_helper.rb') }
238
+
239
+ it 'includes BrowserHelper' do
240
+ expect(helper).to include('include BrowserHelper')
241
+ end
242
+
243
+ it 'requires browser_helper' do
244
+ expect(helper).to include("require_relative 'browser_helper'")
245
+ end
246
+ end
247
+
248
+ shared_examples 'capybara test helper' do |project_name|
249
+ subject(:helper) { read_generated(project_name, 'helpers/test_helper.rb') }
250
+
251
+ it 'includes Capybara::DSL' do
252
+ expect(helper).to include('include Capybara::DSL')
253
+ end
254
+
255
+ it 'requires capybara_helper' do
256
+ expect(helper).to include("require_relative 'capybara_helper'")
257
+ end
258
+
259
+ it 'calls CapybaraHelper.configure' do
260
+ expect(helper).to include('CapybaraHelper.configure')
261
+ end
262
+ end
263
+
264
+ # --- Video helper ---
265
+
266
+ shared_examples 'valid video helper' do |project_name|
267
+ subject(:helper) { read_generated(project_name, 'helpers/video_helper.rb') }
268
+
269
+ it 'has frozen_string_literal' do
270
+ expect(helper).to have_frozen_string_literal
271
+ end
272
+
273
+ it 'has valid Ruby syntax' do
274
+ expect(helper).to have_valid_ruby_syntax
275
+ end
276
+
277
+ it 'defines VideoHelper module' do
278
+ expect(helper).to match(/module VideoHelper/)
279
+ end
280
+
281
+ it 'defines recorder_for method' do
282
+ expect(helper).to include('def recorder_for')
283
+ end
284
+
285
+ it 'defines CdpRecorder class' do
286
+ expect(helper).to include('class CdpRecorder')
287
+ end
288
+
289
+ it 'defines ScreenCaptureRecorder class' do
290
+ expect(helper).to include('class ScreenCaptureRecorder')
291
+ end
292
+
293
+ it 'defines NullRecorder class' do
294
+ expect(helper).to include('class NullRecorder')
295
+ end
296
+
297
+ it 'reads config from YAML' do
298
+ expect(helper).to include('YAML.load_file')
299
+ end
300
+ end
301
+
302
+ shared_examples 'mobile video helper' do |project_name|
303
+ subject(:helper) { read_generated(project_name, 'helpers/video_helper.rb') }
304
+
305
+ it 'defines AppiumRecorder class' do
306
+ expect(helper).to include('class AppiumRecorder')
307
+ end
308
+ end
309
+
310
+ shared_examples 'web-only video helper' do |project_name|
311
+ subject(:helper) { read_generated(project_name, 'helpers/video_helper.rb') }
312
+
313
+ it 'does not include AppiumRecorder' do
314
+ expect(helper).not_to include('class AppiumRecorder')
315
+ end
316
+ end
317
+
318
+ # --- Allure helper ---
319
+
320
+ shared_examples 'valid allure helper' do |project_name|
321
+ subject(:helper) { read_generated(project_name, 'helpers/allure_helper.rb') }
322
+
323
+ it 'has valid Ruby syntax' do
324
+ expect(helper).to have_valid_ruby_syntax
325
+ end
326
+
327
+ it 'defines AllureHelper' do
328
+ expect(helper).to match(/AllureHelper|module AllureHelper|class AllureHelper/)
329
+ end
330
+ end
331
+
332
+ # --- Debug helper ---
333
+
334
+ shared_examples 'valid debug helper' do |project_name|
335
+ subject(:helper) { read_generated(project_name, 'helpers/debug_helper.rb') }
336
+
337
+ it 'has frozen_string_literal' do
338
+ expect(helper).to have_frozen_string_literal
339
+ end
340
+
341
+ it 'has valid Ruby syntax' do
342
+ expect(helper).to have_valid_ruby_syntax
343
+ end
344
+
345
+ it 'defines DebugHelper module' do
346
+ expect(helper).to match(/module DebugHelper/)
347
+ end
348
+
349
+ it 'defines enabled? method' do
350
+ expect(helper).to include('def enabled?')
351
+ end
352
+
353
+ it 'defines capture_failure_diagnostics method' do
354
+ expect(helper).to include('def capture_failure_diagnostics')
355
+ end
356
+
357
+ it 'defines ActionLogger class' do
358
+ expect(helper).to include('class ActionLogger')
359
+ end
360
+
361
+ it 'defines NullActionLogger class' do
362
+ expect(helper).to include('class NullActionLogger')
363
+ end
364
+
365
+ it 'reads config from YAML' do
366
+ expect(helper).to include('YAML.load_file')
367
+ end
368
+ end
369
+
370
+ # --- RSpec + automation contexts ---
371
+
372
+ context 'with rspec and selenium' do
373
+ name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::SELENIUM}"
374
+ it_behaves_like 'valid driver helper', name
375
+ it_behaves_like 'selenium driver helper', name
376
+ it_behaves_like 'valid spec helper', name
377
+ it_behaves_like 'selenium spec helper', name
378
+ it_behaves_like 'valid allure helper', name
379
+ it_behaves_like 'valid video helper', name
380
+ it_behaves_like 'web-only video helper', name
381
+ it_behaves_like 'valid debug helper', name
382
+ end
383
+
384
+ context 'with rspec and watir' do
385
+ name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::WATIR}"
386
+ it_behaves_like 'valid browser helper', name
387
+ it_behaves_like 'valid spec helper', name
388
+ it_behaves_like 'watir spec helper', name
389
+ it_behaves_like 'valid allure helper', name
390
+ it_behaves_like 'valid video helper', name
391
+ it_behaves_like 'web-only video helper', name
392
+ it_behaves_like 'valid debug helper', name
393
+ end
394
+
395
+ context 'with rspec and capybara' do
396
+ name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::CAPYBARA}"
397
+ it_behaves_like 'valid capybara helper', name
398
+ it_behaves_like 'valid spec helper', name
399
+ it_behaves_like 'capybara spec helper', name
400
+ it_behaves_like 'valid allure helper', name
401
+ it_behaves_like 'valid video helper', name
402
+ it_behaves_like 'web-only video helper', name
403
+ it_behaves_like 'valid debug helper', name
404
+ end
405
+
406
+ # --- Minitest + automation contexts ---
407
+
408
+ context 'with minitest and selenium' do
409
+ name = "#{FrameworkIndex::MINITEST}_#{AutomationIndex::SELENIUM}"
410
+ it_behaves_like 'valid driver helper', name
411
+ it_behaves_like 'selenium driver helper', name
412
+ it_behaves_like 'valid test helper', name
413
+ it_behaves_like 'selenium test helper', name
414
+ it_behaves_like 'valid allure helper', name
415
+ it_behaves_like 'valid video helper', name
416
+ it_behaves_like 'web-only video helper', name
417
+ it_behaves_like 'valid debug helper', name
418
+ end
419
+
420
+ context 'with minitest and watir' do
421
+ name = "#{FrameworkIndex::MINITEST}_#{AutomationIndex::WATIR}"
422
+ it_behaves_like 'valid browser helper', name
423
+ it_behaves_like 'valid test helper', name
424
+ it_behaves_like 'watir test helper', name
425
+ it_behaves_like 'valid allure helper', name
426
+ it_behaves_like 'valid video helper', name
427
+ it_behaves_like 'web-only video helper', name
428
+ it_behaves_like 'valid debug helper', name
429
+ end
430
+
431
+ context 'with minitest and capybara' do
432
+ name = "#{FrameworkIndex::MINITEST}_#{AutomationIndex::CAPYBARA}"
433
+ it_behaves_like 'valid capybara helper', name
434
+ it_behaves_like 'valid test helper', name
435
+ it_behaves_like 'capybara test helper', name
436
+ it_behaves_like 'valid allure helper', name
437
+ it_behaves_like 'valid video helper', name
438
+ it_behaves_like 'web-only video helper', name
439
+ it_behaves_like 'valid debug helper', name
440
+ end
441
+
442
+ # --- Cucumber + automation contexts (no spec_helper/test_helper) ---
443
+
444
+ context 'with cucumber and selenium' do
445
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::SELENIUM}"
446
+ it_behaves_like 'valid driver helper', name
447
+ it_behaves_like 'selenium driver helper', name
448
+ it_behaves_like 'valid allure helper', name
449
+ it_behaves_like 'valid video helper', name
450
+ it_behaves_like 'web-only video helper', name
451
+ it_behaves_like 'valid debug helper', name
452
+ end
453
+
454
+ context 'with cucumber and watir' do
455
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::WATIR}"
456
+ it_behaves_like 'valid browser helper', name
457
+ it_behaves_like 'valid allure helper', name
458
+ it_behaves_like 'valid video helper', name
459
+ it_behaves_like 'web-only video helper', name
460
+ it_behaves_like 'valid debug helper', name
461
+ end
462
+
463
+ context 'with cucumber and capybara' do
464
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::CAPYBARA}"
465
+ it_behaves_like 'valid capybara helper', name
466
+ it_behaves_like 'valid allure helper', name
467
+ it_behaves_like 'valid video helper', name
468
+ it_behaves_like 'web-only video helper', name
469
+ it_behaves_like 'valid debug helper', name
470
+ end
471
+
472
+ # --- Mobile contexts (with AppiumRecorder) ---
473
+
474
+ context 'with cucumber and appium android' do
475
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::ANDROID}"
476
+ it_behaves_like 'valid video helper', name
477
+ it_behaves_like 'mobile video helper', name
478
+ end
479
+
480
+ context 'with rspec and appium ios' do
481
+ name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::IOS}"
482
+ it_behaves_like 'valid video helper', name
483
+ it_behaves_like 'mobile video helper', name
484
+ end
485
+ end