ruby_raider 3.4.0 → 3.6.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -2
  3. data/RELEASE.md +18 -0
  4. data/lib/generators/common_generator.rb +2 -0
  5. data/lib/generators/cucumber/templates/cucumber.tt +1 -1
  6. data/lib/generators/cucumber/templates/partials/appium_env.tt +10 -5
  7. data/lib/generators/cucumber/templates/partials/selenium_env.tt +9 -5
  8. data/lib/generators/cucumber/templates/partials/watir_env.tt +9 -5
  9. data/lib/generators/generator.rb +9 -0
  10. data/lib/generators/helper_generator.rb +2 -0
  11. data/lib/generators/infrastructure/azure_generator.rb +11 -0
  12. data/lib/generators/infrastructure/github_generator.rb +2 -2
  13. data/lib/generators/infrastructure/templates/azure_pipelines.tt +44 -0
  14. data/lib/generators/infrastructure/templates/github.tt +4 -7
  15. data/lib/generators/infrastructure/templates/github_appium.tt +0 -6
  16. data/lib/generators/invoke_generators.rb +19 -1
  17. data/lib/generators/menu_generator.rb +16 -6
  18. data/lib/generators/templates/common/gemfile.tt +2 -4
  19. data/lib/generators/templates/common/git_ignore.tt +3 -1
  20. data/lib/generators/templates/common/read_me.tt +27 -1
  21. data/lib/ruby_raider.rb +8 -1
  22. data/lib/version +1 -1
  23. data/sig/generators/generator.rbs +2 -0
  24. data/sig/generators/infrastructure/azure_generator.rbs +4 -0
  25. data/sig/generators/invoke_generators.rbs +5 -0
  26. data/sig/generators/menu_generator.rbs +2 -1
  27. data/sig/ruby_raider.rbs +1 -0
  28. data/spec/integration/content/azure_content_spec.rb +109 -0
  29. data/spec/integration/content/ci_content_spec.rb +24 -24
  30. data/spec/integration/content/common_content_spec.rb +4 -4
  31. data/spec/integration/content/cucumber_reporter_content_spec.rb +64 -0
  32. data/spec/integration/content/gemfile_content_spec.rb +7 -7
  33. data/spec/integration/content/helper_content_spec.rb +2 -6
  34. data/spec/integration/content/readme_content_spec.rb +13 -3
  35. data/spec/integration/content/test_content_spec.rb +4 -0
  36. data/spec/integration/end_to_end_spec.rb +171 -3
  37. data/spec/integration/generators/azure_generator_spec.rb +100 -0
  38. data/spec/integration/generators/helpers_generator_spec.rb +6 -3
  39. data/spec/menus/menu_generator_spec.rb +49 -0
  40. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5141b6656f193315dce72afc9a7096ea48e63eed8a23c348cf38be0978627e90
4
- data.tar.gz: b47a32013c49843ac2511f4bb0188adfcd50a83294fdbe692f8e483f3215ca67
3
+ metadata.gz: ddfb958e45c6bc2214a0d9b80fd9085d8c8bd061199988ba5d0717becfa8e4ba
4
+ data.tar.gz: bc6baf9bc40c2cc60c7dbdbf68386b49ede6c014a80e76bef90746841db7933d
5
5
  SHA512:
6
- metadata.gz: 4840894d57645404ac69faf2ebe7985e59b5df8e653ec8746fb40d23a45e082b0f2708b1d2cc275f7cfa3ce250a009dea61d2022ed6ca96f6c835ac36ed04bca
7
- data.tar.gz: f0eee8de1a42d7ff1440ee7d6700c9d6ffa9370fe53a811b2c99ba03147eed8101edeff5a8e9df0849fe25fb5189d5fd34aab9e07b5ee0642d575d46739f487c
6
+ metadata.gz: 2357fb714baf101f7bb2891fd0f0e2560acb6c5b0009b3188da7714f0579361519d5f00aace5bbaa725e8e6fee3bc9e5d38ad887ff71eed218b0db7154ad3077
7
+ data.tar.gz: c27785ba31ac441a2c8f76cc15e3266881ee4b69a8d3dde8b4de10eabfdc52e81fa3b3ae8be1247afa6256ea03389ee76fe0812d7228ea94934ccdfd5604b9f7
data/README.md CHANGED
@@ -50,6 +50,7 @@ Ruby Raider is a CLI gem and API backend for scaffolding and generating UI test
50
50
  | Add-on | Flag | Description |
51
51
  |--------|------|-------------|
52
52
  | Accessibility | `--accessibility` | Adds axe gem + example accessibility tests |
53
+ | CI provider | `-p ci:azure` | Generates `azure-pipelines.yml` instead of the GitHub Actions workflow (default `ci:github`) |
53
54
 
54
55
  This works on all platforms (Mac OS, Linux and Windows).
55
56
 
@@ -59,8 +60,8 @@ Every generated project comes with:
59
60
 
60
61
  - **Page Object Model** — Base page and component classes with example pages
61
62
  - **Test examples** — Working login tests against the [Raider Test Store](https://raider-test-site.onrender.com/)
62
- - **Allure reporting** — Pre-configured with screenshot capture on failure
63
- - **Raider reporting** — RSpec projects include [raider_reporter](https://github.com/RaiderHQ/raider_reporter), which writes results to `raider-results/` and uploads runs when `RAIDER_TOKEN` and `RAIDER_ENDPOINT` are set
63
+ - **Allure reporting** (RSpec) — Pre-configured with screenshot capture on failure
64
+ - **Raider reporting** — RSpec and Cucumber projects include [raider_reporter](https://github.com/RaiderHQ/raider_reporter), which writes results to `raider-results/` and uploads runs when `RAIDER_TOKEN` and `RAIDER_ENDPOINT` are set
64
65
  - **GitHub Actions CI** — Ready-to-use test pipeline
65
66
  - **Rake tasks** — Default, smoke, and regression tasks with tag-based filtering
66
67
  - **Retry support** — RSpec retry with configurable retry count via `RETRY_COUNT` env var
@@ -101,6 +102,15 @@ Add accessibility testing:
101
102
  raider new my_project -p framework:rspec automation:selenium --accessibility
102
103
  ```
103
104
 
105
+ Generate an Azure Pipelines file instead of GitHub Actions (web projects only):
106
+
107
+ ```bash
108
+ raider new my_project -p framework:rspec automation:selenium ci:azure
109
+ ```
110
+
111
+ Azure Pipelines for mobile (Appium) projects is not available yet: with `ci:azure` no pipeline file is generated and a notice is printed.
112
+ Azure Repos ignores `pr:` triggers, so add the pipeline as a Build validation branch policy to get pull request builds.
113
+
104
114
  ## Commands
105
115
 
106
116
  ###### Anything between square brackets ([...]) is where your input goes
data/RELEASE.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## Release Notes
4
4
 
5
+ ### 3.6.0
6
+
7
+ - New `ci` parameter: `raider new my_project -p framework:rspec automation:selenium ci:azure` generates an `azure-pipelines.yml` for web projects instead of the GitHub Actions workflow. `ci:github` (the default) is unchanged; any other value fails with `Invalid parameters: ci must be github or azure`.
8
+ - The pipeline runs the suite on `ubuntu-latest`, publishes `raider-results/` as a pipeline artifact and includes a `raider_comment` job that comments Raider results on pull requests via `raider-reporter comment`. It needs the `RAIDER_TOKEN` (secret) and `RAIDER_ENDPOINT` pipeline variables and the "Contribute to pull requests" permission for the build service.
9
+ - Azure Repos ignores `pr:` triggers: add the pipeline as a Build validation branch policy so pull request builds and the Raider comment run.
10
+ - The interactive menu asks "Which CI provider?" (GitHub Actions / Azure Pipelines) for web automations.
11
+ - The generated Readme gets an "Azure Pipelines" section when `ci:azure` is used.
12
+ - Mobile projects with `ci:azure` get no pipeline file yet; `raider new` prints a notice.
13
+ - Generated Gemfiles now require `raider_reporter` `~> 0.5`.
14
+
15
+ ### 3.5.0
16
+
17
+ - Generated Cucumber projects now report through `raider_reporter` `~> 0.4` instead of Allure: results are written to `raider-results/` and uploaded when `RAIDER_TOKEN` and `RAIDER_ENDPOINT` are set. The reporter is activated by `require 'raider_reporter/cucumber'` in `features/support/env.rb`.
18
+ - Cucumber projects no longer include `allure-cucumber` or `helpers/allure_helper.rb`; failure screenshots are attached to Raider only, and `.gitignore` lists `raider-results` instead of `allure-results`.
19
+ - Generated Cucumber GitHub CI now passes the Raider settings to the test run, uploads `raider-results/` as an artifact and includes the `raider-comment` job, matching RSpec projects. The Allure report and gh-pages steps are removed for Cucumber. RSpec pipelines are unchanged.
20
+ - The generated Readme has a "Reporting" section for Cucumber projects too.
21
+ - Generated Gemfiles now require `raider_reporter` `~> 0.4`.
22
+
5
23
  ### 3.4.0
6
24
 
7
25
  - Generated RSpec projects with GitHub CI now include a `raider-comment` job that comments Raider test results on pull requests via `raider-reporter comment`. It runs after every test job, only on pull requests, and needs the `RAIDER_TOKEN` secret and `RAIDER_ENDPOINT` variable. Cucumber projects are unchanged.
@@ -40,6 +40,8 @@ class CommonGenerator < Generator
40
40
  end
41
41
 
42
42
  def create_allure_folder
43
+ return if cucumber?
44
+
43
45
  empty_directory "#{name}/allure-results"
44
46
  end
45
47
  end
@@ -1 +1 @@
1
- default: --format AllureCucumber::CucumberFormatter --out allure-results --publish-quiet --retry 0
1
+ default: --format pretty --publish-quiet --retry 0
@@ -1,15 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'raider_reporter/cucumber'
1
4
  require 'tmpdir'
2
- require_relative '../../helpers/allure_helper'
3
5
 
4
6
  Before do
5
- AllureHelper.configure
6
7
  driver.start_driver
7
8
  end
8
9
 
9
10
  After do |scenario|
10
- Dir.mktmpdir do |temp_folder|
11
- screenshot = driver.screenshot("#{temp_folder}/#{scenario.name}.png")
12
- AllureHelper.add_screenshot(scenario.name, screenshot)
11
+ if scenario.failed?
12
+ Dir.mktmpdir do |temp_folder|
13
+ screenshot_path = File.join(temp_folder, 'screenshot.png')
14
+ driver.screenshot(screenshot_path)
15
+ RaiderReporter.attach('screenshot', screenshot_path, type: :png)
16
+ end
13
17
  end
18
+ ensure
14
19
  driver.quit_driver
15
20
  end
@@ -4,9 +4,9 @@
4
4
  require 'axe-rspec'
5
5
  <%- end -%>
6
6
  require 'rspec'
7
+ require 'raider_reporter/cucumber'
7
8
  require 'tmpdir'
8
9
  require 'yaml'
9
- require_relative '../../helpers/allure_helper'
10
10
 
11
11
  Before do
12
12
  viewport = YAML.load_file('config/config.yml')['viewport']
@@ -18,9 +18,13 @@ Before do
18
18
  end
19
19
 
20
20
  After do |scenario|
21
- Dir.mktmpdir do |temp_folder|
22
- screenshot = driver.save_screenshot("#{temp_folder}/#{scenario.name}.png")
23
- AllureHelper.add_screenshot(scenario.name, screenshot)
21
+ if scenario.failed?
22
+ Dir.mktmpdir do |temp_folder|
23
+ screenshot_path = File.join(temp_folder, 'screenshot.png')
24
+ driver.save_screenshot(screenshot_path)
25
+ RaiderReporter.attach('screenshot', screenshot_path, type: :png)
26
+ end
24
27
  end
28
+ ensure
25
29
  driver.quit
26
- end
30
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'raider_reporter/cucumber'
3
4
  require 'tmpdir'
4
5
  require 'yaml'
5
- require_relative '../../helpers/allure_helper'
6
6
 
7
7
  Before do
8
8
  viewport = YAML.load_file('config/config.yml')['viewport']
@@ -14,9 +14,13 @@ Before do
14
14
  end
15
15
 
16
16
  After do |scenario|
17
- Dir.mktmpdir do |temp_folder|
18
- screenshot = browser.screenshot.save("#{temp_folder}/#{scenario.name}.png")
19
- AllureHelper.add_screenshot(scenario.name, screenshot)
17
+ if scenario.failed?
18
+ Dir.mktmpdir do |temp_folder|
19
+ screenshot_path = File.join(temp_folder, 'screenshot.png')
20
+ browser.screenshot.save(screenshot_path)
21
+ RaiderReporter.attach('screenshot', screenshot_path, type: :png)
22
+ end
20
23
  end
24
+ ensure
21
25
  browser.quit
22
- end
26
+ end
@@ -51,6 +51,15 @@ class Generator < Thor::Group
51
51
  args.include?('rspec')
52
52
  end
53
53
 
54
+ # Only the options after automation, framework and name, so a project named "azure" is not Azure CI
55
+ def azure?
56
+ args.drop(3).include?('azure')
57
+ end
58
+
59
+ def github_ci?
60
+ !azure?
61
+ end
62
+
54
63
  def selenium?
55
64
  args.include?('selenium')
56
65
  end
@@ -14,6 +14,8 @@ class HelpersGenerator < Generator
14
14
  private
15
15
 
16
16
  def generate_allure_helper
17
+ return if cucumber?
18
+
17
19
  template('helpers/allure_helper.tt', "#{name}/helpers/allure_helper.rb")
18
20
  end
19
21
 
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../generator'
4
+
5
+ class AzureGenerator < Generator
6
+ def generate_azure_pipeline
7
+ return unless azure? && web?
8
+
9
+ template('azure_pipelines.tt', "#{name}/azure-pipelines.yml")
10
+ end
11
+ end
@@ -4,13 +4,13 @@ require_relative '../generator'
4
4
 
5
5
  class GithubGenerator < Generator
6
6
  def generate_actions_file
7
- return unless web?
7
+ return unless github_ci? && web?
8
8
 
9
9
  template('github.tt', "#{name}/.github/workflows/test_pipeline.yml")
10
10
  end
11
11
 
12
12
  def generate_appium_pipeline
13
- return unless mobile?
13
+ return unless github_ci? && mobile?
14
14
 
15
15
  template('github_appium.tt', "#{name}/.github/workflows/appium_pipeline.yml")
16
16
  end
@@ -0,0 +1,44 @@
1
+ trigger:
2
+ branches:
3
+ include: [main, master]
4
+ # Azure Repos ignores pr: — add this pipeline as a Build validation branch policy so pull request builds (and the Raider comment) run.
5
+ pr:
6
+ branches:
7
+ include: ['*']
8
+
9
+ # Self-hosted agent? Replace vmImage with: pool: { name: Default }
10
+ pool:
11
+ vmImage: ubuntu-latest
12
+
13
+ variables:
14
+ HEADLESS: 'true'
15
+ # Add RAIDER_TOKEN (secret) and RAIDER_ENDPOINT as pipeline variables.
16
+
17
+ jobs:
18
+ - job: tests
19
+ steps:
20
+ - task: UseRubyVersion@0
21
+ inputs: { versionSpec: '3.4' }
22
+ - script: bundle install
23
+ displayName: Install gems
24
+ - script: <%- if cucumber? -%>bundle exec cucumber features/ --format pretty<%- else -%>bundle exec rspec spec/ --format documentation<%- end %>
25
+ displayName: Run tests
26
+ env:
27
+ RAIDER_TOKEN: $(RAIDER_TOKEN)
28
+ RAIDER_ENDPOINT: $(RAIDER_ENDPOINT)
29
+ - task: PublishPipelineArtifact@1
30
+ condition: always()
31
+ inputs: { targetPath: raider-results, artifact: raider-results-$(System.JobPositionInPhase)-$(System.JobAttempt) }
32
+ - job: raider_comment
33
+ dependsOn: tests
34
+ condition: and(always(), eq(variables['Build.Reason'], 'PullRequest'))
35
+ steps:
36
+ - task: UseRubyVersion@0
37
+ inputs: { versionSpec: '3.4' }
38
+ - script: bundle install
39
+ - script: bundle exec raider-reporter comment
40
+ displayName: Comment Raider results on the pull request
41
+ env:
42
+ RAIDER_TOKEN: $(RAIDER_TOKEN)
43
+ RAIDER_ENDPOINT: $(RAIDER_ENDPOINT)
44
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
@@ -33,19 +33,18 @@ jobs:
33
33
  with:
34
34
  chrome-version: stable
35
35
 
36
+ <%- unless framework == 'cucumber' -%>
36
37
  - name: Create allure-results folder
37
38
  run: mkdir -p allure-results
38
39
 
40
+ <%- end -%>
39
41
  - name: Run tests
40
42
  run: <%- if framework == 'cucumber' -%>bundle exec cucumber features --format pretty<%- else -%>bundle exec rspec spec --format documentation<%- end %>
41
43
  env:
42
44
  HEADLESS: true
43
- <%- unless framework == 'cucumber' -%>
44
45
  RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
45
46
  RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
46
- <%- end -%>
47
47
 
48
- <%- unless framework == 'cucumber' -%>
49
48
  - name: Upload Raider results
50
49
  uses: actions/upload-artifact@v4
51
50
  if: always()
@@ -54,8 +53,7 @@ jobs:
54
53
  path: raider-results/
55
54
  if-no-files-found: ignore
56
55
 
57
- <%- end -%>
58
-
56
+ <%- unless framework == 'cucumber' -%>
59
57
  - name: Get Allure history
60
58
  uses: actions/checkout@v2
61
59
  if: always()
@@ -82,7 +80,7 @@ jobs:
82
80
  PUBLISH_BRANCH: gh-pages
83
81
  PUBLISH_DIR: allure-history
84
82
 
85
- <%- unless framework == 'cucumber' -%>
83
+ <%- end -%>
86
84
  raider-comment:
87
85
  needs: [build]
88
86
  if: always() && github.event_name == 'pull_request'
@@ -101,4 +99,3 @@ jobs:
101
99
  RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
102
100
  RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
103
101
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
104
- <%- end -%>
@@ -52,7 +52,6 @@ jobs:
52
52
  <%- end -%>
53
53
  env:
54
54
  APP_PATH: ${{ github.workspace }}/apps/RaiderTestApp.app
55
- <%- unless cucumber? -%>
56
55
  RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
57
56
  RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
58
57
 
@@ -64,7 +63,6 @@ jobs:
64
63
  path: raider-results/
65
64
  if-no-files-found: ignore
66
65
  <%- end -%>
67
- <%- end -%>
68
66
 
69
67
  <%- if android? || cross_platform? -%>
70
68
  android-tests:
@@ -113,7 +111,6 @@ jobs:
113
111
  <%- end -%>
114
112
  env:
115
113
  APP_PATH: ${{ github.workspace }}/apps/app-release.apk
116
- <%- unless cucumber? -%>
117
114
  RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
118
115
  RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
119
116
 
@@ -125,9 +122,7 @@ jobs:
125
122
  path: raider-results/
126
123
  if-no-files-found: ignore
127
124
  <%- end -%>
128
- <%- end -%>
129
125
 
130
- <%- unless cucumber? -%>
131
126
  raider-comment:
132
127
  needs: [<%= [('ios-tests' if ios? || cross_platform?), ('android-tests' if android? || cross_platform?)].compact.join(', ') %>]
133
128
  if: always() && github.event_name == 'pull_request'
@@ -146,4 +141,3 @@ jobs:
146
141
  RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
147
142
  RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
148
143
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
149
- <%- end -%>
@@ -1,4 +1,5 @@
1
1
  require_relative 'infrastructure/github_generator'
2
+ require_relative 'infrastructure/azure_generator'
2
3
  require_relative 'automation/automation_generator'
3
4
  require_relative 'common_generator'
4
5
  require_relative 'cucumber/cucumber_generator'
@@ -6,13 +7,16 @@ require_relative 'helper_generator'
6
7
  require_relative 'rspec/rspec_generator'
7
8
 
8
9
  module InvokeGenerators
10
+ class InvalidParameters < ArgumentError; end
11
+
9
12
  module_function
10
13
 
11
14
  def generate_framework(structure = {})
15
+ validate_ci(structure[:ci])
12
16
  generators = %w[Automation Common Helpers]
13
17
  framework = structure[:framework]
14
18
  add_generator(generators, framework.capitalize)
15
- add_generator(generators, 'Github')
19
+ add_generator(generators, 'Github', 'Azure')
16
20
  extra_args = collect_flags(structure)
17
21
  generators.each do |generator|
18
22
  invoke_generator({
@@ -23,6 +27,19 @@ module InvokeGenerators
23
27
  extra_args:
24
28
  })
25
29
  end
30
+ print_mobile_azure_notice(structure)
31
+ end
32
+
33
+ def validate_ci(provider)
34
+ return if [nil, '', 'github', 'azure'].include?(provider&.to_s)
35
+
36
+ raise InvalidParameters, 'ci must be github or azure'
37
+ end
38
+
39
+ def print_mobile_azure_notice(structure)
40
+ return unless structure[:ci].to_s == 'azure' && mobile_automation?(structure[:automation])
41
+
42
+ puts 'Azure Pipelines template for mobile projects is not available yet; see the README.'
26
43
  end
27
44
 
28
45
  def add_generator(generators, *gens)
@@ -45,6 +62,7 @@ module InvokeGenerators
45
62
  def collect_flags(structure)
46
63
  flags = []
47
64
  flags << 'axe_addon' if structure[:accessibility] && !mobile_automation?(structure[:automation])
65
+ flags << 'azure' if structure[:ci].to_s == 'azure'
48
66
  flags
49
67
  end
50
68
 
@@ -30,6 +30,7 @@ class MenuGenerator
30
30
  automation: options[:automation],
31
31
  framework: options[:framework],
32
32
  accessibility: options[:accessibility],
33
+ ci: options[:ci],
33
34
  name: @name
34
35
  }
35
36
  generate_framework(structure)
@@ -75,18 +76,26 @@ class MenuGenerator
75
76
  end
76
77
  end
77
78
 
78
- FrameworkOptions = Struct.new(:automation, :framework, :accessibility)
79
+ FrameworkOptions = Struct.new(:automation, :framework, :accessibility, :ci)
79
80
 
80
81
  def create_framework_options(params)
81
- FrameworkOptions.new(params[:automation], params[:framework], params[:accessibility])
82
+ FrameworkOptions.new(params[:automation], params[:framework], params[:accessibility], params[:ci])
82
83
  end
83
84
 
84
85
  def select_accessibility(framework, automation_type)
85
86
  return create_framework(framework, automation_type) if mobile_automation?(automation_type)
86
87
 
87
88
  prompt.select('Add accessibility testing (axe)?') do |menu|
88
- menu.choice :Yes, -> { create_framework(framework, automation_type, accessibility: true) }
89
- menu.choice :No, -> { create_framework(framework, automation_type) }
89
+ menu.choice :Yes, -> { select_ci(framework, automation_type, accessibility: true) }
90
+ menu.choice :No, -> { select_ci(framework, automation_type, accessibility: false) }
91
+ menu.choice :Quit, -> { exit }
92
+ end
93
+ end
94
+
95
+ def select_ci(framework, automation_type, accessibility:)
96
+ prompt.select('Which CI provider?') do |menu|
97
+ menu.choice 'GitHub Actions', -> { create_framework(framework, automation_type, accessibility:) }
98
+ menu.choice 'Azure Pipelines', -> { create_framework(framework, automation_type, accessibility:, ci_provider: 'azure') }
90
99
  menu.choice :Quit, -> { exit }
91
100
  end
92
101
  end
@@ -95,15 +104,16 @@ class MenuGenerator
95
104
  %w[ios android cross_platform].include?(automation_type)
96
105
  end
97
106
 
98
- def create_framework(framework, automation_type, accessibility: false)
107
+ def create_framework(framework, automation_type, accessibility: false, ci_provider: nil)
99
108
  options = create_framework_options(automation: automation_type,
100
109
  framework: framework.downcase,
101
- accessibility:)
110
+ accessibility:, ci: ci_provider)
102
111
 
103
112
  puts 'Chosen Options:'
104
113
  puts " Automation Type: #{options[:automation]}"
105
114
  puts " Framework: #{options[:framework]}"
106
115
  puts ' Accessibility: enabled' if options[:accessibility]
116
+ puts ' CI: Azure Pipelines' if options[:ci] == 'azure'
107
117
 
108
118
  set_up_framework(options)
109
119
  prompt.say("You have chosen to use #{framework} with #{automation_type}")
@@ -5,9 +5,7 @@ gem 'activesupport'
5
5
  gem 'appium_lib'
6
6
  gem 'appium_console'
7
7
  <% end %>
8
- <%- if cucumber? -%>
9
- gem 'allure-cucumber', '2.28.0'
10
- <%- else -%>
8
+ <%- if rspec? -%>
11
9
  gem 'allure-rspec', '2.28.0'
12
10
  gem 'allure-ruby-commons', '2.28.0'
13
11
  <%- end -%>
@@ -19,8 +17,8 @@ gem 'parallel_split_test'
19
17
  gem 'parallel_tests'
20
18
  gem 'rake'
21
19
  gem 'reek'
20
+ gem 'raider_reporter', '~> 0.5'
22
21
  <%- if rspec? -%>
23
- gem 'raider_reporter', '~> 0.3'
24
22
  gem 'rspec-retry'
25
23
  <%- end -%>
26
24
  gem '<%= framework %>'
@@ -1,5 +1,7 @@
1
- allure-results
2
1
  <%- if rspec? -%>
2
+ allure-results
3
+ <%- end -%>
3
4
  raider-results
5
+ <%- if rspec? -%>
4
6
  spec/examples.txt
5
7
  <%- end -%>
@@ -82,11 +82,15 @@ raider g steps [NAME] # Create step definitions
82
82
  raider g scaffold [NAME] # Create page + test + steps
83
83
  ```
84
84
 
85
- <%- if rspec? -%>
86
85
  ## Reporting
87
86
 
87
+ <%- if rspec? -%>
88
88
  Every run writes machine-readable results to `raider-results/` (including `run.json`), next to the usual Allure results.
89
89
  Allure reports are still produced.
90
+ <%- else -%>
91
+ Every run writes machine-readable results to `raider-results/` (including `run.json`). The reporter runs in plugin mode:
92
+ `features/support/env.rb` requires `raider_reporter/cucumber`, so no extra Cucumber formatter flag is needed.
93
+ <%- end -%>
90
94
 
91
95
  To upload runs to Raider, set these environment variables before running the suite:
92
96
 
@@ -95,8 +99,30 @@ export RAIDER_TOKEN=your-token
95
99
  export RAIDER_ENDPOINT=https://your-raider-endpoint
96
100
  ```
97
101
 
102
+ <%- if rspec? -%>
98
103
  Without `RAIDER_TOKEN`, nothing is uploaded and the suite output is unchanged. Failure screenshots are attached to both
99
104
  Allure and Raider. See the [raider_reporter README](https://github.com/RaiderHQ/raider_reporter) for details.
105
+ <%- else -%>
106
+ Without `RAIDER_TOKEN`, nothing is uploaded and the suite output is unchanged. Failure screenshots are attached to
107
+ Raider. See the [raider_reporter README](https://github.com/RaiderHQ/raider_reporter) for details.
108
+ <%- end -%>
109
+
110
+ <%- if azure? && mobile? -%>
111
+ ## CI
112
+
113
+ Azure Pipelines template for mobile projects is not available yet. Use GitHub Actions (`ci:github`) or write your own pipeline; see the raider_reporter README for the Azure setup.
114
+
115
+ <%- elsif azure? -%>
116
+ ## Azure Pipelines
117
+
118
+ `azure-pipelines.yml` runs the suite on `ubuntu-latest` and, on pull requests, comments the Raider results.
119
+
120
+ - Create a pipeline from `azure-pipelines.yml`, then add `RAIDER_TOKEN` (mark it secret) and `RAIDER_ENDPOINT` as pipeline variables.
121
+ - Contribute to pull requests: grant the pipeline's build service identity (`<Project> Build Service (<Organization>)`) the "Contribute to pull requests" permission on the repository, so `raider-reporter comment` can post the comment and status.
122
+ - Azure Repos ignores `pr:` triggers. Add this pipeline as a Build validation branch policy so pull request builds (and the Raider comment) run.
123
+ - Keep the `raider_comment` job in the same stage as the `tests` job.
124
+ - Pull request comments work for Azure Repos only; a GitHub-hosted repo built by Azure Pipelines gets results uploaded but no PR comment.
125
+ - Self-hosted agent? Replace `vmImage: ubuntu-latest` with `pool: { name: Default }`.
100
126
 
101
127
  <%- end -%>
102
128
  ### Sponsors
data/lib/ruby_raider.rb CHANGED
@@ -25,7 +25,7 @@ module RubyRaider
25
25
  params[:name] = project_name
26
26
  parsed_hash = params.transform_keys(&:to_sym)
27
27
  merge_flags(parsed_hash)
28
- return InvokeGenerators.generate_framework(parsed_hash)
28
+ return generate_from_parameters(parsed_hash)
29
29
  end
30
30
 
31
31
  MenuGenerator.new(project_name).generate_choice_menu
@@ -50,6 +50,13 @@ module RubyRaider
50
50
  map 'u' => 'utility'
51
51
 
52
52
  no_tasks do
53
+ def generate_from_parameters(params)
54
+ InvokeGenerators.generate_framework(params)
55
+ rescue InvokeGenerators::InvalidParameters => e
56
+ puts "Invalid parameters: #{e.message}"
57
+ exit 1
58
+ end
59
+
53
60
  def merge_flags(params)
54
61
  params[:accessibility] = true if options[:accessibility]
55
62
  end
data/lib/version CHANGED
@@ -1 +1 @@
1
- 3.4.0
1
+ 3.6.0
@@ -15,6 +15,8 @@ class Generator < Thor::Group
15
15
  def ios?: () -> bool
16
16
  def android?: () -> bool
17
17
  def rspec?: () -> bool
18
+ def azure?: () -> bool
19
+ def github_ci?: () -> bool
18
20
  def selenium?: () -> bool
19
21
  def watir?: () -> bool
20
22
  def web?: () -> bool
@@ -0,0 +1,4 @@
1
+ # Type definitions for AzureGenerator
2
+ class AzureGenerator < Generator
3
+ def generate_azure_pipeline: () -> void
4
+ end
@@ -1,6 +1,11 @@
1
1
  # Type definitions for InvokeGenerators module
2
2
  module InvokeGenerators
3
+ class InvalidParameters < ArgumentError
4
+ end
5
+
3
6
  def self?.generate_framework: (?Hash[Symbol, untyped] structure) -> void
7
+ def self?.validate_ci: (untyped provider) -> void
8
+ def self?.print_mobile_azure_notice: (Hash[Symbol, untyped] structure) -> void
4
9
  def self?.add_generator: (Array[String] generators, *String gens) -> void
5
10
  def self?.invoke_generator: (?Hash[Symbol, untyped] structure) -> void
6
11
  def self?.collect_flags: (Hash[Symbol, untyped] structure) -> Array[String]
@@ -18,7 +18,8 @@ class MenuGenerator
18
18
  def create_framework_options: (Hash[Symbol, untyped] params) -> untyped
19
19
  def select_accessibility: (String framework, String automation_type) -> void
20
20
  def mobile_automation?: (String automation_type) -> bool
21
- def create_framework: (String framework, String automation_type, ?accessibility: bool) -> void
21
+ def select_ci: (String framework, String automation_type, accessibility: bool) -> void
22
+ def create_framework: (String framework, String automation_type, ?accessibility: bool, ?ci_provider: String?) -> void
22
23
  def yes_no_menu_choices: () -> Hash[Symbol, Proc]
23
24
  def select_automation_framework: (untyped menu) -> void
24
25
  def automation_options: (untyped menu) -> void
data/sig/ruby_raider.rbs CHANGED
@@ -8,6 +8,7 @@ module RubyRaider
8
8
 
9
9
  private
10
10
 
11
+ def generate_from_parameters: (Hash[Symbol, untyped] params) -> void
11
12
  def merge_flags: (Hash[Symbol, untyped] params) -> void
12
13
  end
13
14
  end