ruby_raider 3.4.0 → 3.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5141b6656f193315dce72afc9a7096ea48e63eed8a23c348cf38be0978627e90
4
- data.tar.gz: b47a32013c49843ac2511f4bb0188adfcd50a83294fdbe692f8e483f3215ca67
3
+ metadata.gz: 11203a49dfd79c493cfa08d13576ecd10933eea755664e75f569c4860d74294b
4
+ data.tar.gz: 7338d98246ce0e765cb805fbfdb64b1feff88d215aeaecc5cb91184901ea0906
5
5
  SHA512:
6
- metadata.gz: 4840894d57645404ac69faf2ebe7985e59b5df8e653ec8746fb40d23a45e082b0f2708b1d2cc275f7cfa3ce250a009dea61d2022ed6ca96f6c835ac36ed04bca
7
- data.tar.gz: f0eee8de1a42d7ff1440ee7d6700c9d6ffa9370fe53a811b2c99ba03147eed8101edeff5a8e9df0849fe25fb5189d5fd34aab9e07b5ee0642d575d46739f487c
6
+ metadata.gz: 6e4c33e6293efb67fbe0207e62b434a422337df81d8936ff579a776d23ed89cf3d47bb3d22637a6d4ab28082003db155cb2e75c553aa8dba8966cf494ab0e90f
7
+ data.tar.gz: 3eff51512305847c73c9dfd8c83582772fe03fdf232047073428583edd25be07f644e8c133862ae633027e6efae9353255d803b430b0ed44fb9f1384df45dd76
data/README.md CHANGED
@@ -59,8 +59,8 @@ Every generated project comes with:
59
59
 
60
60
  - **Page Object Model** — Base page and component classes with example pages
61
61
  - **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
62
+ - **Allure reporting** (RSpec) — Pre-configured with screenshot capture on failure
63
+ - **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
64
  - **GitHub Actions CI** — Ready-to-use test pipeline
65
65
  - **Rake tasks** — Default, smoke, and regression tasks with tag-based filtering
66
66
  - **Retry support** — RSpec retry with configurable retry count via `RETRY_COUNT` env var
data/RELEASE.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## Release Notes
4
4
 
5
+ ### 3.5.0
6
+
7
+ - 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`.
8
+ - 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`.
9
+ - 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.
10
+ - The generated Readme has a "Reporting" section for Cucumber projects too.
11
+ - Generated Gemfiles now require `raider_reporter` `~> 0.4`.
12
+
5
13
  ### 3.4.0
6
14
 
7
15
  - 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
@@ -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
 
@@ -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 -%>
@@ -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.4'
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,10 +99,14 @@ 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.
100
-
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.
101
108
  <%- end -%>
109
+
102
110
  ### Sponsors
103
111
 
104
112
  This project is tested with BrowserStack.
data/lib/version CHANGED
@@ -1 +1 @@
1
- 3.4.0
1
+ 3.5.0
@@ -62,13 +62,13 @@ describe 'CI pipeline content' do
62
62
  end
63
63
  end
64
64
 
65
- shared_examples 'github raider wiring' do |project_name, file|
65
+ shared_examples 'github raider wiring' do |project_name, file, runner = 'rspec'|
66
66
  subject(:pipeline) { read_generated(project_name, ".github/workflows/#{file}") }
67
67
 
68
68
  let(:steps) { YAML.safe_load(pipeline)['jobs'].values.flat_map { |job| job['steps'] } }
69
69
 
70
70
  let(:test_steps) do
71
- steps.select { |step| step['run'].to_s.include?('rspec') || step['with'].to_h['script'].to_s.include?('rspec') }
71
+ steps.select { |step| step['run'].to_s.include?(runner) || step['with'].to_h['script'].to_s.include?(runner) }
72
72
  end
73
73
 
74
74
  it 'passes Raider settings to every test step' do
@@ -128,29 +128,19 @@ describe 'CI pipeline content' do
128
128
  end
129
129
  end
130
130
 
