ruby_raider 3.8.0 → 3.9.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: 9cd1d87871eeb4bad99f5952f35a7f81da1f54d9170536ebd959ebe19403d63d
4
- data.tar.gz: 0bdb788bce2e8245483176ebe5118ff046fef892ae8767d74986384d9747deba
3
+ metadata.gz: ed3634de8115662d6148059e139a55f330a07fe9736ac82efbc439a256dd5747
4
+ data.tar.gz: 2c88f2ecb9c18c6f787ac216ef89de3e2dd626c1d1671c990b313d3df29b0e4d
5
5
  SHA512:
6
- metadata.gz: 0a9f31493361abd7af6a78f8afe18a7d6f82569c364ed08c17445705bc3e0e5ef770a0da54b927139996393622a49306433b8aa0deccd61483a8af724b432fcc
7
- data.tar.gz: 85c9d92cf395f858f4c2977a382c96385ebb82992cdc6ad100477ed8c9d91f34a6ea302a3cea26a612e5b682b4ad1b3d398449420abc6e5f58c3b5eaa8ccebbb
6
+ metadata.gz: f534bbb7ae8a9ae5870f905376bf1fc6bdc2189729ccb01fd5d76c8a0886255b1693a716e28cebd87d892ce3646b17dfca9a2b887c35349431bae2d47573fc05
7
+ data.tar.gz: 15eba78213eaee9100e1bc9ec5959fa5a8f89843b65fd77259db1571f74684ac01e665ab36a1ff152fb9ec3b8b96090acea9edf3e5d5c7ccd145f5b88c450b67
data/README.md CHANGED
@@ -60,7 +60,7 @@ Every generated project comes with:
60
60
 
61
61
  - **Page Object Model** — Base page and component classes with example pages
