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
|
@@ -1,30 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Uncomment for interactive debugging:
|
|
4
|
+
# require 'debug' # Ruby's built-in debugger (binding.break)
|
|
5
|
+
# require 'pry' # Pry debugger (binding.pry)
|
|
6
|
+
|
|
3
7
|
require_relative '../../page_objects/pages/account'
|
|
4
8
|
require_relative '../../page_objects/pages/login'
|
|
5
9
|
|
|
6
10
|
Given("I'm a {user} on the login page") do |user|
|
|
7
11
|
@user = user
|
|
8
|
-
@login_page = Login.new
|
|
9
|
-
@login_page
|
|
12
|
+
@login_page = <% if capybara? %>Login.new<% elsif watir? %>Login.new(browser)<% else %>Login.new(driver)<% end %>
|
|
13
|
+
@login_page.<% if capybara? %>visit_page<% else %>visit<% end %>
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
When('I login with my credentials') do
|
|
17
|
+
# binding.break # Uncomment to pause here and inspect state
|
|
13
18
|
@login_page.login(@user['username'], @user['password'])
|
|
14
19
|
end
|
|
15
20
|
|
|
16
|
-
<%- if axe? -%>
|
|
17
|
-
Then('the page should be axe clean') do
|
|
18
|
-
account = Account.new(driver)
|
|
19
|
-
expect(account.page).to be_axe_clean
|
|
20
|
-
end
|
|
21
|
-
<%- else -%>
|
|
22
21
|
Then("I'm logged in") do
|
|
23
|
-
account_page = Account.new
|
|
24
|
-
|
|
25
|
-
check_page account_page
|
|
26
|
-
<%- else -%>
|
|
22
|
+
account_page = <% if capybara? %>Account.new<% elsif watir? %>Account.new(browser)<% else %>Account.new(driver)<% end %>
|
|
23
|
+
account_page.<% if capybara? %>visit_page<% else %>visit<% end %>
|
|
27
24
|
expect(account_page.header.customer_name).to eq "Welcome back #{@user['name']}"
|
|
28
|
-
|
|
29
|
-
end
|
|
30
|
-
<%- end -%>
|
|
25
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../helpers/performance_helper'
|
|
4
|
+
|
|
5
|
+
include PerformanceHelper
|
|
6
|
+
|
|
7
|
+
Given('I audit the home page performance') do
|
|
8
|
+
@result = assert_performance_above('https://raider-test-site.onrender.com/', threshold: 0.7)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Then('the performance score should be above the threshold') do
|
|
12
|
+
expect(@result[:status]).not_to eq(:error),
|
|
13
|
+
"Lighthouse error: #{@result[:message]}"
|
|
14
|
+
|
|
15
|
+
expect(@result[:passed]).to be(true),
|
|
16
|
+
"Performance below threshold (#{@result[:threshold]}): #{@result[:scores]}"
|
|
17
|
+
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<%- if web? -%>
|
|
2
|
-
<%=
|
|
2
|
+
<%= partial('web_steps', strip: true) -%>
|
|
3
3
|
<%- else -%>
|
|
4
|
-
<%=
|
|
4
|
+
<%= partial('mobile_steps', strip: true) -%>
|
|
5
5
|
<%- end -%>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../helpers/visual_helper'
|
|
4
|
+
require_relative '../../page_objects/pages/login'
|
|
5
|
+
|
|
6
|
+
include VisualHelper
|
|
7
|
+
|
|
8
|
+
Given("I'm on the login page") do
|
|
9
|
+
@login_page = <% if capybara? %>Login.new<% elsif watir? %>Login.new(browser)<% else %>Login.new(driver)<% end %>
|
|
10
|
+
@login_page.<% if capybara? %>visit_page<% else %>visit<% end %>
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Then('the page should match the visual baseline {string}') do |baseline_name|
|
|
14
|
+
screenshot_path = <% if capybara? %>page.save_screenshot("tmp/visual_#{baseline_name}.png")<% elsif watir? %>browser.screenshot.save("tmp/visual_#{baseline_name}.png")<% else %>driver.save_screenshot("tmp/visual_#{baseline_name}.png")<% end %>
|
|
15
|
+
result = compare_screenshot(baseline_name, screenshot_path)
|
|
16
|
+
|
|
17
|
+
expect(result[:status]).not_to eq(:mismatch),
|
|
18
|
+
"Visual diff: #{(result[:diff].to_f * 100).round(2)}% difference. See: #{result[:diff_path]}"
|
|
19
|
+
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
<%- if
|
|
2
|
-
<%=-
|
|
1
|
+
<%- if capybara? -%>
|
|
2
|
+
<%=- partial('capybara_world', strip: true) -%>
|
|
3
|
+
<%- elsif watir? -%>
|
|
4
|
+
<%=- partial('watir_world', strip: true) -%>
|
|
3
5
|
<%- else -%>
|
|
4
|
-
<%=-
|
|
6
|
+
<%=- partial('driver_world', strip: true) -%>
|
|
5
7
|
<%- end -%>
|
data/lib/generators/generator.rb
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'thor'
|
|
4
|
+
require_relative 'template_renderer'
|
|
4
5
|
|
|
5
6
|
class Generator < Thor::Group
|
|
6
7
|
include Thor::Actions
|
|
8
|
+
include TemplateRenderer
|
|
9
|
+
|
|
10
|
+
LATEST_RUBY = '3.4'
|
|
7
11
|
|
|
8
12
|
argument :automation
|
|
9
13
|
argument :framework
|
|
@@ -12,7 +16,8 @@ class Generator < Thor::Group
|
|
|
12
16
|
def self.source_paths
|
|
13
17
|
base_path = File.dirname(__FILE__)
|
|
14
18
|
%W[#{base_path}/automation/templates #{base_path}/cucumber/templates
|
|
15
|
-
#{base_path}/rspec/templates #{base_path}/
|
|
19
|
+
#{base_path}/rspec/templates #{base_path}/minitest/templates
|
|
20
|
+
#{base_path}/templates #{base_path}/infrastructure/templates ]
|
|
16
21
|
end
|
|
17
22
|
|
|
18
23
|
def args
|
|
@@ -48,12 +53,20 @@ class Generator < Thor::Group
|
|
|
48
53
|
args.include?('rspec')
|
|
49
54
|
end
|
|
50
55
|
|
|
56
|
+
def minitest?
|
|
57
|
+
args.include?('minitest')
|
|
58
|
+
end
|
|
59
|
+
|
|
51
60
|
def selenium?
|
|
52
61
|
args.include?('selenium')
|
|
53
62
|
end
|
|
54
63
|
|
|
55
|
-
def
|
|
56
|
-
args.include?('
|
|
64
|
+
def capybara?
|
|
65
|
+
args.include?('capybara')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def visual_addon?
|
|
69
|
+
args.include?('visual_addon')
|
|
57
70
|
end
|
|
58
71
|
|
|
59
72
|
def watir?
|
|
@@ -61,15 +74,45 @@ class Generator < Thor::Group
|
|
|
61
74
|
end
|
|
62
75
|
|
|
63
76
|
def web?
|
|
64
|
-
(args &
|
|
77
|
+
(args & %w[selenium watir capybara]).count.positive?
|
|
65
78
|
end
|
|
66
79
|
|
|
67
|
-
def
|
|
68
|
-
args.include?('
|
|
80
|
+
def axe_addon?
|
|
81
|
+
args.include?('axe_addon')
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def lighthouse_addon?
|
|
85
|
+
args.include?('lighthouse_addon')
|
|
69
86
|
end
|
|
70
87
|
|
|
71
88
|
def selenium_based?
|
|
72
|
-
(
|
|
89
|
+
args.include?('selenium')
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def skip_allure?
|
|
93
|
+
args.include?('skip_allure')
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def skip_video?
|
|
97
|
+
args.include?('skip_video')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def allure_reporter?
|
|
101
|
+
has_reporter = args.any? { |a| a&.start_with?('reporter_') }
|
|
102
|
+
has_reporter ? args.include?('reporter_allure') : !skip_allure?
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def junit_reporter?
|
|
106
|
+
args.include?('reporter_junit')
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def json_reporter?
|
|
110
|
+
args.include?('reporter_json')
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def ruby_version
|
|
114
|
+
arg = args.find { |a| a&.start_with?('ruby_version:') }
|
|
115
|
+
arg ? arg.split(':', 2).last : LATEST_RUBY
|
|
73
116
|
end
|
|
74
117
|
|
|
75
118
|
private
|
|
@@ -6,12 +6,16 @@ class HelpersGenerator < Generator
|
|
|
6
6
|
def generate_helpers
|
|
7
7
|
generate_browser_helper
|
|
8
8
|
generate_driver_helper
|
|
9
|
+
generate_capybara_helper
|
|
9
10
|
generate_appium_helper
|
|
10
11
|
generate_allure_helper
|
|
12
|
+
generate_video_helper
|
|
13
|
+
generate_debug_helper
|
|
14
|
+
generate_visual_helper
|
|
15
|
+
generate_performance_helper
|
|
11
16
|
|
|
12
|
-
if
|
|
13
|
-
|
|
14
|
-
generate_visual_spec_helper
|
|
17
|
+
if minitest?
|
|
18
|
+
generate_test_helper
|
|
15
19
|
else
|
|
16
20
|
generate_spec_helper
|
|
17
21
|
end
|
|
@@ -20,40 +24,66 @@ class HelpersGenerator < Generator
|
|
|
20
24
|
private
|
|
21
25
|
|
|
22
26
|
def generate_allure_helper
|
|
27
|
+
return unless allure_reporter?
|
|
28
|
+
|
|
23
29
|
template('helpers/allure_helper.tt', "#{name}/helpers/allure_helper.rb")
|
|
24
30
|
end
|
|
25
31
|
|
|
32
|
+
def generate_video_helper
|
|
33
|
+
return if skip_video?
|
|
34
|
+
|
|
35
|
+
template('helpers/video_helper.tt', "#{name}/helpers/video_helper.rb")
|
|
36
|
+
end
|
|
37
|
+
|
|
26
38
|
def generate_browser_helper
|
|
27
|
-
return if selenium_based? || mobile?
|
|
39
|
+
return if selenium_based? || mobile? || capybara?
|
|
28
40
|
|
|
29
41
|
template('helpers/browser_helper.tt', "#{name}/helpers/browser_helper.rb")
|
|
30
42
|
end
|
|
31
43
|
|
|
32
44
|
def generate_spec_helper
|
|
33
|
-
return if cucumber?
|
|
45
|
+
return if cucumber? || minitest?
|
|
34
46
|
|
|
35
47
|
template('helpers/spec_helper.tt', "#{name}/helpers/spec_helper.rb")
|
|
36
48
|
end
|
|
37
49
|
|
|
38
50
|
def generate_driver_helper
|
|
39
|
-
return if watir?
|
|
51
|
+
return if watir? || capybara?
|
|
40
52
|
|
|
41
53
|
template('helpers/driver_helper.tt', "#{name}/helpers/driver_helper.rb")
|
|
42
54
|
end
|
|
43
55
|
|
|
56
|
+
def generate_capybara_helper
|
|
57
|
+
return unless capybara?
|
|
58
|
+
|
|
59
|
+
template('helpers/capybara_helper.tt', "#{name}/helpers/capybara_helper.rb")
|
|
60
|
+
end
|
|
61
|
+
|
|
44
62
|
def generate_appium_helper
|
|
45
63
|
return unless cross_platform?
|
|
46
64
|
|
|
47
65
|
template('helpers/appium_helper.tt', "#{name}/helpers/appium_helper.rb")
|
|
48
66
|
end
|
|
49
67
|
|
|
68
|
+
def generate_test_helper
|
|
69
|
+
template('helpers/test_helper.tt', "#{name}/helpers/test_helper.rb")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def generate_debug_helper
|
|
73
|
+
return unless web?
|
|
74
|
+
|
|
75
|
+
template('helpers/debug_helper.tt', "#{name}/helpers/debug_helper.rb")
|
|
76
|
+
end
|
|
77
|
+
|
|
50
78
|
def generate_visual_helper
|
|
79
|
+
return unless visual_addon? && web?
|
|
80
|
+
|
|
51
81
|
template('helpers/visual_helper.tt', "#{name}/helpers/visual_helper.rb")
|
|
52
82
|
end
|
|
53
83
|
|
|
54
|
-
def
|
|
55
|
-
return
|
|
84
|
+
def generate_performance_helper
|
|
85
|
+
return unless lighthouse_addon? && web?
|
|
56
86
|
|
|
57
|
-
template('helpers/
|
|
87
|
+
template('helpers/performance_helper.tt', "#{name}/helpers/performance_helper.rb")
|
|
58
88
|
end
|
|
59
89
|
end
|
|
@@ -8,4 +8,10 @@ class GithubGenerator < Generator
|
|
|
8
8
|
|
|
9
9
|
template('github.tt', "#{name}/.github/workflows/test_pipeline.yml")
|
|
10
10
|
end
|
|
11
|
+
|
|
12
|
+
def generate_appium_pipeline
|
|
13
|
+
return unless mobile?
|
|
14
|
+
|
|
15
|
+
template('github_appium.tt', "#{name}/.github/workflows/appium_pipeline.yml")
|
|
16
|
+
end
|
|
11
17
|
end
|
|
@@ -16,23 +16,27 @@ jobs:
|
|
|
16
16
|
runs-on: ubuntu-latest
|
|
17
17
|
|
|
18
18
|
steps:
|
|
19
|
+
- name: Checkout repository
|
|
20
|
+
uses: actions/checkout@v4
|
|
21
|
+
|
|
19
22
|
- name: Set up Ruby
|
|
20
23
|
uses: ruby/setup-ruby@v1
|
|
21
24
|
with:
|
|
22
|
-
ruby-version:
|
|
25
|
+
ruby-version: <%= ruby_version %>.0
|
|
23
26
|
bundler-cache: true
|
|
24
27
|
|
|
25
|
-
- name:
|
|
26
|
-
uses: actions/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
run: bundle install
|
|
28
|
+
- name: Set up Chrome
|
|
29
|
+
uses: browser-actions/setup-chrome@v1
|
|
30
|
+
with:
|
|
31
|
+
chrome-version: stable
|
|
30
32
|
|
|
31
33
|
- name: Create allure-results folder
|
|
32
34
|
run: mkdir -p allure-results
|
|
33
35
|
|
|
34
|
-
- name:
|
|
35
|
-
run: <%- if framework == 'cucumber' -%>cucumber features --format pretty <%- else -%>bundle exec rspec spec --format documentation<%- end
|
|
36
|
+
- name: Run tests
|
|
37
|
+
run: <%- if framework == 'cucumber' -%>bundle exec cucumber features --format pretty<%- elsif minitest? -%>bundle exec ruby -Itest test/test_login_page.rb<%- else -%>bundle exec rspec spec --format documentation<%- end %>
|
|
38
|
+
env:
|
|
39
|
+
HEADLESS: true
|
|
36
40
|
|
|
37
41
|
- name: Get Allure history
|
|
38
42
|
uses: actions/checkout@v2
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
name: Appium Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
<%- if ios? || cross_platform? -%>
|
|
11
|
+
ios-tests:
|
|
12
|
+
runs-on: macos-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: ruby/setup-ruby@v1
|
|
16
|
+
with:
|
|
17
|
+
ruby-version: <%= ruby_version %>.0
|
|
18
|
+
bundler-cache: true
|
|
19
|
+
|
|
20
|
+
- name: Download iOS app
|
|
21
|
+
uses: dawidd6/action-download-artifact@v6
|
|
22
|
+
with:
|
|
23
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
24
|
+
repo: RaiderHQ/raider_test_app
|
|
25
|
+
workflow: build-ios.yml
|
|
26
|
+
name: raider-test-app-ios
|
|
27
|
+
path: apps/
|
|
28
|
+
|
|
29
|
+
- name: Unzip iOS app
|
|
30
|
+
run: |
|
|
31
|
+
cd apps
|
|
32
|
+
unzip RaiderTestApp.app.zip
|
|
33
|
+
|
|
34
|
+
- name: Start iOS Simulator
|
|
35
|
+
uses: futureware-tech/simulator-action@v3
|
|
36
|
+
with:
|
|
37
|
+
model: 'iPhone 15'
|
|
38
|
+
os_version: '17'
|
|
39
|
+
|
|
40
|
+
- name: Install and start Appium
|
|
41
|
+
run: |
|
|
42
|
+
npm install -g appium
|
|
43
|
+
appium driver install xcuitest
|
|
44
|
+
appium &
|
|
45
|
+
sleep 5
|
|
46
|
+
|
|
47
|
+
- name: Run tests
|
|
48
|
+
<%- if cucumber? -%>
|
|
49
|
+
run: bundle exec cucumber features/ --format pretty
|
|
50
|
+
<%- elsif minitest? -%>
|
|
51
|
+
run: bundle exec ruby -Itest test/test_pdp_page.rb
|
|
52
|
+
<%- else -%>
|
|
53
|
+
run: bundle exec rspec spec/ --format documentation
|
|
54
|
+
<%- end -%>
|
|
55
|
+
env:
|
|
56
|
+
APP_PATH: ${{ github.workspace }}/apps/RaiderTestApp.app
|
|
57
|
+
<%- end -%>
|
|
58
|
+
|
|
59
|
+
<%- if android? || cross_platform? -%>
|
|
60
|
+
android-tests:
|
|
61
|
+
runs-on: ubuntu-latest
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@v4
|
|
64
|
+
- uses: ruby/setup-ruby@v1
|
|
65
|
+
with:
|
|
66
|
+
ruby-version: <%= ruby_version %>.0
|
|
67
|
+
bundler-cache: true
|
|
68
|
+
|
|
69
|
+
- name: Download Android app
|
|
70
|
+
uses: dawidd6/action-download-artifact@v6
|
|
71
|
+
with:
|
|
72
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
73
|
+
repo: RaiderHQ/raider_test_app
|
|
74
|
+
workflow: build-android.yml
|
|
75
|
+
name: raider-test-app-android
|
|
76
|
+
path: apps/
|
|
77
|
+
|
|
78
|
+
- name: Set up JDK 17
|
|
79
|
+
uses: actions/setup-java@v4
|
|
80
|
+
with:
|
|
81
|
+
java-version: '17'
|
|
82
|
+
distribution: 'temurin'
|
|
83
|
+
|
|
84
|
+
- name: Install and start Appium
|
|
85
|
+
run: |
|
|
86
|
+
npm install -g appium
|
|
87
|
+
appium driver install uiautomator2
|
|
88
|
+
appium &
|
|
89
|
+
sleep 5
|
|
90
|
+
|
|
91
|
+
- name: Run Android Emulator and Tests
|
|
92
|
+
uses: reactivecircus/android-emulator-runner@v2
|
|
93
|
+
with:
|
|
94
|
+
api-level: 34
|
|
95
|
+
target: google_apis
|
|
96
|
+
arch: x86_64
|
|
97
|
+
profile: pixel_8
|
|
98
|
+
script: |
|
|
99
|
+
<%- if cucumber? -%>
|
|
100
|
+
bundle exec cucumber features/ --format pretty
|
|
101
|
+
<%- elsif minitest? -%>
|
|
102
|
+
bundle exec ruby -Itest test/test_pdp_page.rb
|
|
103
|
+
<%- else -%>
|
|
104
|
+
bundle exec rspec spec/ --format documentation
|
|
105
|
+
<%- end -%>
|
|
106
|
+
env:
|
|
107
|
+
APP_PATH: ${{ github.workspace }}/apps/app-release.apk
|
|
108
|
+
<%- end -%>
|
|
@@ -4,7 +4,8 @@ stages:
|
|
|
4
4
|
- report
|
|
5
5
|
|
|
6
6
|
variables:
|
|
7
|
-
RUBY_VERSION: "
|
|
7
|
+
RUBY_VERSION: "<%= ruby_version %>.0"
|
|
8
|
+
HEADLESS: "true"
|
|
8
9
|
|
|
9
10
|
setup_ruby:
|
|
10
11
|
stage: setup
|
|
@@ -18,9 +19,11 @@ setup_ruby:
|
|
|
18
19
|
run_tests:
|
|
19
20
|
stage: test
|
|
20
21
|
image: ruby:${RUBY_VERSION}
|
|
21
|
-
|
|
22
|
+
before_script:
|
|
23
|
+
- apt-get update -qq && apt-get install -y -qq chromium chromium-driver
|
|
22
24
|
- mkdir -p allure-results
|
|
23
|
-
|
|
25
|
+
script:
|
|
26
|
+
- <%- if framework == 'cucumber' -%>bundle exec cucumber features --format pretty<%- elsif minitest? -%>bundle exec ruby -Itest test/test_login_page.rb<%- else -%>bundle exec rspec spec --format documentation<%- end %>
|
|
24
27
|
artifacts:
|
|
25
28
|
paths:
|
|
26
29
|
- allure-results/
|
|
@@ -4,10 +4,9 @@ require_relative 'automation/automation_generator'
|
|
|
4
4
|
require_relative 'common_generator'
|
|
5
5
|
require_relative 'cucumber/cucumber_generator'
|
|
6
6
|
require_relative 'helper_generator'
|
|
7
|
+
require_relative 'minitest/minitest_generator'
|
|
7
8
|
require_relative 'rspec/rspec_generator'
|
|
8
9
|
|
|
9
|
-
# :reek:FeatureEnvy { enabled: false }
|
|
10
|
-
# :reek:UtilityFunction { enabled: false }
|
|
11
10
|
module InvokeGenerators
|
|
12
11
|
module_function
|
|
13
12
|
|
|
@@ -15,14 +14,16 @@ module InvokeGenerators
|
|
|
15
14
|
generators = %w[Automation Common Helpers]
|
|
16
15
|
framework = structure[:framework]
|
|
17
16
|
add_generator(generators, framework.capitalize)
|
|
18
|
-
add_generator(generators, structure[:ci_platform].capitalize) if structure[:ci_platform]
|
|
17
|
+
add_generator(generators, structure[:ci_platform].capitalize) if !structure[:skip_ci] && (structure[:ci_platform])
|
|
18
|
+
extra_args = collect_skip_flags(structure)
|
|
19
19
|
generators.each do |generator|
|
|
20
20
|
invoke_generator({
|
|
21
21
|
automation: structure[:automation],
|
|
22
22
|
framework:,
|
|
23
23
|
generator:,
|
|
24
24
|
ci_platform: structure[:ci_platform],
|
|
25
|
-
name: structure[:name]
|
|
25
|
+
name: structure[:name],
|
|
26
|
+
extra_args:
|
|
26
27
|
})
|
|
27
28
|
end
|
|
28
29
|
end
|
|
@@ -31,12 +32,45 @@ module InvokeGenerators
|
|
|
31
32
|
gens.each { |generator| generators.push generator }
|
|
32
33
|
end
|
|
33
34
|
|
|
35
|
+
# Generator class lookup cache — avoids repeated Object.const_get string interpolation
|
|
36
|
+
GENERATOR_CLASSES = Hash.new { |h, k| h[k] = Object.const_get("#{k}Generator") }
|
|
37
|
+
|
|
34
38
|
def invoke_generator(structure = {})
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
args = [structure[:automation], structure[:framework], structure[:name], structure[:ci_platform]]
|
|
40
|
+
args.concat(structure[:extra_args] || [])
|
|
41
|
+
generator_class = GENERATOR_CLASSES[structure[:generator]]
|
|
42
|
+
generator = generator_class.new(args)
|
|
43
|
+
# Enable batch mode on the template cache to skip mtime checks during generation
|
|
44
|
+
generator.class.template_renderer.batch_mode = true if generator.class.respond_to?(:template_renderer)
|
|
45
|
+
generator.invoke_all
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def collect_skip_flags(structure)
|
|
49
|
+
flags = []
|
|
50
|
+
flags << 'skip_allure' if structure[:skip_allure]
|
|
51
|
+
flags << 'skip_video' if structure[:skip_video]
|
|
52
|
+
flags << 'axe_addon' if structure[:accessibility] && !mobile_automation?(structure[:automation])
|
|
53
|
+
flags << 'visual_addon' if structure[:visual] && !mobile_automation?(structure[:automation])
|
|
54
|
+
flags << 'lighthouse_addon' if structure[:performance] && !mobile_automation?(structure[:automation])
|
|
55
|
+
flags << "ruby_version:#{structure[:ruby_version]}" if structure[:ruby_version]
|
|
56
|
+
flags.concat(reporter_flags(structure[:reporter]))
|
|
57
|
+
flags
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def reporter_flags(reporter)
|
|
61
|
+
case reporter
|
|
62
|
+
when 'allure' then ['reporter_allure']
|
|
63
|
+
when 'junit' then ['reporter_junit']
|
|
64
|
+
when 'json' then ['reporter_json']
|
|
65
|
+
when 'both' then %w[reporter_allure reporter_junit]
|
|
66
|
+
when 'all' then %w[reporter_allure reporter_junit reporter_json]
|
|
67
|
+
when 'none' then ['reporter_none']
|
|
68
|
+
else []
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def mobile_automation?(automation)
|
|
73
|
+
%w[ios android cross_platform].include?(automation)
|
|
40
74
|
end
|
|
41
75
|
|
|
42
76
|
def to_bool(string)
|