131
- shared_examples 'github without raider-comment job' do |project_name, file|
132
- subject(:pipeline) { read_generated(project_name, ".github/workflows/#{file}") }
133
-
134
- it 'has no raider-comment job' do
135
- expect(pipeline).not_to include('raider-comment')
136
- expect(pipeline).not_to include('raider-reporter')
137
- end
138
- end
139
-
140
- shared_examples 'github without raider wiring' do |project_name, file|
141
- subject(:pipeline) { read_generated(project_name, ".github/workflows/#{file}") }
131
+ shared_examples 'github allure steps' do |project_name|
132
+ subject(:pipeline) { read_generated(project_name, '.github/workflows/test_pipeline.yml') }
142
133
 
143
- it 'has no Raider settings or artifact' do
144
- expect(pipeline).not_to include('RAIDER_')
145
- expect(pipeline).not_to include('raider-results')
134
+ it 'keeps the Allure steps' do
135
+ expect(pipeline).to include('simple-elf/allure-report-action', 'peaceiris/actions-gh-pages')
146
136
  end
147
137
  end
148
138
 
149
- shared_examples 'github allure steps' do |project_name|
139
+ shared_examples 'github without allure steps' do |project_name|
150
140
  subject(:pipeline) { read_generated(project_name, '.github/workflows/test_pipeline.yml') }
151
141
 
152
- it 'keeps the Allure steps' do
153
- expect(pipeline).to include('simple-elf/allure-report-action', 'peaceiris/actions-gh-pages')
142
+ it 'has no Allure report or gh-pages steps' do
143
+ expect(pipeline).not_to match(/allure|gh-pages/i)
154
144
  end
155
145
  end
156
146
 
@@ -169,9 +159,9 @@ describe 'CI pipeline content' do
169
159
  include_examples 'valid github pipeline', name
170
160
  include_examples 'github cucumber pipeline', name
171
161
  include_examples 'github triggers', name, 'test_pipeline.yml'
172
- include_examples 'github without raider wiring', name, 'test_pipeline.yml'
173
- include_examples 'github without raider-comment job', name, 'test_pipeline.yml'
174
- include_examples 'github allure steps', name
162
+ include_examples 'github raider wiring', name, 'test_pipeline.yml', 'cucumber'
163
+ include_examples 'github raider-comment job', name, 'test_pipeline.yml', %w[build]
164
+ include_examples 'github without allure steps', name
175
165
  end
176
166
 
177
167
  context 'with rspec and watir' do
@@ -184,6 +174,16 @@ describe 'CI pipeline content' do
184
174
  include_examples 'github allure steps', name
185
175
  end
186
176
 
177
+ context 'with cucumber and watir' do
178
+ name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::WATIR}"
179
+ include_examples 'valid github pipeline', name
180
+ include_examples 'github cucumber pipeline', name
181
+ include_examples 'github triggers', name, 'test_pipeline.yml'
182
+ include_examples 'github raider wiring', name, 'test_pipeline.yml', 'cucumber'
183
+ include_examples 'github raider-comment job', name, 'test_pipeline.yml', %w[build]
184
+ include_examples 'github without allure steps', name
185
+ end
186
+
187
187
  appium_jobs = { 'android' => %w[android-tests], 'ios' => %w[ios-tests],
188
188
  'cross_platform' => %w[ios-tests android-tests] }
189
189
 
@@ -198,8 +198,8 @@ describe 'CI pipeline content' do
198
198
  context "with cucumber and #{automation}" do
199
199
  name = "#{FrameworkIndex::CUCUMBER}_#{automation}"
200
200
  include_examples 'github triggers', name, 'appium_pipeline.yml'
201
- include_examples 'github without raider wiring', name, 'appium_pipeline.yml'
202
- include_examples 'github without raider-comment job', name, 'appium_pipeline.yml'
201
+ include_examples 'github raider wiring', name, 'appium_pipeline.yml', 'cucumber'
202
+ include_examples 'github raider-comment job', name, 'appium_pipeline.yml', test_jobs
203
203
  end
204
204
  end
205
205
  end
@@ -122,16 +122,16 @@ describe 'Common file content' do
122
122
  shared_examples 'non-rspec gitignore' do |project_name|
123
123
  subject(:gitignore) { read_generated(project_name, '.gitignore') }
124
124
 
125
- it 'includes allure-results' do
126
- expect(gitignore).to include('allure-results')
125
+ it 'does not include allure-results' do
126
+ expect(gitignore).not_to include('allure-results')
127
127
  end