62
62
  - **Test examples** — Working login tests against the [Raider Test Store](https://raider-test-site.onrender.com/)
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; generated CI runs the suite through `raider-reporter exec` with `RAIDER_QUARANTINE`, so quarantined tests do not fail the build
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; generated CI runs the suite through `raider-reporter exec` with `RAIDER_QUARANTINE`, so quarantined tests do not fail the build; an opt-in `raider-gate` job (`RAIDER_GATE=1`) fails CI when the Raider quality gate fails
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
@@ -31,7 +31,7 @@ jobs:
31
31
  condition: always()
32
32
  inputs: { targetPath: raider-results, artifact: raider-results-$(System.JobPositionInPhase)-$(System.JobAttempt) }
33
33
  - job: raider_comment
34
- dependsOn: tests
34
+ dependsOn: [tests, raider_gate]
35
35
  condition: and(always(), eq(variables['Build.Reason'], 'PullRequest'))
36
36
  steps:
37
37
  - task: UseRubyVersion@0
@@ -43,3 +43,16 @@ jobs:
43
43
  RAIDER_TOKEN: $(RAIDER_TOKEN)
44
44
  RAIDER_ENDPOINT: $(RAIDER_ENDPOINT)
45
45
  SYSTEM_ACCESSTOKEN: $(System.AccessToken)
46
+ - job: raider_gate
47
+ dependsOn: tests
48
+ condition: and(always(), eq(variables['RAIDER_GATE'], '1'))
49
+ steps:
50
+ - task: UseRubyVersion@0
51
+ inputs: { versionSpec: '3.4' }
52
+ - script: bundle install
53
+ - script: bundle exec raider-reporter gate
54
+ displayName: Wait for the Raider quality gate
55
+ env:
56
+ RAIDER_TOKEN: $(RAIDER_TOKEN)
57
+ RAIDER_ENDPOINT: $(RAIDER_ENDPOINT)
58
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
@@ -50,7 +50,7 @@ jobs:
50
50
  if-no-files-found: ignore
51
51
 
52
52
  raider-comment:
53
- needs: [build]
53
+ needs: [build, raider-gate]
54
54
  if: always() && github.event_name == 'pull_request'
55
55
  runs-on: ubuntu-latest
56
56
  permissions:
@@ -67,3 +67,21 @@ jobs:
67
67
  RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
68
68
  RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
69
69
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
70
+
71
+ raider-gate:
72
+ needs: [build]
73
+ if: always() && vars.RAIDER_GATE == '1'
74
+ runs-on: ubuntu-latest
75
+ permissions:
76
+ contents: read
77
+ statuses: write
78
+ steps:
79
+ - uses: actions/checkout@v4
80
+ - uses: ruby/setup-ruby@v1
81
+ with: { ruby-version: 3.4.0, bundler-cache: true }
82
+ - name: Wait for the Raider quality gate
83
+ run: bundle exec raider-reporter gate
84
+ env:
85
+ RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
86
+ RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
87
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -55,6 +55,10 @@ jobs:
55
55
  RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
56
56
  RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
57
57
  RAIDER_QUARANTINE: "1"
58
+ <%- if cross_platform? -%>
59
+ RAIDER_SHARD_INDEX: "1"
60
+ RAIDER_SHARD_TOTAL: "2"
61
+ <%- end -%>
58
62
 
59
63
  - name: Upload Raider results
60
64
  uses: actions/upload-artifact@v4
@@ -115,6 +119,10 @@ jobs:
115
119
  RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
116
120
  RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
117
121
  RAIDER_QUARANTINE: "1"
122
+ <%- if cross_platform? -%>
123
+ RAIDER_SHARD_INDEX: "2"
124
+ RAIDER_SHARD_TOTAL: "2"
125
+ <%- end -%>
118
126
 
119
127
  - name: Upload Raider results
120
128
  uses: actions/upload-artifact@v4
@@ -126,7 +134,7 @@ jobs:
126
134
  <%- end -%>
127
135
 
128
136
  raider-comment:
129
- needs: [<%= [('ios-tests' if ios? || cross_platform?), ('android-tests' if android? || cross_platform?)].compact.join(', ') %>]
137
+ needs: [<%= [('ios-tests' if ios? || cross_platform?), ('android-tests' if android? || cross_platform?)].compact.join(', ') %>, raider-gate]
130
138
  if: always() && github.event_name == 'pull_request'
131
139
  runs-on: ubuntu-latest
132
140
  permissions:
@@ -143,3 +151,21 @@ jobs:
143
151
  RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
144
152
  RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
145
153
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
154
+
155
+ raider-gate:
156
+ needs: [<%= [('ios-tests' if ios? || cross_platform?), ('android-tests' if android? || cross_platform?)].compact.join(', ') %>]
157
+ if: always() && vars.RAIDER_GATE == '1'
158
+ runs-on: ubuntu-latest
159
+ permissions:
160
+ contents: read
161
+ statuses: write
162
+ steps:
163
+ - uses: actions/checkout@v4
164
+ - uses: ruby/setup-ruby@v1
165
+ with: { ruby-version: 3.4.0, bundler-cache: true }
166
+ - name: Wait for the Raider quality gate
167
+ run: bundle exec raider-reporter gate
168
+ env:
169
+ RAIDER_TOKEN: ${{ secrets.RAIDER_TOKEN }}
170
+ RAIDER_ENDPOINT: ${{ vars.RAIDER_ENDPOINT }}
171
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -13,7 +13,7 @@ gem 'parallel_split_test'
13
13
  gem 'parallel_tests'
14
14
  gem 'rake'
15
15
  gem 'reek'
16
- gem 'raider_reporter', '~> 0.8'
16
+ gem 'raider_reporter', '~> 0.9'
17
17
  <%- if rspec? -%>
18
18
  gem 'rspec-retry'
19
19
  <%- end -%>
@@ -115,6 +115,26 @@ CI runs the suite through `bundle exec raider-reporter exec -- …` with `RAIDER
115
115
  Raider still run and are still reported (as `quarantined`), and a build whose only failures are quarantined stays green.
116
116
  Local runs keep quarantine off. To turn it off in CI, remove `RAIDER_QUARANTINE` from the pipeline.
117
117
 
118
+ <%- end -%>
119
+ <%- unless azure? && mobile? -%>
120
+ ### Quality gate
121
+
122
+ The `<%= azure? ? 'raider_gate' : 'raider-gate' %>` CI job runs `bundle exec raider-reporter gate` after the tests and
123
+ fails the pipeline when the Raider quality gate fails. It is off until you turn it on:
124
+
125
+ - set the CI variable `RAIDER_GATE=1` (<%= azure? ? 'a pipeline variable' : 'a repository variable under Settings → Secrets and variables → Actions → Variables' %>);
126
+ - turn on rules under the project's Gate page in Raider: a minimum pass rate, no new failures against the default
127
+ branch, no new flaky tests;
128
+ - optionally require the `raider/gate` check in branch protection.
129
+
130
+ `raider-reporter gate` exits 1 when the gate fails, naming the failed rules, and 2 when it gets no verdict (timeout,
131
+ Raider unreachable, token rejected, build not found). `RAIDER_GATE_TIMEOUT` sets how long it waits, in seconds
132
+ (default 600). The job stays off by default because a project without `RAIDER_TOKEN`, or a pull request from a fork,
133
+ would exit 2 on every run.
134
+
135
+ Parallel test jobs that upload to one build must each set `RAIDER_SHARD_TOTAL` (the number of jobs) and
136
+ `RAIDER_SHARD_INDEX` (1 to that number), so the gate waits for all of them instead of judging the first one to finish.
137
+
118
138
  <%- end -%>
119
139
  <%- if azure? && mobile? -%>
120
140
  ## CI
data/lib/version CHANGED
@@ -1 +1 @@
1
- 3.8.0
1
+ 3.9.0
@@ -54,16 +54,32 @@ describe 'Azure Pipelines content' do
54
54
  expect(yml['variables']['HEADLESS']).to eq('true')
55
55
  end
56
56
 
57
- it 'has a raider_comment job for pull requests' do
57
+ it 'has a raider_comment job for pull requests that waits for the gate job but runs even when it is skipped' do
58
58
  comment = yml['jobs'][1]
59
59
  expect(comment['job']).to eq('raider_comment')
60
- expect(comment['dependsOn']).to eq('tests')
60
+ expect(comment['dependsOn']).to eq(%w[tests raider_gate])
61
61
  expect(comment['condition']).to eq("and(always(), eq(variables['Build.Reason'], 'PullRequest'))")
62
62
  last = comment['steps'].last
63
63
  expect(last['script']).to eq('bundle exec raider-reporter comment')
64
64
  expect(last['env']).to include('SYSTEM_ACCESSTOKEN' => '$(System.AccessToken)')
65
65
  end
66
66
 
67
+ it 'has a raider_gate job that runs only when RAIDER_GATE is 1' do
68
+ gate = yml['jobs'][2]
69
+ expect(yml['jobs'].size).to eq(3)
70
+ expect(gate['job']).to eq('raider_gate')
71
+ expect(gate['dependsOn']).to eq('tests')
72
+ expect(gate['condition']).to eq("and(always(), eq(variables['RAIDER_GATE'], '1'))")
73
+ end
74
+
75
+ it 'sets up Ruby in the raider_gate job and runs the gate with the token env' do
76
+ gate = yml['jobs'][2]
77
+ expect(gate['steps'].first).to eq('task' => 'UseRubyVersion@0', 'inputs' => { 'versionSpec' => '3.4' })
78
+ expect(gate['steps'].filter_map { |s| s['script'] }).to eq(['bundle install', 'bundle exec raider-reporter gate'])
79
+ expect(gate['steps'].last['env']).to eq('RAIDER_TOKEN' => '$(RAIDER_TOKEN)', 'RAIDER_ENDPOINT' => '$(RAIDER_ENDPOINT)',
80
+ 'SYSTEM_ACCESSTOKEN' => '$(System.AccessToken)')
81
+ end
82
+
67
83
  it 'has triggers, pool and the self-hosted hint' do
68
84
  expect(yml['trigger']['branches']['include']).to include('main', 'master')
69
85
  expect(yml['pr']['branches']['include']).to include('*')
@@ -84,7 +100,7 @@ describe 'Azure Pipelines content' do
84
100
  readme = read_generated(name, 'Readme.md')
85
101
  expect(readme).to include('## Azure Pipelines', 'RAIDER_TOKEN', 'Contribute to pull requests',
86
102
  'pool: { name: Default }', 'Build validation branch policy',
87
- 'same stage')
103
+ 'same stage', 'raider_gate', 'RAIDER_GATE=1', 'RAIDER_SHARD_TOTAL', 'RAIDER_SHARD_INDEX')
88
104
  expect(readme).not_to match(/GitHub Actions/i)
89
105
  end
90
106
  end
@@ -92,7 +92,7 @@ describe 'CI pipeline content' do
92
92
 
93
93
  it 'uploads raider-results as an artifact even on failure in every job' do
94
94
  uploads = steps.select { |step| step['uses'] == 'actions/upload-artifact@v4' }
95
- expect(uploads.size).to eq(YAML.safe_load(pipeline)['jobs'].except('raider-comment').size)
95
+ expect(uploads.size).to eq(YAML.safe_load(pipeline)['jobs'].except('raider-comment', 'raider-gate').size)
96
96
  uploads.each do |upload|
97
97
  expect(upload['with']['path']).to eq('raider-results/')
98
98
  expect(upload['if']).to eq('always()')
@@ -107,15 +107,16 @@ describe 'CI pipeline content' do
107
107
  let(:job) { jobs['raider-comment'] }
108
108
 
109
109
  it 'is a valid workflow with exactly the expected jobs' do
110
- expect(jobs.keys).to match_array(test_jobs + ['raider-comment'])
110
+ expect(jobs.keys).to match_array(test_jobs + %w[raider-comment raider-gate])
111
111
  end
112
112
 
113
- it 'needs every test job' do
114
- expect(job['needs']).to match_array(test_jobs)
113
+ it 'needs every test job and the gate job, so the comment carries the final gate line' do
114
+ expect(job['needs']).to match_array(test_jobs + %w[raider-gate])
115
115
  end
116
116
 
117
- it 'runs always, on pull requests only' do
117
+ it 'runs always, on pull requests only, so a skipped or failed gate job does not skip it' do
118
118
  expect(job['if']).to eq("always() && github.event_name == 'pull_request'")
119
+ expect(job['if']).to start_with('always()')
119
120
  expect(job['runs-on']).to eq('ubuntu-latest')
120
121
  end
121
122
 
@@ -151,6 +152,62 @@ describe 'CI pipeline content' do
151
152
  end
152
153
  end
153
154
 
155
+ shared_examples 'github raider-gate job' do |project_name, file, test_jobs|
156
+ subject(:pipeline) { read_generated(project_name, ".github/workflows/#{file}") }
157
+
158
+ let(:jobs) { YAML.safe_load(pipeline)['jobs'] }
159
+ let(:gate_job) { jobs['raider-gate'] }
160
+
161
+ it 'needs every test job and runs always when RAIDER_GATE is 1, on push and pull requests' do
162
+ expect(gate_job['needs']).to match_array(test_jobs)
163
+ expect(gate_job['if']).to eq("always() && vars.RAIDER_GATE == '1'")
164
+ expect(gate_job['runs-on']).to eq('ubuntu-latest')
165
+ end
166
+
167
+ it 'can read the code and write statuses only' do
168
+ expect(gate_job['permissions']).to eq('contents' => 'read', 'statuses' => 'write')
169
+ end
170
+
171
+ it 'checks out, sets up the same Ruby as the test jobs and runs the gate' do
172
+ steps = gate_job['steps']
173
+ expect(steps[0]).to eq('uses' => 'actions/checkout@v4')
174
+ test_ruby = jobs.values_at(*test_jobs).flat_map { |j| j['steps'] }
175
+ .find { |step| step['uses'] == 'ruby/setup-ruby@v1' }['with']['ruby-version']
176
+ expect(steps[1]).to eq('uses' => 'ruby/setup-ruby@v1', 'with' => { 'ruby-version' => test_ruby, 'bundler-cache' => true })
177
+ expect(steps[2]).to eq('name' => 'Wait for the Raider quality gate',
178
+ 'run' => 'bundle exec raider-reporter gate',
179
+ 'env' => { 'RAIDER_TOKEN' => '${{ secrets.RAIDER_TOKEN }}',
180
+ 'RAIDER_ENDPOINT' => '${{ vars.RAIDER_ENDPOINT }}',
181
+ 'GITHUB_TOKEN' => '${{ secrets.GITHUB_TOKEN }}' })
182
+ expect(steps.size).to eq(3)
183
+ end
184
+ end
185
+
186
+ shared_examples 'github appium shards' do |project_name, runner, shards|
187
+ subject(:pipeline) { read_generated(project_name, '.github/workflows/appium_pipeline.yml') }
188
+
189
+ let(:jobs) { YAML.safe_load(pipeline)['jobs'] }
190
+
191
+ def test_step(job, runner)
192
+ job['steps'].find { |step| step['run'].to_s.include?(runner) || step['with'].to_h['script'].to_s.include?(runner) }
193
+ end
194
+
195
+ if shards
196
+ it 'gives each platform job its own shard of two, so the gate waits for both' do
197
+ shards.each do |job_name, index|
198
+ expect(test_step(jobs[job_name], runner)['env'])
199
+ .to include('RAIDER_SHARD_INDEX' => index, 'RAIDER_SHARD_TOTAL' => '2')
200
+ end
201
+ end
202
+ else
203
+ it 'sets no shard env for a single platform' do
204
+ jobs.except('raider-comment', 'raider-gate').each_value do |job|
205
+ expect(test_step(job, runner)['env'].keys).not_to include('RAIDER_SHARD_INDEX', 'RAIDER_SHARD_TOTAL')
206
+ end
207
+ end
208
+ end
209
+ end
210
+
154
211
  context 'with rspec and selenium' do
155
212
  name = "#{FrameworkIndex::RSPEC}_#{AutomationIndex::SELENIUM}"
156
213
  include_examples 'valid github pipeline', name
@@ -158,6 +215,7 @@ describe 'CI pipeline content' do
158
215
  include_examples 'github triggers', name, 'test_pipeline.yml'
159
216
  include_examples 'github raider wiring', name, 'test_pipeline.yml'
160
217
  include_examples 'github raider-comment job', name, 'test_pipeline.yml', %w[build]
218
+ include_examples 'github raider-gate job', name, 'test_pipeline.yml', %w[build]
161
219
  include_examples 'github without allure steps', name
162
220
  end
163
221
 
@@ -168,6 +226,7 @@ describe 'CI pipeline content' do
168
226
  include_examples 'github triggers', name, 'test_pipeline.yml'
169
227
  include_examples 'github raider wiring', name, 'test_pipeline.yml', 'cucumber'
170
228
  include_examples 'github raider-comment job', name, 'test_pipeline.yml', %w[build]
229
+ include_examples 'github raider-gate job', name, 'test_pipeline.yml', %w[build]
171
230
  include_examples 'github without allure steps', name
172
231
  end
173
232
 
@@ -178,6 +237,7 @@ describe 'CI pipeline content' do
178
237
  include_examples 'github triggers', name, 'test_pipeline.yml'
179
238
  include_examples 'github raider wiring', name, 'test_pipeline.yml'
180
239
  include_examples 'github raider-comment job', name, 'test_pipeline.yml', %w[build]
240
+ include_examples 'github raider-gate job', name, 'test_pipeline.yml', %w[build]
181
241
  include_examples 'github without allure steps', name
182
242
  end
183
243
 
@@ -188,25 +248,32 @@ describe 'CI pipeline content' do
188
248
  include_examples 'github triggers', name, 'test_pipeline.yml'
189
249
  include_examples 'github raider wiring', name, 'test_pipeline.yml', 'cucumber'
190
250
  include_examples 'github raider-comment job', name, 'test_pipeline.yml', %w[build]
251
+ include_examples 'github raider-gate job', name, 'test_pipeline.yml', %w[build]
191
252
  include_examples 'github without allure steps', name
192
253
  end
193
254
 
194
255
  appium_jobs = { 'android' => %w[android-tests], 'ios' => %w[ios-tests],
195
256
  'cross_platform' => %w[ios-tests android-tests] }
196
257
 
258
+ appium_shards = { 'cross_platform' => { 'ios-tests' => '1', 'android-tests' => '2' } }
259
+
197
260
  appium_jobs.each do |automation, test_jobs|
198
261
  context "with rspec and #{automation}" do
199
262
  name = "#{FrameworkIndex::RSPEC}_#{automation}"
263
+ include_examples 'github appium shards', name, 'rspec', appium_shards[automation]
200
264
  include_examples 'github raider-comment job', name, 'appium_pipeline.yml', test_jobs
265
+ include_examples 'github raider-gate job', name, 'appium_pipeline.yml', test_jobs
201
266
  include_examples 'github triggers', name, 'appium_pipeline.yml'
202
267
  include_examples 'github raider wiring', name, 'appium_pipeline.yml'
203
268
  end
204
269
 
205
270
  context "with cucumber and #{automation}" do
206
271
  name = "#{FrameworkIndex::CUCUMBER}_#{automation}"
272
+ include_examples 'github appium shards', name, 'cucumber', appium_shards[automation]
207
273
  include_examples 'github triggers', name, 'appium_pipeline.yml'
208
274
  include_examples 'github raider wiring', name, 'appium_pipeline.yml', 'cucumber'
209
275
  include_examples 'github raider-comment job', name, 'appium_pipeline.yml', test_jobs
276
+ include_examples 'github raider-gate job', name, 'appium_pipeline.yml', test_jobs
210
277
  end
211
278
  end
212
279
  end
@@ -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.8'")
130
+ expect(gemfile).to include("gem 'raider_reporter', '~> 0.9'")
131
131
  end
132
132
 
133
133
  it 'has no allure gems' do
@@ -143,7 +143,7 @@ describe 'Gemfile content' do
143
143
  let(:gemfile) { read_generated("#{FrameworkIndex::CUCUMBER}_#{automation}", 'Gemfile') }
144
144
 
145
145
  it 'includes raider_reporter' do
146
- expect(gemfile).to include("gem 'raider_reporter', '~> 0.8'")
146
+ expect(gemfile).to include("gem 'raider_reporter', '~> 0.9'")
147
147
  end
148
148
 
149
149
  it 'drops allure-cucumber' do
@@ -20,6 +20,13 @@ describe 'Generated Readme content' do
20
20
  expect(readme).to include('### Quarantine', 'RAIDER_QUARANTINE', 'raider-reporter exec')
21
21
  end
22
22
 
23
+ it 'explains the quality gate' do
24
+ expect(readme).to include('### Quality gate', 'RAIDER_GATE=1', 'Gate page', 'raider/gate',
25
+ 'raider-reporter gate', 'raider-gate', 'exits 1 when the gate fails',
26
+ '2 when it gets no verdict', 'RAIDER_GATE_TIMEOUT', 'RAIDER_SHARD_TOTAL',
27
+ 'RAIDER_SHARD_INDEX')
28
+ end
29
+
23
30
  it 'points to the local HTML report' do
24
31
  expect(readme).to include('raider-results/index.html')
25
32
  expect(readme).not_to match(/allure/i)
@@ -42,6 +49,13 @@ describe 'Generated Readme content' do
42
49
  expect(readme).to include('### Quarantine', 'RAIDER_QUARANTINE', 'raider-reporter exec')
43
50
  end
44
51
 
52
+ it 'explains the quality gate' do
53
+ expect(readme).to include('### Quality gate', 'RAIDER_GATE=1', 'Gate page', 'raider/gate',
54
+ 'raider-reporter gate', 'raider-gate', 'exits 1 when the gate fails',
55
+ '2 when it gets no verdict', 'RAIDER_GATE_TIMEOUT', 'RAIDER_SHARD_TOTAL',
56
+ 'RAIDER_SHARD_INDEX')
57
+ end
58
+
45
59
  it 'does not mention Allure' do
46
60
  expect(readme).not_to match(/allure/i)
47
61
  end
@@ -18,8 +18,8 @@ describe 'RSpec projects without Allure' do
18
18
  expect(File).not_to exist(File.join(project_name, 'allure-results'))
19
19
  end
20
20
 
21
- it 'pins raider_reporter 0.8' do
22
- expect(read_generated(project_name, 'Gemfile')).to include("gem 'raider_reporter', '~> 0.8'")
21
+ it 'pins raider_reporter 0.9' do
22
+ expect(read_generated(project_name, 'Gemfile')).to include("gem 'raider_reporter', '~> 0.9'")
23
23
  end
24
24
  end
25
25
  end
@@ -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.8 from RubyGems and ships the raider-reporter executable', :aggregate_failures do
107
+ it 'resolves raider_reporter 0.9 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\.8\.\d+\)$/)
110
+ expect(File.read(File.join(project, 'Gemfile.lock'))).to match(/^ raider_reporter \(0\.9\.\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')
@@ -163,11 +163,11 @@ describe 'End-to-End Project Generation and Execution' do
163
163
  "STDERR: #{result[:stderr]}"
164
164
  end
165
165
 
166
- it 'resolves raider_reporter 0.8 from RubyGems and requires its Cucumber plugin', :aggregate_failures do
166
+ it 'resolves raider_reporter 0.9 from RubyGems and requires its Cucumber plugin', :aggregate_failures do
167
167
  skip 'Bundle install failed' unless bundle_install(project)
168
168
 
169
169
  lockfile = File.read(File.join(project, 'Gemfile.lock'))
170
- expect(lockfile).to match(/^ raider_reporter \(0\.8\.\d+\)$/)
170
+ expect(lockfile).to match(/^ raider_reporter \(0\.9\.\d+\)$/)
171
171
  expect(File.read(File.join(project, 'features/support/env.rb'))).to include("require 'raider_reporter/cucumber'")
172
172
  end
173
173
 
@@ -310,12 +310,12 @@ describe 'End-to-End Project Generation and Execution' do
310
310
  describe 'Selenium + RSpec' do
311
311
  let(:project) { generate_azure_project('rspec') }
312
312
 
313
- it 'ships azure-pipelines.yml and resolves raider_reporter 0.8', :aggregate_failures do
313
+ it 'ships azure-pipelines.yml and resolves raider_reporter 0.9', :aggregate_failures do
314
314
  expect(File).to exist(File.join(project, 'azure-pipelines.yml'))
315
315
  expect(File).not_to exist(File.join(project, '.github/workflows'))
316
316
  skip 'Bundle install failed' unless bundle_install(project)
317
317
 
318
- expect(File.read(File.join(project, 'Gemfile.lock'))).to match(/^ raider_reporter \(0\.8\.\d+\)$/)
318
+ expect(File.read(File.join(project, 'Gemfile.lock'))).to match(/^ raider_reporter \(0\.9\.\d+\)$/)
319
319
  end
320
320
 
321
321
  it 'records provider azure_pipelines and an azure_pipelines: build key in run.json', :aggregate_failures, :slow do
@@ -332,11 +332,11 @@ describe 'End-to-End Project Generation and Execution' do
332
332
  describe 'Selenium + Cucumber' do
333
333
  let(:project) { generate_azure_project('cucumber') }
334
334
 
335
- it 'ships azure-pipelines.yml and resolves raider_reporter 0.8', :aggregate_failures do
335
+ it 'ships azure-pipelines.yml and resolves raider_reporter 0.9', :aggregate_failures do
336
336
  expect(File).to exist(File.join(project, 'azure-pipelines.yml'))
337
337
  skip 'Bundle install failed' unless bundle_install(project)
338
338
 
339
- expect(File.read(File.join(project, 'Gemfile.lock'))).to match(/^ raider_reporter \(0\.8\.\d+\)$/)
339
+ expect(File.read(File.join(project, 'Gemfile.lock'))).to match(/^ raider_reporter \(0\.9\.\d+\)$/)
340
340
  end
341
341
 
342
342
  it 'records provider azure_pipelines and an azure_pipelines: build key in run.json', :aggregate_failures, :slow do
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.8.0
4
+ version: 3.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Agustin Pequeno
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-10-24 00:00:00.000000000 Z
10
+ date: 2026-10-25 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake