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,259 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'content_helper'
4
+
5
+ describe 'Page object content' do
6
+ # --- Login page ---
7
+
8
+ shared_examples 'valid login page' do |project_name|
9
+ subject(:login) { read_generated(project_name, 'page_objects/pages/login.rb') }
10
+
11
+ it 'has frozen_string_literal' do
12
+ expect(login).to have_frozen_string_literal
13
+ end
14
+
15
+ it 'has valid Ruby syntax' do
16
+ expect(login).to have_valid_ruby_syntax
17
+ end
18
+
19
+ it 'defines Login class inheriting from Page' do
20
+ expect(login).to match(/class Login < Page/)
21
+ end
22
+
23
+ it 'requires the abstract page' do
24
+ expect(login).to include("require_relative '../abstract/page'")
25
+ end
26
+
27
+ it 'defines a login method' do
28
+ expect(login).to match(/def login\(username, password\)/)
29
+ end
30
+
31
+ it 'defines a url method' do
32
+ expect(login).to match(/def url/)
33
+ end
34
+ end
35
+
36
+ shared_examples 'selenium login page' do |project_name|
37
+ subject(:login) { read_generated(project_name, 'page_objects/pages/login.rb') }
38
+
39
+ it 'uses find_element for elements' do
40
+ expect(login).to include('driver.find_element')
41
+ end
42
+
43
+ it 'uses send_keys for input' do
44
+ expect(login).to include('send_keys')
45
+ end
46
+
47
+ it 'has private element methods' do
48
+ expect(login).to include('private')
49
+ expect(login).to match(/def username_field/)
50
+ expect(login).to match(/def password_field/)
51
+ expect(login).to match(/def login_button/)
52
+ end
53
+
54
+ it 'does not include Capybara DSL' do
55
+ expect(login).not_to include('Capybara::DSL')
56
+ expect(login).not_to include('fill_in')
57
+ end
58
+
59
+ it 'does not include Watir methods' do
60
+ expect(login).not_to include('browser.text_field')
61
+ end
62
+ end
63
+
64
+ shared_examples 'watir login page' do |project_name|
65
+ subject(:login) { read_generated(project_name, 'page_objects/pages/login.rb') }
66
+
67
+ it 'uses browser methods for elements' do
68
+ expect(login).to include('browser.text_field')
69
+ expect(login).to include('browser.button')
70
+ end
71
+
72
+ it 'uses set for input' do
73
+ expect(login).to include('.set ')
74
+ end
75
+
76
+ it 'does not include Selenium methods' do
77
+ expect(login).not_to include('find_element')
78
+ expect(login).not_to include('send_keys')
79
+ end
80
+ end
81
+
82
+ shared_examples 'capybara login page' do |project_name|
83
+ subject(:login) { read_generated(project_name, 'page_objects/pages/login.rb') }
84
+
85
+ it 'uses fill_in for input' do
86
+ expect(login).to include('fill_in')
87
+ end
88
+
89
+ it 'uses click_button' do
90
+ expect(login).to include('click_button')
91
+ end
92
+
93
+ it 'has no private element methods' do
94
+ expect(login).not_to include('private')
95
+ expect(login).not_to match(/def username_field/)
96
+ end
97
+
98
+ it 'does not include Selenium methods' do
99
+ expect(login).not_to include('find_element')
100
+ expect(login).not_to include('send_keys')
101
+ end
102
+
103
+ it 'does not include Watir methods' do
104
+ expect(login).not_to include('browser.text_field')
105
+ end
106
+ end
107
+
108
+ # --- Abstract page ---
109
+
110
+ shared_examples 'valid abstract page' do |project_name|
111
+ subject(:page) { read_generated(project_name, 'page_objects/abstract/page.rb') }
112
+
113
+ it 'has valid Ruby syntax' do
114
+ expect(page).to have_valid_ruby_syntax
115
+ end
116
+
117
+ it 'defines Page class' do
118
+ expect(page).to match(/class Page/)
119
+ end
120
+
121
+ it 'defines to_s method' do
122
+ expect(page).to match(/def to_s/)
123
+ end
124
+ end
125
+
126
+ shared_examples 'selenium abstract page' do |project_name|
127
+ subject(:page) { read_generated(project_name, 'page_objects/abstract/page.rb') }
128
+
129
+ it 'has attr_reader :driver' do
130
+ expect(page).to include('attr_reader :driver')
131
+ end
132
+
133
+ it 'has initialize accepting driver' do
134
+ expect(page).to match(/def initialize\(driver\)/)
135
+ end
136
+
137
+ it 'has visit with driver.navigate' do
138
+ expect(page).to include('driver.navigate.to')
139
+ end
140
+
141
+ it 'does not include Capybara DSL' do
142
+ expect(page).not_to include('Capybara::DSL')
143
+ end
144
+ end
145
+
146
+ shared_examples 'watir abstract page' do |project_name|
147
+ subject(:page) { read_generated(project_name, 'page_objects/abstract/page.rb') }
148
+
149
+ it 'has attr_reader :browser' do
150
+ expect(page).to include('attr_reader :browser')
151
+ end
152
+
153
+ it 'has initialize accepting browser' do
154
+ expect(page).to match(/def initialize\(browser\)/)
155
+ end
156
+
157
+ it 'has visit with browser.goto' do
158
+ expect(page).to include('browser.goto')
159
+ end
160
+ end
161
+
162
+ shared_examples 'capybara abstract page' do |project_name|
163
+ subject(:page) { read_generated(project_name, 'page_objects/abstract/page.rb') }
164
+
165
+ it 'includes Capybara::DSL' do
166
+ expect(page).to include('include Capybara::DSL')
167
+ end
168
+
169
+ it 'uses visit_page method' do
170
+ expect(page).to match(/def visit_page/)
171
+ end
172
+
173
+ it 'uses Capybara.visit' do
174
+ expect(page).to include('Capybara.visit')
175
+ end
176
+
177
+ it 'does not have attr_reader :driver' do
178
+ expect(page).not_to include('attr_reader :driver')
179
+ end
180
+
181
+ it 'does not have initialize with driver' do
182
+ expect(page).not_to match(/def initialize\(driver\)/)
183
+ end
184
+ end
185
+
186
+ # --- Contexts ---
187
+
188
+ context 'with rspec and selenium' do
189
+ name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::SELENIUM}"
190
+ include_examples 'valid login page', name
191
+ include_examples 'selenium login page', name
192
+ include_examples 'valid abstract page', name
193
+ include_examples 'selenium abstract page', name
194
+ end
195
+
196
+ context 'with rspec and watir' do
197
+ name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::WATIR}"
198
+ include_examples 'valid login page', name
199
+ include_examples 'watir login page', name
200
+ include_examples 'valid abstract page', name
201
+ include_examples 'watir abstract page', name
202
+ end
203
+
204
+ context 'with rspec and capybara' do
205
+ name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::CAPYBARA}"
206
+ include_examples 'valid login page', name
207
+ include_examples 'capybara login page', name
208
+ include_examples 'valid abstract page', name
209
+ include_examples 'capybara abstract page', name
210
+ end
211
+
212
+ context 'with cucumber and selenium' do
213
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::SELENIUM}"
214
+ include_examples 'valid login page', name
215
+ include_examples 'selenium login page', name
216
+ include_examples 'valid abstract page', name
217
+ include_examples 'selenium abstract page', name
218
+ end
219
+
220
+ context 'with cucumber and watir' do
221
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::WATIR}"
222
+ include_examples 'valid login page', name
223
+ include_examples 'watir login page', name
224
+ include_examples 'valid abstract page', name
225
+ include_examples 'watir abstract page', name
226
+ end
227
+
228
+ context 'with cucumber and capybara' do
229
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::CAPYBARA}"
230
+ include_examples 'valid login page', name
231
+ include_examples 'capybara login page', name
232
+ include_examples 'valid abstract page', name
233
+ include_examples 'capybara abstract page', name
234
+ end
235
+
236
+ context 'with minitest and selenium' do
237
+ name = "#{FrameworkIndex::MINITEST}_#{AutomationIndex::SELENIUM}"
238
+ include_examples 'valid login page', name
239
+ include_examples 'selenium login page', name
240
+ include_examples 'valid abstract page', name
241
+ include_examples 'selenium abstract page', name
242
+ end
243
+
244
+ context 'with minitest and watir' do
245
+ name = "#{FrameworkIndex::MINITEST}_#{AutomationIndex::WATIR}"
246
+ include_examples 'valid login page', name
247
+ include_examples 'watir login page', name
248
+ include_examples 'valid abstract page', name
249
+ include_examples 'watir abstract page', name
250
+ end
251
+
252
+ context 'with minitest and capybara' do
253
+ name = "#{FrameworkIndex::MINITEST}_#{AutomationIndex::CAPYBARA}"
254
+ include_examples 'valid login page', name
255
+ include_examples 'capybara login page', name
256
+ include_examples 'valid abstract page', name
257
+ include_examples 'capybara abstract page', name
258
+ end
259
+ end
@@ -0,0 +1,236 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'content_helper'
4
+ require 'fileutils'
5
+
6
+ describe 'Reporter content validation' do
7
+ include InvokeGenerators
8
+
9
+ # Generate projects with different reporter configurations
10
+ before(:all) do # rubocop:disable RSpec/BeforeAfterAll
11
+ %w[allure junit both none].each do |reporter|
12
+ %w[rspec cucumber minitest].each do |framework|
13
+ name = "reporter_#{reporter}_#{framework}"
14
+ InvokeGenerators.generate_framework(
15
+ automation: 'selenium', framework:, name:, reporter:
16
+ )
17
+ end
18
+ end
19
+ end
20
+
21
+ after(:all) do # rubocop:disable RSpec/BeforeAfterAll
22
+ %w[allure junit both none].each do |reporter|
23
+ %w[rspec cucumber minitest].each do |framework|
24
+ FileUtils.rm_rf("reporter_#{reporter}_#{framework}")
25
+ end
26
+ end
27
+ end
28
+
29
+ # --- Shared examples ---
30
+
31
+ shared_examples 'project with allure' do |project_name|
32
+ it 'generates allure_helper.rb' do
33
+ expect(File).to exist("#{project_name}/helpers/allure_helper.rb")
34
+ end
35
+
36
+ it 'creates allure-results directory' do
37
+ expect(File).to exist("#{project_name}/allure-results")
38
+ end
39
+
40
+ it 'includes allure-results in .gitignore' do
41
+ gitignore = read_generated(project_name, '.gitignore')
42
+ expect(gitignore).to include('allure-results')
43
+ end
44
+ end
45
+
46
+ shared_examples 'project without allure' do |project_name|
47
+ it 'does not generate allure_helper.rb' do
48
+ expect(File).not_to exist("#{project_name}/helpers/allure_helper.rb")
49
+ end
50
+
51
+ it 'does not create allure-results directory' do
52
+ expect(File).not_to exist("#{project_name}/allure-results")
53
+ end
54
+
55
+ it 'does not include allure-results in .gitignore' do
56
+ gitignore = read_generated(project_name, '.gitignore')
57
+ expect(gitignore).not_to include('allure-results')
58
+ end
59
+ end
60
+
61
+ shared_examples 'rspec with allure reporter' do |project_name|
62
+ it 'includes allure gems in Gemfile' do
63
+ gemfile = read_generated(project_name, 'Gemfile')
64
+ expect(gemfile).to include("gem 'allure-rspec'")
65
+ expect(gemfile).to include("gem 'allure-ruby-commons'")
66
+ end
67
+
68
+ it 'references AllureHelper in spec_helper' do
69
+ helper = read_generated(project_name, 'helpers/spec_helper.rb')
70
+ expect(helper).to include("require_relative 'allure_helper'")
71
+ expect(helper).to include('AllureHelper.configure')
72
+ expect(helper).to include('config.formatter = AllureHelper.formatter')
73
+ end
74
+
75
+ it 'allure_helper has valid Ruby syntax' do
76
+ content = read_generated(project_name, 'helpers/allure_helper.rb')
77
+ expect(content).to have_valid_ruby_syntax
78
+ end
79
+ end
80
+
81
+ shared_examples 'rspec without allure reporter' do |project_name|
82
+ it 'does not include allure gems in Gemfile' do
83
+ gemfile = read_generated(project_name, 'Gemfile')
84
+ expect(gemfile).not_to include("gem 'allure-rspec'")
85
+ end
86
+
87
+ it 'does not reference AllureHelper in spec_helper' do
88
+ helper = read_generated(project_name, 'helpers/spec_helper.rb')
89
+ expect(helper).not_to include('AllureHelper')
90
+ end
91
+ end
92
+
93
+ shared_examples 'rspec with junit reporter' do |project_name|
94
+ it 'includes rspec_junit_formatter gem in Gemfile' do
95
+ gemfile = read_generated(project_name, 'Gemfile')
96
+ expect(gemfile).to include("gem 'rspec_junit_formatter'")
97
+ end
98
+
99
+ it 'configures junit formatter in spec_helper' do
100
+ helper = read_generated(project_name, 'helpers/spec_helper.rb')
101
+ expect(helper).to include("config.add_formatter('RspecJunitFormatter', 'results/junit.xml')")
102
+ end
103
+ end
104
+
105
+ shared_examples 'rspec without junit reporter' do |project_name|
106
+ it 'does not include rspec_junit_formatter gem in Gemfile' do
107
+ gemfile = read_generated(project_name, 'Gemfile')
108
+ expect(gemfile).not_to include("gem 'rspec_junit_formatter'")
109
+ end
110
+
111
+ it 'does not configure junit formatter in spec_helper' do
112
+ helper = read_generated(project_name, 'helpers/spec_helper.rb')
113
+ expect(helper).not_to include('RspecJunitFormatter')
114
+ end
115
+ end
116
+
117
+ shared_examples 'cucumber with allure reporter' do |project_name|
118
+ it 'includes allure-cucumber gem in Gemfile' do
119
+ gemfile = read_generated(project_name, 'Gemfile')
120
+ expect(gemfile).to include("gem 'allure-cucumber'")
121
+ end
122
+
123
+ it 'configures allure formatter in cucumber.yml' do
124
+ cucumber_yml = read_generated(project_name, 'cucumber.yml')
125
+ expect(cucumber_yml).to include('AllureCucumber::CucumberFormatter')
126
+ expect(cucumber_yml).to include('--out allure-results')
127
+ end
128
+ end
129
+
130
+ shared_examples 'cucumber without allure reporter' do |project_name|
131
+ it 'does not include allure-cucumber gem in Gemfile' do
132
+ gemfile = read_generated(project_name, 'Gemfile')
133
+ expect(gemfile).not_to include("gem 'allure-cucumber'")
134
+ end
135
+
136
+ it 'does not configure allure formatter in cucumber.yml' do
137
+ cucumber_yml = read_generated(project_name, 'cucumber.yml')
138
+ expect(cucumber_yml).not_to include('AllureCucumber')
139
+ end
140
+ end
141
+
142
+ shared_examples 'valid ruby files' do |project_name|
143
+ it 'generates spec_helper or test_helper with valid syntax' do
144
+ %w[helpers/spec_helper.rb helpers/test_helper.rb].each do |path|
145
+ file = File.join(project_name, path)
146
+ next unless File.exist?(file)
147
+
148
+ content = File.read(file)
149
+ expect(content).to have_valid_ruby_syntax
150
+ expect(content).to have_frozen_string_literal
151
+ end
152
+ end
153
+ end
154
+
155
+ # --- reporter: allure ---
156
+
157
+ context 'with reporter: allure' do
158
+ context 'and rspec' do
159
+ name = 'reporter_allure_rspec'
160
+ it_behaves_like 'project with allure', name
161
+ it_behaves_like 'rspec with allure reporter', name
162
+ it_behaves_like 'rspec without junit reporter', name
163
+ it_behaves_like 'valid ruby files', name
164
+ end
165
+
166
+ context 'and cucumber' do
167
+ name = 'reporter_allure_cucumber'
168
+ it_behaves_like 'project with allure', name
169
+ it_behaves_like 'cucumber with allure reporter', name
170
+ it_behaves_like 'valid ruby files', name
171
+ end
172
+ end
173
+
174
+ # --- reporter: junit ---
175
+
176
+ context 'with reporter: junit' do
177
+ context 'and rspec' do
178
+ name = 'reporter_junit_rspec'
179
+ it_behaves_like 'project without allure', name
180
+ it_behaves_like 'rspec without allure reporter', name
181
+ it_behaves_like 'rspec with junit reporter', name
182
+ it_behaves_like 'valid ruby files', name
183
+ end
184
+
185
+ context 'and cucumber' do
186
+ name = 'reporter_junit_cucumber'
187
+ it_behaves_like 'project without allure', name
188
+ it_behaves_like 'cucumber without allure reporter', name
189
+ it_behaves_like 'valid ruby files', name
190
+ end
191
+ end
192
+
193
+ # --- reporter: both ---
194
+
195
+ context 'with reporter: both' do
196
+ context 'and rspec' do
197
+ name = 'reporter_both_rspec'
198
+ it_behaves_like 'project with allure', name
199
+ it_behaves_like 'rspec with allure reporter', name
200
+ it_behaves_like 'rspec with junit reporter', name
201
+ it_behaves_like 'valid ruby files', name
202
+ end
203
+
204
+ context 'and cucumber' do
205
+ name = 'reporter_both_cucumber'
206
+ it_behaves_like 'project with allure', name
207
+ it_behaves_like 'cucumber with allure reporter', name
208
+ it_behaves_like 'valid ruby files', name
209
+ end
210
+ end
211
+
212
+ # --- reporter: none ---
213
+
214
+ context 'with reporter: none' do
215
+ context 'and rspec' do
216
+ name = 'reporter_none_rspec'
217
+ it_behaves_like 'project without allure', name
218
+ it_behaves_like 'rspec without allure reporter', name
219
+ it_behaves_like 'rspec without junit reporter', name
220
+ it_behaves_like 'valid ruby files', name
221
+ end
222
+
223
+ context 'and cucumber' do
224
+ name = 'reporter_none_cucumber'
225
+ it_behaves_like 'project without allure', name
226
+ it_behaves_like 'cucumber without allure reporter', name
227
+ it_behaves_like 'valid ruby files', name
228
+ end
229
+
230
+ context 'and minitest' do
231
+ name = 'reporter_none_minitest'
232
+ it_behaves_like 'project without allure', name
233
+ it_behaves_like 'valid ruby files', name
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'content_helper'
4
+ require 'fileutils'
5
+
6
+ describe 'Skip flags content validation' do
7
+ include InvokeGenerators
8
+
9
+ before(:all) do # rubocop:disable RSpec/BeforeAfterAll
10
+ {
11
+ 'skip_allure_content' => { skip_allure: true },
12
+ 'skip_video_content' => { skip_video: true },
13
+ 'skip_ci_content' => { skip_ci: true, ci_platform: 'github' },
14
+ 'skip_all_content' => { skip_allure: true, skip_video: true, skip_ci: true, ci_platform: 'github' }
15
+ }.each do |name, flags|
16
+ InvokeGenerators.generate_framework(
17
+ { automation: 'selenium', framework: 'rspec', name: }.merge(flags)
18
+ )
19
+ end
20
+ end
21
+
22
+ after(:all) do # rubocop:disable RSpec/BeforeAfterAll
23
+ %w[skip_allure_content skip_video_content skip_ci_content skip_all_content].each do |name|
24
+ FileUtils.rm_rf(name)
25
+ end
26
+ end
27
+
28
+ # --- skip_allure content validation ---
29
+
30
+ describe '--skip-allure file content' do
31
+ let(:name) { 'skip_allure_content' }
32
+
33
+ it 'Gemfile excludes allure gems' do
34
+ gemfile = read_generated(name, 'Gemfile')
35
+ expect(gemfile).not_to include('allure-rspec')
36
+ expect(gemfile).not_to include('allure-ruby-commons')
37
+ end
38
+
39
+ it 'Gemfile still includes core gems' do
40
+ gemfile = read_generated(name, 'Gemfile')
41
+ expect(gemfile).to include("gem 'rake'")
42
+ expect(gemfile).to include("gem 'rspec'")
43
+ expect(gemfile).to include("gem 'selenium-webdriver'")
44
+ expect(gemfile).to include("gem 'rspec-retry'")
45
+ end
46
+
47
+ it 'spec_helper does not reference AllureHelper' do
48
+ helper = read_generated(name, 'helpers/spec_helper.rb')
49
+ expect(helper).not_to include('AllureHelper')
50
+ expect(helper).not_to include('allure_helper')
51
+ end
52
+
53
+ it 'spec_helper still has retry config' do
54
+ helper = read_generated(name, 'helpers/spec_helper.rb')
55
+ expect(helper).to include("require 'rspec/retry'")
56
+ expect(helper).to include('config.verbose_retry = true')
57
+ expect(helper).to include("config.default_retry_count = ENV.fetch('RETRY_COUNT', 0).to_i")
58
+ end
59
+
60
+ it 'spec_helper has valid Ruby syntax' do
61
+ helper = read_generated(name, 'helpers/spec_helper.rb')
62
+ expect(helper).to have_valid_ruby_syntax
63
+ end
64
+
65
+ it '.gitignore excludes allure-results' do
66
+ gitignore = read_generated(name, '.gitignore')
67
+ expect(gitignore).not_to include('allure-results')
68
+ end
69
+
70
+ it '.gitignore still includes spec/examples.txt' do
71
+ gitignore = read_generated(name, '.gitignore')
72
+ expect(gitignore).to include('spec/examples.txt')
73
+ end
74
+
75
+ it 'Rakefile still has tag tasks' do
76
+ rakefile = read_generated(name, 'Rakefile')
77
+ expect(rakefile).to include('RakeTask.new(:smoke)')
78
+ expect(rakefile).to include('RakeTask.new(:regression)')
79
+ end
80
+
81
+ it '.rspec file still exists with correct content' do
82
+ rspec = read_generated(name, '.rspec')
83
+ expect(rspec).to include('--require helpers/spec_helper')
84
+ expect(rspec).to include('--format documentation')
85
+ end
86
+ end
87
+
88
+ # --- skip_video content validation ---
89
+
90
+ describe '--skip-video file content' do
91
+ let(:name) { 'skip_video_content' }
92
+
93
+ it 'spec_helper does not reference video_helper' do
94
+ helper = read_generated(name, 'helpers/spec_helper.rb')
95
+ expect(helper).not_to include('video_helper')
96
+ end
97
+
98
+ it 'spec_helper still includes AllureHelper' do
99
+ helper = read_generated(name, 'helpers/spec_helper.rb')
100
+ expect(helper).to include('AllureHelper')
101
+ end
102
+
103
+ it 'spec_helper has valid Ruby syntax' do
104
+ helper = read_generated(name, 'helpers/spec_helper.rb')
105
+ expect(helper).to have_valid_ruby_syntax
106
+ end
107
+
108
+ it 'Gemfile still includes allure gems' do
109
+ gemfile = read_generated(name, 'Gemfile')
110
+ expect(gemfile).to include("gem 'allure-rspec'")
111
+ end
112
+ end
113
+
114
+ # --- skip_ci content validation ---
115
+
116
+ describe '--skip-ci file content' do
117
+ let(:name) { 'skip_ci_content' }
118
+
119
+ it 'does not generate GitHub Actions directory' do
120
+ expect(File).not_to exist("#{name}/.github")
121
+ end
122
+
123
+ it 'still generates Gemfile with all gems' do
124
+ gemfile = read_generated(name, 'Gemfile')
125
+ expect(gemfile).to include("gem 'rspec'")
126
+ expect(gemfile).to include("gem 'allure-rspec'")
127
+ expect(gemfile).to include("gem 'rspec-retry'")
128
+ end
129
+
130
+ it 'still generates all helpers' do
131
+ expect(File).to exist("#{name}/helpers/spec_helper.rb")
132
+ expect(File).to exist("#{name}/helpers/allure_helper.rb")
133
+ expect(File).to exist("#{name}/helpers/video_helper.rb")
134
+ expect(File).to exist("#{name}/helpers/driver_helper.rb")
135
+ end
136
+ end
137
+
138
+ # --- all skip flags combined ---
139
+
140
+ describe 'all skip flags combined' do
141
+ let(:name) { 'skip_all_content' }
142
+
143
+ it 'Gemfile has no allure gems' do
144
+ gemfile = read_generated(name, 'Gemfile')
145
+ expect(gemfile).not_to include('allure')
146
+ end
147
+
148
+ it 'Gemfile still has core gems' do
149
+ gemfile = read_generated(name, 'Gemfile')
150
+ expect(gemfile).to include("gem 'rspec'")
151
+ expect(gemfile).to include("gem 'selenium-webdriver'")
152
+ expect(gemfile).to include("gem 'rspec-retry'")
153
+ end
154
+
155
+ it 'has no allure_helper.rb' do
156
+ expect(File).not_to exist("#{name}/helpers/allure_helper.rb")
157
+ end
158
+
159
+ it 'has no video_helper.rb' do
160
+ expect(File).not_to exist("#{name}/helpers/video_helper.rb")
161
+ end
162
+
163
+ it 'has no CI files' do
164
+ expect(File).not_to exist("#{name}/.github")
165
+ end
166
+
167
+ it 'spec_helper has no allure or video references' do
168
+ helper = read_generated(name, 'helpers/spec_helper.rb')
169
+ expect(helper).not_to include('AllureHelper')
170
+ expect(helper).not_to include('allure_helper')
171
+ expect(helper).not_to include('video_helper')
172
+ end
173
+
174
+ it 'spec_helper has valid Ruby syntax' do
175
+ helper = read_generated(name, 'helpers/spec_helper.rb')
176
+ expect(helper).to have_valid_ruby_syntax
177
+ end
178
+
179
+ it 'spec_helper still has retry and persistence config' do
180
+ helper = read_generated(name, 'helpers/spec_helper.rb')
181
+ expect(helper).to include("require 'rspec/retry'")
182
+ expect(helper).to include("config.example_status_persistence_file_path = 'spec/examples.txt'")
183
+ end
184
+
185
+ it 'Rakefile still has tag tasks' do
186
+ rakefile = read_generated(name, 'Rakefile')
187
+ expect(rakefile).to include('RakeTask.new(:smoke)')
188
+ end
189
+
190
+ it 'all generated .rb files have valid syntax' do
191
+ Dir.glob("#{name}/**/*.rb").each do |file|
192
+ content = File.read(file)
193
+ expect(content).to have_valid_ruby_syntax,
194
+ "#{file} has invalid Ruby syntax"
195
+ end
196
+ end
197
+
198
+ it 'all generated .rb files (except abstract) have frozen_string_literal' do
199
+ Dir.glob("#{name}/**/*.rb").reject { |f| f.include?('/abstract/') }.each do |file|
200
+ content = File.read(file)
201
+ expect(content).to have_frozen_string_literal,
202
+ "#{file} is missing frozen_string_literal"
203
+ end
204
+ end
205
+ end
206
+ end