128
128
 
129
129
  it 'does not include spec/examples.txt' do
130
130
  expect(gitignore).not_to include('spec/examples.txt')
131
131
  end
132
132
 
133
- it 'does not include raider-results' do
134
- expect(gitignore).not_to include('raider-results')
133
+ it 'includes raider-results' do
134
+ expect(gitignore).to include('raider-results')
135
135
  end
136
136
  end
137
137
 
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'content_helper'
4
+
5
+ describe 'Cucumber raider_reporter wiring' do
6
+ screenshot_calls = {
7
+ 'selenium' => 'driver.save_screenshot(screenshot_path)',
8
+ 'watir' => 'browser.screenshot.save(screenshot_path)'
9
+ }
10
+
11
+ AUTOMATION_TYPES.each do |automation|
12
+ context "with cucumber and #{automation}" do
13
+ let(:project_name) { "#{FrameworkIndex::CUCUMBER}_#{automation}" }
14
+ let(:env) { read_generated(project_name, 'features/support/env.rb') }
15
+ let(:screenshot_call) { screenshot_calls.fetch(automation, 'driver.screenshot(screenshot_path)') }
16
+ let(:hook) { env[/^\s*After do.*\z/m] }
17
+ let(:quit_call) { automation == 'watir' ? 'browser.quit' : 'driver.quit' }
18
+
19
+ it 'activates the reporter by requiring raider_reporter/cucumber' do
20
+ expect(env).to include("require 'raider_reporter/cucumber'")
21
+ end
22
+
23
+ it 'does not reference the allure helper' do
24
+ expect(env).not_to match(/AllureHelper|allure_helper/)
25
+ end
26
+
27
+ it 'takes the screenshot only for failed scenarios, inside the guard block' do
28
+ guarded = /if scenario\.failed\?\n\s+Dir\.mktmpdir do \|temp_folder\|\n(?<body>.*?)\n\s+end\n\s+end\nensure/m
29
+ expect(hook.match(guarded)[:body]).to include(screenshot_call)
30
+ end
31
+
32
+ it 'uses a fixed file name in the tmpdir, never the scenario name' do
33
+ expect(env).to include("screenshot_path = File.join(temp_folder, 'screenshot.png')")
34
+ expect(hook).not_to include('scenario.name')
35
+ end
36
+
37
+ it 'quits the driver in an ensure of the After block, without a redundant begin' do
38
+ quit = %w[android ios cross_platform].include?(automation) ? 'driver.quit_driver' : quit_call
39
+ expect(hook).to match(/^\s*After do \|scenario\|\n.*\n^ensure\n\s+#{Regexp.escape(quit)}\nend/m)
40
+ expect(hook).not_to match(/^\s+begin$/)
41
+ end
42
+
43
+ it 'attaches the screenshot path before quitting the driver' do
44
+ attach = "RaiderReporter.attach('screenshot', screenshot_path, type: :png)"
45
+ expect(env).to include(attach)
46
+ expect(env.index(screenshot_call)).to be < env.index(attach)
47
+ expect(env.index(attach)).to be < env.index(/driver\.quit|browser\.quit/, env.index(attach))
48
+ end
49
+
50
+ it 'does not generate the allure helper' do
51
+ expect(File).not_to exist(File.join(project_name, 'helpers/allure_helper.rb'))
52
+ end
53
+
54
+ it 'does not mention Allure in any generated file' do
55
+ files = Dir.glob("#{project_name}/**/*", File::FNM_DOTMATCH).select { |f| File.file?(f) }
56
+ expect(files.select { |f| File.read(f).match?(/allure/i) }).to be_empty
57
+ end
58
+
59
+ it 'does not create an allure-results folder' do
60
+ expect(File).not_to exist(File.join(project_name, 'allure-results'))
61
+ end
62
+ end
63
+ end
64
+ end
@@ -58,8 +58,8 @@ describe 'Gemfile content' do
58
58
  expect(gemfile).to include("gem 'cucumber'")
59
59
  end
60
60
 
61
- it 'includes allure-cucumber' do
62
- expect(gemfile).to include("gem 'allure-cucumber'")
61
+ it 'does not include allure-cucumber' do
62
+ expect(gemfile).not_to include('allure')
63
63
  end
64
64
 
65
65
  it 'includes rspec as cucumber dependency' do
@@ -127,7 +127,7 @@ describe 'Gemfile content' do
127
127
  let(:gemfile) { read_generated("#{FrameworkIndex::RSPEC}_#{automation}", 'Gemfile') }
128
128
 
129
129
  it 'includes raider_reporter' do
130
- expect(gemfile).to include("gem 'raider_reporter', '~> 0.3'")
130
+ expect(gemfile).to include("gem 'raider_reporter', '~> 0.4'")
131
131
  end
132
132
 
133
133
  it 'keeps allure gems' do
@@ -142,12 +142,12 @@ describe 'Gemfile content' do
142
142
  context "with cucumber and #{automation}" do
143
143
  let(:gemfile) { read_generated("#{FrameworkIndex::CUCUMBER}_#{automation}", 'Gemfile') }
144
144
 
145
- it 'does not include raider_reporter' do
146
- expect(gemfile).not_to include('raider_reporter')
145
+ it 'includes raider_reporter' do
146
+ expect(gemfile).to include("gem 'raider_reporter', '~> 0.4'")
147
147
  end
148
148
 
149
- it 'keeps allure-cucumber' do
150
- expect(gemfile).to include("gem 'allure-cucumber', '2.28.0'")
149
+ it 'drops allure-cucumber' do
150
+ expect(gemfile).not_to include('allure')
151
151
  end
152
152
 
153
153
  it 'pins ruby_raider to the generator major.minor' do
@@ -221,13 +221,11 @@ describe 'Helper file content' do
221
221
  name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::SELENIUM}"
