ruby_raider 1.1.4 → 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.
- checksums.yaml +4 -4
- data/.github/workflows/e2e_tests.yml +58 -0
- data/.github/workflows/integration.yml +4 -6
- data/.github/workflows/reek.yml +6 -5
- data/.github/workflows/release.yml +175 -0
- data/.github/workflows/rubocop.yml +7 -6
- data/.github/workflows/steep.yml +21 -0
- data/.github/workflows/system_tests.yml +83 -0
- data/.gitignore +1 -1
- data/.reek.yml +46 -4
- data/.rubocop.yml +24 -0
- data/.ruby-version +1 -1
- data/README.md +140 -77
- data/RELEASE.md +412 -0
- data/RELEASE_QUICK_GUIDE.md +77 -0
- data/Steepfile +22 -0
- data/assets/ruby_raider_logo.svg +51 -0
- data/bin/release +186 -0
- data/lib/adopter/adopt_menu.rb +146 -0
- data/lib/adopter/converters/base_converter.rb +84 -0
- data/lib/adopter/converters/identity_converter.rb +53 -0
- data/lib/adopter/migration_plan.rb +74 -0
- data/lib/adopter/migrator.rb +96 -0
- data/lib/adopter/plan_builder.rb +275 -0
- data/lib/adopter/project_analyzer.rb +252 -0
- data/lib/adopter/project_detector.rb +157 -0
- data/lib/commands/adopt_commands.rb +42 -0
- data/lib/commands/plugin_commands.rb +0 -2
- data/lib/commands/scaffolding_commands.rb +220 -37
- data/lib/commands/utility_commands.rb +82 -2
- data/lib/generators/automation/automation_generator.rb +0 -7
- data/lib/generators/automation/templates/account.tt +9 -5
- data/lib/generators/automation/templates/appium_caps.tt +60 -6
- data/lib/generators/automation/templates/home.tt +4 -4
- data/lib/generators/automation/templates/login.tt +61 -4
- data/lib/generators/automation/templates/page.tt +13 -7
- data/lib/generators/automation/templates/partials/element.tt +1 -1
- data/lib/generators/automation/templates/partials/home_page_selector.tt +4 -4
- data/lib/generators/automation/templates/partials/initialize_selector.tt +3 -8
- data/lib/generators/automation/templates/partials/pdp_page_selector.tt +4 -4
- data/lib/generators/automation/templates/partials/url_methods.tt +0 -1
- data/lib/generators/automation/templates/partials/visit_method.tt +11 -1
- data/lib/generators/automation/templates/pdp.tt +1 -1
- data/lib/generators/common_generator.rb +12 -0
- data/lib/generators/cucumber/cucumber_generator.rb +36 -0
- data/lib/generators/cucumber/templates/accessibility_feature.tt +5 -0
- data/lib/generators/cucumber/templates/accessibility_steps.tt +21 -0
- data/lib/generators/cucumber/templates/cucumber.tt +8 -1
- data/lib/generators/cucumber/templates/env.tt +6 -4
- data/lib/generators/cucumber/templates/feature.tt +0 -4
- data/lib/generators/cucumber/templates/partials/appium_env.tt +5 -0
- data/lib/generators/cucumber/templates/partials/capybara_env.tt +38 -0
- data/lib/generators/cucumber/templates/partials/capybara_world.tt +6 -0
- data/lib/generators/cucumber/templates/partials/driver_world.tt +1 -4
- data/lib/generators/cucumber/templates/partials/mobile_steps.tt +2 -2
- data/lib/generators/cucumber/templates/partials/selenium_env.tt +22 -35
- data/lib/generators/cucumber/templates/partials/watir_env.tt +20 -1
- data/lib/generators/cucumber/templates/partials/web_steps.tt +10 -15
- data/lib/generators/cucumber/templates/performance_feature.tt +5 -0
- data/lib/generators/cucumber/templates/performance_steps.tt +17 -0
- data/lib/generators/cucumber/templates/steps.tt +2 -2
- data/lib/generators/cucumber/templates/visual_feature.tt +5 -0
- data/lib/generators/cucumber/templates/visual_steps.tt +19 -0
- data/lib/generators/cucumber/templates/world.tt +5 -3
- data/lib/generators/generator.rb +50 -7
- data/lib/generators/helper_generator.rb +39 -9
- data/lib/generators/infrastructure/github_generator.rb +6 -0
- data/lib/generators/infrastructure/templates/github.tt +12 -8
- data/lib/generators/infrastructure/templates/github_appium.tt +108 -0
- data/lib/generators/infrastructure/templates/gitlab.tt +6 -3
- data/lib/generators/invoke_generators.rb +43 -9
- data/lib/generators/menu_generator.rb +122 -11
- data/lib/generators/minitest/minitest_generator.rb +35 -0
- data/lib/generators/minitest/templates/accessibility_test.tt +26 -0
- data/lib/generators/minitest/templates/performance_test.tt +18 -0
- data/lib/generators/minitest/templates/test.tt +64 -0
- data/lib/generators/minitest/templates/visual_test.tt +23 -0
- data/lib/generators/rspec/rspec_generator.rb +16 -4
- data/lib/generators/rspec/templates/accessibility_spec.tt +25 -0
- data/lib/generators/rspec/templates/performance_spec.tt +18 -0
- data/lib/generators/rspec/templates/spec.tt +13 -41
- data/lib/generators/rspec/templates/visual_spec.tt +20 -0
- data/lib/generators/template_renderer/partial_cache.rb +126 -0
- data/lib/generators/template_renderer/partial_resolver.rb +110 -0
- data/lib/generators/template_renderer/template_error.rb +50 -0
- data/lib/generators/template_renderer.rb +106 -0
- data/lib/generators/templates/common/config.tt +2 -2
- data/lib/generators/templates/common/gemfile.tt +36 -9
- data/lib/generators/templates/common/git_ignore.tt +6 -1
- data/lib/generators/templates/common/partials/mobile_config.tt +5 -1
- data/lib/generators/templates/common/partials/web_config.tt +17 -8
- data/lib/generators/templates/common/rakefile.tt +36 -0
- data/lib/generators/templates/common/read_me.tt +43 -91
- data/lib/generators/templates/common/rspec.tt +3 -0
- data/lib/generators/templates/common/ruby_version.tt +1 -0
- data/lib/generators/templates/helpers/allure_helper.tt +13 -2
- data/lib/generators/templates/helpers/browser_helper.tt +13 -2
- data/lib/generators/templates/helpers/capybara_helper.tt +32 -0
- data/lib/generators/templates/helpers/debug_helper.tt +190 -0
- data/lib/generators/templates/helpers/driver_helper.tt +3 -11
- data/lib/generators/templates/helpers/partials/allure_imports.tt +3 -1
- data/lib/generators/templates/helpers/partials/allure_requirements.tt +3 -1
- data/lib/generators/templates/helpers/partials/appium_driver.tt +44 -0
- data/lib/generators/templates/helpers/partials/browserstack_config.tt +13 -0
- data/lib/generators/templates/helpers/partials/debug_diagnostics.tt +7 -0
- data/lib/generators/templates/helpers/partials/debug_start.tt +7 -0
- data/lib/generators/templates/helpers/partials/driver_and_options.tt +5 -115
- data/lib/generators/templates/helpers/partials/quit_driver.tt +3 -1
- data/lib/generators/templates/helpers/partials/screenshot.tt +3 -1
- data/lib/generators/templates/helpers/partials/selenium_driver.tt +26 -0
- data/lib/generators/templates/helpers/partials/video_start.tt +9 -0
- data/lib/generators/templates/helpers/partials/video_stop.tt +4 -0
- data/lib/generators/templates/helpers/performance_helper.tt +57 -0
- data/lib/generators/templates/helpers/spec_helper.tt +72 -10
- data/lib/generators/templates/helpers/test_helper.tt +94 -0
- data/lib/generators/templates/helpers/video_helper.tt +270 -0
- data/lib/generators/templates/helpers/visual_helper.tt +39 -46
- data/lib/llm/client.rb +79 -0
- data/lib/llm/config.rb +57 -0
- data/lib/llm/prompts.rb +84 -0
- data/lib/llm/provider.rb +27 -0
- data/lib/llm/providers/anthropic_provider.rb +43 -0
- data/lib/llm/providers/ollama_provider.rb +56 -0
- data/lib/llm/providers/openai_provider.rb +42 -0
- data/lib/llm/response_parser.rb +67 -0
- data/lib/plugin/plugin.rb +22 -20
- data/lib/plugin/plugin_exposer.rb +16 -38
- data/lib/ruby_raider.rb +51 -11
- data/lib/scaffolding/crud_generator.rb +94 -0
- data/lib/scaffolding/dry_run_presenter.rb +16 -0
- data/lib/scaffolding/name_normalizer.rb +63 -0
- data/lib/scaffolding/page_introspector.rb +45 -0
- data/lib/scaffolding/project_detector.rb +72 -0
- data/lib/scaffolding/scaffold_menu.rb +103 -0
- data/lib/scaffolding/scaffolding.rb +158 -11
- data/lib/scaffolding/templates/component.tt +30 -0
- data/lib/scaffolding/templates/feature.tt +4 -4
- data/lib/scaffolding/templates/helper.tt +15 -1
- data/lib/scaffolding/templates/page_from_url.tt +75 -0
- data/lib/scaffolding/templates/page_object.tt +50 -1
- data/lib/scaffolding/templates/spec.tt +33 -2
- data/lib/scaffolding/templates/spec_from_page.tt +31 -0
- data/lib/scaffolding/templates/spec_from_url.tt +46 -0
- data/lib/scaffolding/templates/steps.tt +17 -5
- data/lib/scaffolding/url_analyzer.rb +179 -0
- data/lib/utilities/desktop_downloader.rb +177 -0
- data/lib/utilities/logo.rb +83 -0
- data/lib/utilities/utilities.rb +53 -20
- data/lib/version +1 -1
- data/ruby_raider.gemspec +1 -0
- data/sig/adopter/adopt_menu.rbs +25 -0
- data/sig/adopter/converters/base_converter.rbs +23 -0
- data/sig/adopter/converters/identity_converter.rbs +16 -0
- data/sig/adopter/migration_plan.rbs +34 -0
- data/sig/adopter/migrator.rbs +21 -0
- data/sig/adopter/plan_builder.rbs +38 -0
- data/sig/adopter/project_analyzer.rbs +39 -0
- data/sig/adopter/project_detector.rbs +26 -0
- data/sig/commands/adopt_commands.rbs +8 -0
- data/sig/commands/loaded_commands.rbs +5 -0
- data/sig/commands/plugin_commands.rbs +9 -0
- data/sig/commands/scaffolding_commands.rbs +28 -0
- data/sig/commands/utility_commands.rbs +21 -0
- data/sig/generators/automation/automation_generator.rbs +20 -0
- data/sig/generators/common_generator.rbs +12 -0
- data/sig/generators/cucumber/cucumber_generator.rbs +16 -0
- data/sig/generators/generator.rbs +40 -0
- data/sig/generators/helper_generator.rbs +18 -0
- data/sig/generators/infrastructure/github_generator.rbs +5 -0
- data/sig/generators/infrastructure/gitlab_generator.rbs +4 -0
- data/sig/generators/invoke_generators.rbs +10 -0
- data/sig/generators/menu_generator.rbs +29 -0
- data/sig/generators/minitest/minitest_generator.rbs +8 -0
- data/sig/generators/rspec/rspec_generator.rbs +8 -0
- data/sig/generators/template_renderer/partial_cache.rbs +20 -0
- data/sig/generators/template_renderer/partial_resolver.rbs +20 -0
- data/sig/generators/template_renderer/template_error.rbs +19 -0
- data/sig/generators/template_renderer.rbs +10 -0
- data/sig/llm/client.rbs +15 -0
- data/sig/llm/config.rbs +20 -0
- data/sig/llm/prompts.rbs +8 -0
- data/sig/llm/provider.rbs +12 -0
- data/sig/llm/providers/anthropic_provider.rbs +16 -0
- data/sig/llm/providers/ollama_provider.rbs +18 -0
- data/sig/llm/providers/openai_provider.rbs +16 -0
- data/sig/llm/response_parser.rbs +13 -0
- data/sig/plugin/plugin.rbs +24 -0
- data/sig/plugin/plugin_exposer.rbs +20 -0
- data/sig/ruby_raider.rbs +15 -0
- data/sig/scaffolding/crud_generator.rbs +16 -0
- data/sig/scaffolding/dry_run_presenter.rbs +4 -0
- data/sig/scaffolding/name_normalizer.rbs +17 -0
- data/sig/scaffolding/page_introspector.rbs +14 -0
- data/sig/scaffolding/project_detector.rbs +14 -0
- data/sig/scaffolding/scaffold_menu.rbs +18 -0
- data/sig/scaffolding/scaffolding.rbs +55 -0
- data/sig/scaffolding/url_analyzer.rbs +28 -0
- data/sig/utilities/desktop_downloader.rbs +23 -0
- data/sig/utilities/logger.rbs +13 -0
- data/sig/utilities/logo.rbs +16 -0
- data/sig/utilities/utilities.rbs +30 -0
- data/sig/vendor/thor.rbs +34 -0
- data/sig/vendor/tty_prompt.rbs +15 -0
- data/spec/adopter/adopt_menu_spec.rb +176 -0
- data/spec/adopter/converters/identity_converter_spec.rb +145 -0
- data/spec/adopter/migration_plan_spec.rb +113 -0
- data/spec/adopter/migrator_spec.rb +277 -0
- data/spec/adopter/plan_builder_spec.rb +298 -0
- data/spec/adopter/project_analyzer_spec.rb +337 -0
- data/spec/adopter/project_detector_spec.rb +295 -0
- data/spec/commands/raider_commands_spec.rb +129 -0
- data/spec/generators/fixtures/templates/test.tt +1 -0
- data/spec/generators/fixtures/templates/test_partial.tt +1 -0
- data/spec/generators/generator_spec.rb +23 -0
- data/spec/generators/template_renderer_spec.rb +298 -0
- data/spec/integration/commands/scaffolding_commands_spec.rb +2 -2
- data/spec/integration/commands/utility_commands_spec.rb +24 -4
- data/spec/integration/content/ci_content_spec.rb +119 -0
- data/spec/integration/content/common_content_spec.rb +288 -0
- data/spec/integration/content/config_content_spec.rb +175 -0
- data/spec/integration/content/content_helper.rb +32 -0
- data/spec/integration/content/gemfile_content_spec.rb +209 -0
- data/spec/integration/content/helper_content_spec.rb +485 -0
- data/spec/integration/content/page_content_spec.rb +259 -0
- data/spec/integration/content/reporter_content_spec.rb +236 -0
- data/spec/integration/content/skip_flags_content_spec.rb +206 -0
- data/spec/integration/content/syntax_validation_spec.rb +30 -0
- data/spec/integration/content/test_content_spec.rb +266 -0
- data/spec/integration/end_to_end_features_spec.rb +690 -0
- data/spec/integration/end_to_end_spec.rb +361 -0
- data/spec/integration/generators/automation_generator_spec.rb +9 -21
- data/spec/integration/generators/axe_addon_spec.rb +150 -0
- data/spec/integration/generators/common_generator_spec.rb +48 -49
- data/spec/integration/generators/config_features_spec.rb +155 -0
- data/spec/integration/generators/cucumber_generator_spec.rb +7 -7
- data/spec/integration/generators/debug_helper_spec.rb +68 -0
- data/spec/integration/generators/github_generator_spec.rb +8 -8
- data/spec/integration/generators/gitlab_generator_spec.rb +8 -8
- data/spec/integration/generators/helpers_generator_spec.rb +70 -44
- data/spec/integration/generators/lighthouse_addon_spec.rb +132 -0
- data/spec/integration/generators/minitest_generator_spec.rb +64 -0
- data/spec/integration/generators/reporter_spec.rb +159 -0
- data/spec/integration/generators/rspec_generator_spec.rb +7 -7
- data/spec/integration/generators/skip_flags_spec.rb +134 -0
- data/spec/integration/generators/visual_addon_spec.rb +148 -0
- data/spec/integration/settings_helper.rb +1 -4
- data/spec/integration/spec_helper.rb +46 -11
- data/spec/llm/client_spec.rb +79 -0
- data/spec/llm/config_spec.rb +92 -0
- data/spec/llm/prompts_spec.rb +49 -0
- data/spec/llm/response_parser_spec.rb +92 -0
- data/spec/menus/adopter_adopt_menu_spec.rb +97 -0
- data/spec/menus/menu_generator_spec.rb +263 -0
- data/spec/scaffolding/name_normalizer_spec.rb +113 -0
- data/spec/scaffolding/page_introspector_spec.rb +82 -0
- data/spec/scaffolding/scaffold_project_detector_spec.rb +104 -0
- data/spec/scaffolding/scaffolding_features_spec.rb +311 -0
- data/spec/scaffolding/url_analyzer_spec.rb +110 -0
- data/spec/system/adopt_matrix_spec.rb +537 -0
- data/spec/system/adopt_spec.rb +225 -0
- data/spec/system/capybara_spec.rb +42 -0
- data/spec/system/selenium_spec.rb +19 -17
- data/spec/system/support/system_test_helper.rb +33 -0
- data/spec/system/watir_spec.rb +19 -17
- data/spec/utilities/desktop_downloader_spec.rb +92 -0
- metadata +193 -18
- data/.github/workflows/push_gem.yml +0 -37
- data/.github/workflows/selenium.yml +0 -22
- data/.github/workflows/watir.yml +0 -22
- data/lib/generators/automation/templates/partials/android_caps.tt +0 -17
- data/lib/generators/automation/templates/partials/cross_platform_caps.tt +0 -25
- data/lib/generators/automation/templates/partials/ios_caps.tt +0 -18
- data/lib/generators/automation/templates/partials/selenium_account.tt +0 -9
- data/lib/generators/automation/templates/partials/selenium_login.tt +0 -34
- data/lib/generators/automation/templates/partials/watir_account.tt +0 -7
- data/lib/generators/automation/templates/partials/watir_login.tt +0 -32
- data/lib/generators/automation/templates/visual_options.tt +0 -16
- data/lib/generators/templates/helpers/visual_spec_helper.tt +0 -35
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'spec_helper'
|
|
4
|
+
require 'timeout'
|
|
5
|
+
require 'open3'
|
|
6
|
+
|
|
7
|
+
# End-to-end integration tests that verify generated projects actually work
|
|
8
|
+
# These tests:
|
|
9
|
+
# 1. Generate a complete project
|
|
10
|
+
# 2. Install dependencies (bundle install)
|
|
11
|
+
# 3. Run the generated tests (rspec/cucumber)
|
|
12
|
+
# 4. Verify tests pass
|
|
13
|
+
#
|
|
14
|
+
# This ensures the template system produces working, executable test frameworks
|
|
15
|
+
describe 'End-to-End Project Generation and Execution' do
|
|
16
|
+
# Helper to run commands in a generated project directory
|
|
17
|
+
def run_in_project(project_name, command, timeout: 300)
|
|
18
|
+
result = {
|
|
19
|
+
success: false,
|
|
20
|
+
stdout: '',
|
|
21
|
+
stderr: '',
|
|
22
|
+
exit_code: nil
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Dir.chdir(project_name) do
|
|
26
|
+
Bundler.with_unbundled_env do
|
|
27
|
+
Timeout.timeout(timeout) do
|
|
28
|
+
stdout, stderr, status = Open3.capture3(command)
|
|
29
|
+
result[:stdout] = stdout
|
|
30
|
+
result[:stderr] = stderr
|
|
31
|
+
result[:exit_code] = status.exitstatus
|
|
32
|
+
result[:success] = status.success?
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
result
|
|
38
|
+
rescue Timeout::Error
|
|
39
|
+
result[:stderr] = "Command timed out after #{timeout} seconds"
|
|
40
|
+
result[:exit_code] = -1
|
|
41
|
+
result
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Helper to install dependencies
|
|
45
|
+
def bundle_install(project_name)
|
|
46
|
+
puts "\n📦 Installing dependencies for #{project_name}..."
|
|
47
|
+
result = run_in_project(project_name, 'bundle install --quiet', timeout: 180)
|
|
48
|
+
|
|
49
|
+
unless result[:success]
|
|
50
|
+
puts '❌ Bundle install failed:'
|
|
51
|
+
puts result[:stderr]
|
|
52
|
+
puts result[:stdout]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
result[:success]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Helper to run RSpec tests
|
|
59
|
+
def run_rspec(project_name)
|
|
60
|
+
puts "\n🧪 Running RSpec tests in #{project_name}..."
|
|
61
|
+
result = run_in_project(project_name, 'bundle exec rspec spec/ --format documentation', timeout: 120)
|
|
62
|
+
|
|
63
|
+
puts result[:stdout] if result[:stdout].length.positive?
|
|
64
|
+
|
|
65
|
+
unless result[:success]
|
|
66
|
+
puts '❌ RSpec tests failed:'
|
|
67
|
+
puts result[:stderr] if result[:stderr].length.positive?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
result
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Helper to run Cucumber tests
|
|
74
|
+
def run_cucumber(project_name)
|
|
75
|
+
puts "\n🥒 Running Cucumber tests in #{project_name}..."
|
|
76
|
+
result = run_in_project(project_name, 'bundle exec cucumber features/ --format pretty', timeout: 120)
|
|
77
|
+
|
|
78
|
+
puts result[:stdout] if result[:stdout].length.positive?
|
|
79
|
+
|
|
80
|
+
unless result[:success]
|
|
81
|
+
puts '❌ Cucumber tests failed:'
|
|
82
|
+
puts result[:stderr] if result[:stderr].length.positive?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
result
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Helper to run Minitest tests
|
|
89
|
+
def run_minitest(project_name)
|
|
90
|
+
puts "\nRunning Minitest tests in #{project_name}..."
|
|
91
|
+
result = run_in_project(project_name, 'bundle exec ruby -Itest test/test_login_page.rb', timeout: 120)
|
|
92
|
+
|
|
93
|
+
puts result[:stdout] if result[:stdout].length.positive?
|
|
94
|
+
|
|
95
|
+
unless result[:success]
|
|
96
|
+
puts 'Minitest tests failed:'
|
|
97
|
+
puts result[:stderr] if result[:stderr].length.positive?
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
result
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Shared example for RSpec-based projects
|
|
104
|
+
shared_examples 'executable rspec project' do |project_name|
|
|
105
|
+
let(:project) { project_name }
|
|
106
|
+
|
|
107
|
+
it 'installs dependencies successfully' do
|
|
108
|
+
expect(bundle_install(project)).to be true
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'runs generated RSpec tests successfully', :slow do
|
|
112
|
+
skip 'Bundle install failed' unless bundle_install(project)
|
|
113
|
+
|
|
114
|
+
result = run_rspec(project)
|
|
115
|
+
|
|
116
|
+
expect(result[:success]).to be(true),
|
|
117
|
+
"RSpec tests failed with exit code #{result[:exit_code]}.\n" \
|
|
118
|
+
"STDOUT: #{result[:stdout]}\n" \
|
|
119
|
+
"STDERR: #{result[:stderr]}"
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Shared example for Cucumber-based projects
|
|
124
|
+
shared_examples 'executable cucumber project' do |project_name|
|
|
125
|
+
let(:project) { project_name }
|
|
126
|
+
|
|
127
|
+
it 'installs dependencies successfully' do
|
|
128
|
+
expect(bundle_install(project)).to be true
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'runs generated Cucumber tests successfully', :slow do
|
|
132
|
+
skip 'Bundle install failed' unless bundle_install(project)
|
|
133
|
+
|
|
134
|
+
result = run_cucumber(project)
|
|
135
|
+
|
|
136
|
+
expect(result[:success]).to be(true),
|
|
137
|
+
"Cucumber tests failed with exit code #{result[:exit_code]}.\n" \
|
|
138
|
+
"STDOUT: #{result[:stdout]}\n" \
|
|
139
|
+
"STDERR: #{result[:stderr]}"
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Shared example for Minitest-based projects
|
|
144
|
+
shared_examples 'executable minitest project' do |project_name|
|
|
145
|
+
let(:project) { project_name }
|
|
146
|
+
|
|
147
|
+
it 'installs dependencies successfully' do
|
|
148
|
+
expect(bundle_install(project)).to be true
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it 'runs generated Minitest tests successfully', :slow do
|
|
152
|
+
skip 'Bundle install failed' unless bundle_install(project)
|
|
153
|
+
|
|
154
|
+
result = run_minitest(project)
|
|
155
|
+
|
|
156
|
+
expect(result[:success]).to be(true),
|
|
157
|
+
"Minitest tests failed with exit code #{result[:exit_code]}.\n" \
|
|
158
|
+
"STDOUT: #{result[:stdout]}\n" \
|
|
159
|
+
"STDERR: #{result[:stderr]}"
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Test Web Frameworks (these can run without external services)
|
|
164
|
+
context 'Web Automation Frameworks' do
|
|
165
|
+
describe 'Selenium + RSpec' do
|
|
166
|
+
include_examples 'executable rspec project', 'rspec_selenium'
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
describe 'Watir + RSpec' do
|
|
170
|
+
include_examples 'executable rspec project', 'rspec_watir'
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
describe 'Capybara + RSpec' do
|
|
174
|
+
include_examples 'executable rspec project', 'rspec_capybara'
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
describe 'Selenium + Cucumber' do
|
|
178
|
+
include_examples 'executable cucumber project', 'cucumber_selenium'
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
describe 'Watir + Cucumber' do
|
|
182
|
+
include_examples 'executable cucumber project', 'cucumber_watir'
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
describe 'Capybara + Cucumber' do
|
|
186
|
+
include_examples 'executable cucumber project', 'cucumber_capybara'
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
describe 'Selenium + Minitest' do
|
|
190
|
+
include_examples 'executable minitest project', 'minitest_selenium'
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
describe 'Watir + Minitest' do
|
|
194
|
+
include_examples 'executable minitest project', 'minitest_watir'
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
describe 'Capybara + Minitest' do
|
|
198
|
+
include_examples 'executable minitest project', 'minitest_capybara'
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Mobile and Visual frameworks require external services, so we only verify structure
|
|
203
|
+
context 'Mobile Automation Frameworks (structure validation only)' do
|
|
204
|
+
describe 'iOS + RSpec' do
|
|
205
|
+
it 'generates valid project structure' do
|
|
206
|
+
expect(File).to exist('rspec_ios/helpers/spec_helper.rb')
|
|
207
|
+
expect(File).to exist('rspec_ios/Gemfile')
|
|
208
|
+
expect(File).to exist('rspec_ios/spec')
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it 'has valid Ruby syntax in generated files' do
|
|
212
|
+
result = run_in_project('rspec_ios', 'ruby -c helpers/spec_helper.rb')
|
|
213
|
+
expect(result[:success]).to be true
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
describe 'iOS + Cucumber' do
|
|
218
|
+
it 'generates valid project structure' do
|
|
219
|
+
expect(File).to exist('cucumber_ios/features/support/env.rb')
|
|
220
|
+
expect(File).to exist('cucumber_ios/Gemfile')
|
|
221
|
+
expect(File).to exist('cucumber_ios/features')
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it 'has valid Ruby syntax in generated files' do
|
|
225
|
+
result = run_in_project('cucumber_ios', 'ruby -c features/support/env.rb')
|
|
226
|
+
expect(result[:success]).to be true
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
describe 'Android + RSpec' do
|
|
231
|
+
it 'generates valid project structure' do
|
|
232
|
+
expect(File).to exist('rspec_android/helpers/spec_helper.rb')
|
|
233
|
+
expect(File).to exist('rspec_android/Gemfile')
|
|
234
|
+
expect(File).to exist('rspec_android/spec')
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
it 'has valid Ruby syntax in generated files' do
|
|
238
|
+
result = run_in_project('rspec_android', 'ruby -c helpers/spec_helper.rb')
|
|
239
|
+
expect(result[:success]).to be true
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
describe 'Android + Cucumber' do
|
|
244
|
+
it 'generates valid project structure' do
|
|
245
|
+
expect(File).to exist('cucumber_android/features/support/env.rb')
|
|
246
|
+
expect(File).to exist('cucumber_android/Gemfile')
|
|
247
|
+
expect(File).to exist('cucumber_android/features')
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it 'has valid Ruby syntax in generated files' do
|
|
251
|
+
result = run_in_project('cucumber_android', 'ruby -c features/support/env.rb')
|
|
252
|
+
expect(result[:success]).to be true
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
describe 'Cross-Platform + RSpec' do
|
|
257
|
+
it 'generates valid project structure' do
|
|
258
|
+
expect(File).to exist('rspec_cross_platform/helpers/appium_helper.rb')
|
|
259
|
+
expect(File).to exist('rspec_cross_platform/Gemfile')
|
|
260
|
+
expect(File).to exist('rspec_cross_platform/spec')
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it 'has valid Ruby syntax in generated files' do
|
|
264
|
+
result = run_in_project('rspec_cross_platform', 'ruby -c helpers/spec_helper.rb')
|
|
265
|
+
expect(result[:success]).to be true
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
describe 'Cross-Platform + Cucumber' do
|
|
270
|
+
it 'generates valid project structure' do
|
|
271
|
+
expect(File).to exist('cucumber_cross_platform/helpers/appium_helper.rb')
|
|
272
|
+
expect(File).to exist('cucumber_cross_platform/Gemfile')
|
|
273
|
+
expect(File).to exist('cucumber_cross_platform/features')
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it 'has valid Ruby syntax in generated files' do
|
|
277
|
+
result = run_in_project('cucumber_cross_platform', 'ruby -c features/support/env.rb')
|
|
278
|
+
expect(result[:success]).to be true
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
context 'Minitest Mobile Frameworks (structure validation only)' do
|
|
284
|
+
describe 'Android + Minitest' do
|
|
285
|
+
it 'generates valid project structure' do
|
|
286
|
+
expect(File).to exist('minitest_android/helpers/test_helper.rb')
|
|
287
|
+
expect(File).to exist('minitest_android/Gemfile')
|
|
288
|
+
expect(File).to exist('minitest_android/test')
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it 'has valid Ruby syntax in generated files' do
|
|
292
|
+
result = run_in_project('minitest_android', 'ruby -c helpers/test_helper.rb')
|
|
293
|
+
expect(result[:success]).to be true
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
describe 'iOS + Minitest' do
|
|
298
|
+
it 'generates valid project structure' do
|
|
299
|
+
expect(File).to exist('minitest_ios/helpers/test_helper.rb')
|
|
300
|
+
expect(File).to exist('minitest_ios/Gemfile')
|
|
301
|
+
expect(File).to exist('minitest_ios/test')
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it 'has valid Ruby syntax in generated files' do
|
|
305
|
+
result = run_in_project('minitest_ios', 'ruby -c helpers/test_helper.rb')
|
|
306
|
+
expect(result[:success]).to be true
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
describe 'Cross-Platform + Minitest' do
|
|
311
|
+
it 'generates valid project structure' do
|
|
312
|
+
expect(File).to exist('minitest_cross_platform/helpers/test_helper.rb')
|
|
313
|
+
expect(File).to exist('minitest_cross_platform/helpers/appium_helper.rb')
|
|
314
|
+
expect(File).to exist('minitest_cross_platform/Gemfile')
|
|
315
|
+
expect(File).to exist('minitest_cross_platform/test')
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it 'has valid Ruby syntax in generated files' do
|
|
319
|
+
result = run_in_project('minitest_cross_platform', 'ruby -c helpers/test_helper.rb')
|
|
320
|
+
expect(result[:success]).to be true
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# Verify template system performance (caching working)
|
|
326
|
+
context 'Template System Performance' do
|
|
327
|
+
it 'benefits from template caching on second generation' do
|
|
328
|
+
require_relative '../../lib/generators/generator'
|
|
329
|
+
|
|
330
|
+
# Clear cache
|
|
331
|
+
Generator.clear_template_cache
|
|
332
|
+
|
|
333
|
+
# First generation (cache miss)
|
|
334
|
+
start_time = Time.now
|
|
335
|
+
settings1 = create_settings(framework: 'rspec', automation: 'selenium')
|
|
336
|
+
settings1[:name] = 'test_cache_1'
|
|
337
|
+
generate_framework(settings1)
|
|
338
|
+
first_duration = Time.now - start_time
|
|
339
|
+
|
|
340
|
+
# Second generation (cache hit)
|
|
341
|
+
start_time = Time.now
|
|
342
|
+
settings2 = create_settings(framework: 'rspec', automation: 'selenium')
|
|
343
|
+
settings2[:name] = 'test_cache_2'
|
|
344
|
+
generate_framework(settings2)
|
|
345
|
+
second_duration = Time.now - start_time
|
|
346
|
+
|
|
347
|
+
# Second generation should be faster (or similar if I/O dominates)
|
|
348
|
+
# At minimum, cache should not slow things down
|
|
349
|
+
expect(second_duration).to be <= (first_duration * 1.2)
|
|
350
|
+
|
|
351
|
+
# Cleanup
|
|
352
|
+
FileUtils.rm_rf('test_cache_1')
|
|
353
|
+
FileUtils.rm_rf('test_cache_2')
|
|
354
|
+
|
|
355
|
+
# Verify cache has entries
|
|
356
|
+
stats = Generator.template_cache_stats
|
|
357
|
+
expect(stats[:size]).to be > 0
|
|
358
|
+
puts "\n📊 Template cache: #{stats[:size]} entries, ~#{stats[:memory_estimate] / 1024}KB"
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
end
|
|
@@ -36,51 +36,39 @@ describe AutomationGenerator do
|
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
shared_examples 'creates web visual framework' do |name|
|
|
40
|
-
it 'creates a login page file' do
|
|
41
|
-
expect(File).to exist("#{name}/page_objects/pages/login.rb")
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it 'creates an abstract page file' do
|
|
45
|
-
expect(File).to exist("#{name}/page_objects/abstract/page.rb")
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
39
|
context 'with rspec and selenium' do
|
|
50
|
-
include_examples 'creates web automation framework', "#{
|
|
51
|
-
include_examples 'creates web visual framework', "#{FRAMEWORKS.last}_#{AUTOMATION_TYPES.last}"
|
|
40
|
+
include_examples 'creates web automation framework', "#{FrameworkIndex::RSPEC}_#{AutomationIndex::SELENIUM}"
|
|
52
41
|
end
|
|
53
42
|
|
|
54
43
|
context 'with rspec and watir' do
|
|
55
|
-
include_examples 'creates web automation framework', "#{
|
|
44
|
+
include_examples 'creates web automation framework', "#{FrameworkIndex::RSPEC}_#{AutomationIndex::WATIR}"
|
|
56
45
|
end
|
|
57
46
|
|
|
58
47
|
context 'with cucumber and selenium' do
|
|
59
|
-
include_examples 'creates web automation framework', "#{
|
|
60
|
-
include_examples 'creates web visual framework', "#{FRAMEWORKS.first}_#{AUTOMATION_TYPES.last}"
|
|
48
|
+
include_examples 'creates web automation framework', "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::SELENIUM}"
|
|
61
49
|
end
|
|
62
50
|
|
|
63
51
|
context 'with cucumber and watir' do
|
|
64
|
-
include_examples 'creates web automation framework', "#{
|
|
52
|
+
include_examples 'creates web automation framework', "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::WATIR}"
|
|
65
53
|
end
|
|
66
54
|
|
|
67
55
|
context 'with rspec and appium android' do
|
|
68
|
-
include_examples 'creates mobile automation framework', "#{
|
|
56
|
+
include_examples 'creates mobile automation framework', "#{FrameworkIndex::RSPEC}_#{AutomationIndex::ANDROID}"
|
|
69
57
|
end
|
|
70
58
|
|
|
71
59
|
context 'with rspec and appium ios' do
|
|
72
|
-
include_examples 'creates mobile automation framework', "#{
|
|
60
|
+
include_examples 'creates mobile automation framework', "#{FrameworkIndex::RSPEC}_#{AutomationIndex::IOS}"
|
|
73
61
|
end
|
|
74
62
|
|
|
75
63
|
context 'with cucumber and appium android' do
|
|
76
|
-
include_examples 'creates mobile automation framework', "#{
|
|
64
|
+
include_examples 'creates mobile automation framework', "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::ANDROID}"
|
|
77
65
|
end
|
|
78
66
|
|
|
79
67
|
context 'with cucumber and appium ios' do
|
|
80
|
-
include_examples 'creates mobile automation framework', "#{
|
|
68
|
+
include_examples 'creates mobile automation framework', "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::IOS}"
|
|
81
69
|
end
|
|
82
70
|
|
|
83
71
|
context 'with cucumber and appium cross platform' do
|
|
84
|
-
include_examples 'creates mobile automation framework', "#{
|
|
72
|
+
include_examples 'creates mobile automation framework', "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::CROSS_PLATFORM}"
|
|
85
73
|
end
|
|
86
74
|
end
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require_relative '../../../lib/generators/invoke_generators'
|
|
5
|
+
require_relative '../settings_helper'
|
|
6
|
+
|
|
7
|
+
describe 'Axe accessibility addon generation' do
|
|
8
|
+
include InvokeGenerators
|
|
9
|
+
include SettingsHelper
|
|
10
|
+
|
|
11
|
+
# rubocop:disable RSpec/BeforeAfterAll, RSpec/InstanceVariable
|
|
12
|
+
before(:all) do
|
|
13
|
+
@axe_projects = []
|
|
14
|
+
%w[rspec cucumber minitest].each do |framework|
|
|
15
|
+
%w[selenium watir capybara].each do |automation|
|
|
16
|
+
name = "axe_#{framework}_#{automation}"
|
|
17
|
+
@axe_projects << name
|
|
18
|
+
InvokeGenerators.generate_framework(
|
|
19
|
+
automation:, framework:, name:, accessibility: true
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
after(:all) do
|
|
26
|
+
@axe_projects.each { |name| FileUtils.rm_rf(name) }
|
|
27
|
+
end
|
|
28
|
+
# rubocop:enable RSpec/BeforeAfterAll, RSpec/InstanceVariable
|
|
29
|
+
|
|
30
|
+
context 'with rspec and selenium' do
|
|
31
|
+
let(:name) { 'axe_rspec_selenium' }
|
|
32
|
+
|
|
33
|
+
it 'creates accessibility_spec.rb' do
|
|
34
|
+
expect(File).to exist("#{name}/spec/accessibility_spec.rb")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'includes axe gems in Gemfile' do
|
|
38
|
+
gemfile = File.read("#{name}/Gemfile")
|
|
39
|
+
expect(gemfile).to include('axe')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'accessibility spec has valid Ruby syntax' do
|
|
43
|
+
content = File.read("#{name}/spec/accessibility_spec.rb")
|
|
44
|
+
expect { RubyVM::InstructionSequence.compile(content) }.not_to raise_error
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context 'with cucumber and selenium' do
|
|
49
|
+
let(:name) { 'axe_cucumber_selenium' }
|
|
50
|
+
|
|
51
|
+
it 'creates accessibility.feature' do
|
|
52
|
+
expect(File).to exist("#{name}/features/accessibility.feature")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'creates accessibility_steps.rb' do
|
|
56
|
+
expect(File).to exist("#{name}/features/step_definitions/accessibility_steps.rb")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'includes axe gems in Gemfile' do
|
|
60
|
+
gemfile = File.read("#{name}/Gemfile")
|
|
61
|
+
expect(gemfile).to include('axe')
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'with minitest and selenium' do
|
|
66
|
+
let(:name) { 'axe_minitest_selenium' }
|
|
67
|
+
|
|
68
|
+
it 'creates test_accessibility.rb' do
|
|
69
|
+
expect(File).to exist("#{name}/test/test_accessibility.rb")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'includes axe gems in Gemfile' do
|
|
73
|
+
gemfile = File.read("#{name}/Gemfile")
|
|
74
|
+
expect(gemfile).to include('axe')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'accessibility test has valid Ruby syntax' do
|
|
78
|
+
content = File.read("#{name}/test/test_accessibility.rb")
|
|
79
|
+
expect { RubyVM::InstructionSequence.compile(content) }.not_to raise_error
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context 'with rspec and watir' do
|
|
84
|
+
let(:name) { 'axe_rspec_watir' }
|
|
85
|
+
|
|
86
|
+
it 'creates accessibility_spec.rb' do
|
|
87
|
+
expect(File).to exist("#{name}/spec/accessibility_spec.rb")
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context 'with rspec and capybara' do
|
|
92
|
+
let(:name) { 'axe_rspec_capybara' }
|
|
93
|
+
|
|
94
|
+
it 'creates accessibility_spec.rb' do
|
|
95
|
+
expect(File).to exist("#{name}/spec/accessibility_spec.rb")
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
context 'with cucumber and watir' do
|
|
100
|
+
let(:name) { 'axe_cucumber_watir' }
|
|
101
|
+
|
|
102
|
+
it 'creates accessibility.feature' do
|
|
103
|
+
expect(File).to exist("#{name}/features/accessibility.feature")
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context 'with cucumber and capybara' do
|
|
108
|
+
let(:name) { 'axe_cucumber_capybara' }
|
|
109
|
+
|
|
110
|
+
it 'creates accessibility.feature' do
|
|
111
|
+
expect(File).to exist("#{name}/features/accessibility.feature")
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
context 'with minitest and watir' do
|
|
116
|
+
let(:name) { 'axe_minitest_watir' }
|
|
117
|
+
|
|
118
|
+
it 'creates test_accessibility.rb' do
|
|
119
|
+
expect(File).to exist("#{name}/test/test_accessibility.rb")
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
context 'with minitest and capybara' do
|
|
124
|
+
let(:name) { 'axe_minitest_capybara' }
|
|
125
|
+
|
|
126
|
+
it 'creates test_accessibility.rb' do
|
|
127
|
+
expect(File).to exist("#{name}/test/test_accessibility.rb")
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context 'without accessibility flag' do
|
|
132
|
+
let(:name) { 'no_axe_rspec_selenium' }
|
|
133
|
+
|
|
134
|
+
# rubocop:disable RSpec/BeforeAfterAll
|
|
135
|
+
before(:all) do
|
|
136
|
+
InvokeGenerators.generate_framework(
|
|
137
|
+
automation: 'selenium', framework: 'rspec', name: 'no_axe_rspec_selenium'
|
|
138
|
+
)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
after(:all) do
|
|
142
|
+
FileUtils.rm_rf('no_axe_rspec_selenium')
|
|
143
|
+
end
|
|
144
|
+
# rubocop:enable RSpec/BeforeAfterAll
|
|
145
|
+
|
|
146
|
+
it 'does not create accessibility_spec.rb' do
|
|
147
|
+
expect(File).not_to exist("#{name}/spec/accessibility_spec.rb")
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|