222
222
  it_behaves_like 'valid driver helper', name
223
223
  it_behaves_like 'selenium driver helper', name
224
- it_behaves_like 'valid allure helper', name
225
224
  end
226
225
 
227
226
  context 'with cucumber and watir' do
228
227
  name = "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::WATIR}"
229
228
  it_behaves_like 'valid browser helper', name
230
- it_behaves_like 'valid allure helper', name
231
229
  end
232
230
 
233
231
  # --- Mobile contexts (with AppiumRecorder) ---
@@ -255,10 +253,8 @@ describe 'Helper file content' do
255
253
  end
256
254
 
257
255
  context "with cucumber and #{automation}" do
258
- it 'has no raider reporter wiring' do
259
- project = "#{FrameworkIndex::CUCUMBER}_#{automation}"
260
- files = Dir.glob("#{project}/**/*", File::FNM_DOTMATCH).select { |f| File.file?(f) }
261
- expect(files.select { |f| File.read(f).match?(/raider_reporter|RaiderReporter/) }).to be_empty
256
+ it 'does not generate the allure helper' do
257
+ expect(File).not_to exist("#{FrameworkIndex::CUCUMBER}_#{automation}/helpers/allure_helper.rb")
262
258
  end
263
259
  end
264
260
  end
@@ -22,9 +22,19 @@ describe 'Generated Readme content' do
22
22
  end
23
23
 
24
24
  context "with cucumber and #{automation}" do
25
- it 'has no Reporting section' do
26
- readme = read_generated("#{FrameworkIndex::CUCUMBER}_#{automation}", 'Readme.md')
27
- expect(readme).not_to include('RAIDER_TOKEN')
25
+ subject(:readme) { read_generated("#{FrameworkIndex::CUCUMBER}_#{automation}", 'Readme.md') }
26
+
27
+ it 'has a Reporting section' do
28
+ expect(readme).to include('## Reporting')
29
+ end
30
+
31
+ it 'documents local results, upload settings, plugin mode and the raider_reporter README' do
32
+ expect(readme).to include('raider-results/', 'RAIDER_TOKEN', 'RAIDER_ENDPOINT', 'features/support/env.rb',
33
+ 'https://github.com/RaiderHQ/raider_reporter')
34
+ end
35
+
36
+ it 'does not mention Allure' do
37
+ expect(readme).not_to match(/allure/i)
28
38
  end
29
39
  end
30
40
  end
@@ -110,6 +110,10 @@ describe 'Test file content' do
110
110
  it 'has default profile' do
111
111
  expect(config).to include('default:')
112
112
  end
113
+
114
+ it 'uses the pretty formatter, with the reporter activated from env.rb' do
115
+ expect(config.strip).to eq('default: --format pretty --publish-quiet --retry 0')
116
+ end
113
117
  end
114
118
 
115
119
  # --- RSpec contexts ---
@@ -84,7 +84,7 @@ describe 'End-to-End Project Generation and Execution' do
84
84
  # Helper to run Cucumber tests
85
85
  def run_cucumber(project_name)
86
86
  puts "\n🥒 Running Cucumber tests in #{project_name}..."
87
- result = run_in_project(project_name, 'bundle exec cucumber features/ --format pretty', timeout: 120)
87
+ result = run_in_project(project_name, 'HEADLESS=true bundle exec cucumber features/ --format pretty', timeout: 120)
88
88
 
89
89
  puts result[:stdout] if result[:stdout].length.positive?
90
90
 
@@ -104,10 +104,10 @@ describe 'End-to-End Project Generation and Execution' do
104
104
  expect(bundle_install(project)).to be true
105
105
  end
106
106
 
107
- it 'resolves raider_reporter 0.3 from RubyGems and ships the raider-reporter executable', :aggregate_failures do
107
+ it 'resolves raider_reporter 0.4 from RubyGems and ships the raider-reporter executable', :aggregate_failures do
108
108
  skip 'Bundle install failed' unless bundle_install(project)
109
109
 
110
- expect(File.read(File.join(project, 'Gemfile.lock'))).to match(/^ raider_reporter \(0\.3\.\d+\)$/)
110
+ expect(File.read(File.join(project, 'Gemfile.lock'))).to match(/^ raider_reporter \(0\.4\.\d+\)$/)
111
111
  result = run_in_project(project, 'bundle exec raider-reporter --help', timeout: 60)
112
112
  expect(result[:exit_code]).to eq(0), "STDOUT: #{result[:stdout]}\nSTDERR: #{result[:stderr]}"
113
113
  expect(result[:stdout] + result[:stderr]).to include('raider-reporter comment')
@@ -162,6 +162,85 @@ describe 'End-to-End Project Generation and Execution' do
162
162
  "STDOUT: #{result[:stdout]}\n" \
163
163
  "STDERR: #{result[:stderr]}"
164
164
  end
165
+
166
+ it 'resolves raider_reporter 0.4 from RubyGems and requires its Cucumber plugin', :aggregate_failures do
167
+ skip 'Bundle install failed' unless bundle_install(project)
168
+
169
+ lockfile = File.read(File.join(project, 'Gemfile.lock'))
170
+ expect(lockfile).to match(/^ raider_reporter \(0\.4\.\d+\)$/)
171
+ expect(File.read(File.join(project, 'features/support/env.rb'))).to include("require 'raider_reporter/cucumber'")
172
+ end
173
+
174
+ it 'prints pretty output and keeps the exit status of a failing Cucumber run', :aggregate_failures, :slow do
175
+ skip 'Bundle install failed' unless bundle_install(project)
176
+
177
+ result = run_cucumber_with_failure(project)
178
+
179
+ expect(result[:stdout]).to include('Feature: Reporter failure')
180
+ expect(result[:stdout]).to include('Scenario: A deliberately failing scenario')
181
+ expect(result[:stdout]).to match(/\d+ scenarios? \(\d+ failed/)
182
+ expect(result[:exit_code]).to eq(1)
183
+ end
184
+
185
+ it 'writes raider-results/run.json listing every scenario with a failing scenario screenshot',
186
+ :aggregate_failures, :slow do
187
+ skip 'Bundle install failed' unless bundle_install(project)
188
+
189
+ result = run_cucumber_with_failure(project)
190
+ summary = result[:stdout].match(/(\d+) scenarios? \((?:(\d+) failed)?/)
191
+ expect(summary).not_to be_nil, "No Cucumber summary line.\nSTDOUT: #{result[:stdout]}\nSTDERR: #{result[:stderr]}"
192
+
193
+ run = JSON.parse(File.read(File.join(project, 'raider-results', 'run.json')))
194
+ expect(run['schema_version']).to eq(1)
195
+ expect(run['results'].size).to eq(summary[1].to_i)
196
+ expect(run['results'].count { |r| r['status'] == 'failed' }).to eq(summary[2].to_i)
197
+
198
+ failing = run['results'].find { |r| r['full_name'] == 'Reporter failure: A deliberately failing scenario' }
199
+ expect(failing).not_to be_nil, "Scenario missing from run.json: #{run['results'].map { |r| r['full_name'] }}"
200
+ expect(failing['status']).to eq('failed')
201
+ expect(failing['file_path']).to eq('features/reporter_failure.feature')
202
+ expect(failing['failure']['message']).to start_with(
203
+ 'Then the reporter records this failure (features/reporter_failure.feature:5)'
204
+ )
205
+ screenshot = failing['attachments'].find { |a| a['name'] == 'screenshot' }
206
+ expect(screenshot).not_to be_nil, "No screenshot attachment: #{failing['attachments']}"
207
+ expect(screenshot['content_type']).to eq('image/png')
208
+ end
209
+ end
210
+
211
+ # Runs the project's features plus a deliberately failing scenario, then removes that scenario again
212
+ def run_cucumber_with_failure(project)
213
+ add_failing_cucumber_scenario(project)
214
+ FileUtils.rm_rf(File.join(project, 'raider-results'))
215
+ run_cucumber(project)
216
+ ensure
217
+ remove_failing_cucumber_scenario(project)
218
+ end
219
+
220
+ # Adds a scenario that always fails at its last step, after the browser has been started
221
+ def add_failing_cucumber_scenario(project)
222
+ File.write(File.join(project, 'features/reporter_failure.feature'), <<~FEATURE)
223
+ Feature: Reporter failure
224
+
225
+ Scenario: A deliberately failing scenario
226
+ Given the reporter has a started scenario
227
+ Then the reporter records this failure
228
+ FEATURE
229
+ File.write(File.join(project, 'features/step_definitions/reporter_failure_steps.rb'), <<~STEPS)
230
+ # frozen_string_literal: true
231
+
232
+ Given('the reporter has a started scenario') {}
233
+
234
+ Then('the reporter records this failure') do
235
+ raise 'deliberate failure for raider_reporter'
236
+ end
237
+ STEPS
238
+ end
239
+
240
+ # Keeps the deliberate failure from leaking into the other examples that share the project
241
+ def remove_failing_cucumber_scenario(project)
242
+ FileUtils.rm_f(File.join(project, 'features/reporter_failure.feature'))
243
+ FileUtils.rm_f(File.join(project, 'features/step_definitions/reporter_failure_steps.rb'))
165
244
  end
166
245
 
167
246
  # Test Web Frameworks (these can run without external services)
@@ -5,8 +5,12 @@ require_relative '../spec_helper'
5
5
 
6
6
  describe HelpersGenerator do
7
7
  shared_examples 'creates common helpers' do |name|
8
- it 'creates an allure helper file' do
9
- expect(File).to exist("#{name}/helpers/allure_helper.rb")
8
+ it 'creates an allure helper file only for rspec projects' do
9
+ if name.start_with?(FrameworkIndex::CUCUMBER)
10
+ expect(File).not_to exist("#{name}/helpers/allure_helper.rb")
11
+ else
12
+ expect(File).to exist("#{name}/helpers/allure_helper.rb")
13
+ end
10
14
  end
11
15
  end
12
16
 
@@ -101,5 +105,4 @@ describe HelpersGenerator do
101
105
  include_examples 'creates cucumber helpers', "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::CROSS_PLATFORM}"
102
106
  include_examples 'creates cross platform helpers', "#{FrameworkIndex::CUCUMBER}_#{AutomationIndex::CROSS_PLATFORM}"
103
107
  end
104
-
105
108
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_raider
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Agustin Pequeno
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-10-11 00:00:00.000000000 Z
10
+ date: 2026-10-12 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake
@@ -306,6 +306,7 @@ files:
306
306
  - spec/integration/content/common_content_spec.rb
307
307
  - spec/integration/content/config_content_spec.rb
308
308
  - spec/integration/content/content_helper.rb
309
+ - spec/integration/content/cucumber_reporter_content_spec.rb
309
310
  - spec/integration/content/gemfile_content_spec.rb
310
311
  - spec/integration/content/helper_content_spec.rb
311
312
  - spec/integration/content/page_content_spec.rb