kensho-cucumber-ruby 0.1.1 → 0.3.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/lib/kensho/cucumber/formatter.rb +41 -1
- data/lib/kensho/cucumber/helpers.rb +163 -0
- data/lib/kensho/cucumber/state.rb +28 -0
- data/lib/kensho/cucumber/version.rb +1 -1
- data/lib/kensho/cucumber.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 01db9e872e361ae51b6f4006652dcb87c864de8d223cb942253dd5832fc08a2c
|
|
4
|
+
data.tar.gz: ceb1feb628390738c358524d4abdc7efb99440f69eedc9c4281a8276953c08f0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: df8c6820ade8df4ff763beba11d068b4e0e113e446c9396fb6b6badc37579bd63b5712ac8da9675aad13a8180a4d20984fd26ca05c36004e675a1cd0931cb549
|
|
7
|
+
data.tar.gz: 113ef8ab53e5bd3bc6f6e020b8a920a6f459f3f90d49d27ef136cc8140fd61447a3b2f578761a6ed00bc7440d580ce6ad26816f97a4b6b6925be9717094bd3a5
|
|
@@ -4,6 +4,8 @@ require 'json'
|
|
|
4
4
|
require 'fileutils'
|
|
5
5
|
require 'securerandom'
|
|
6
6
|
require_relative '../_schema'
|
|
7
|
+
require_relative 'state'
|
|
8
|
+
require_relative 'helpers'
|
|
7
9
|
|
|
8
10
|
# Cucumber 7+ formatter that emits Kensho v1 results.
|
|
9
11
|
#
|
|
@@ -145,9 +147,20 @@ module Kensho
|
|
|
145
147
|
worst_status: 'pass',
|
|
146
148
|
first_error: nil,
|
|
147
149
|
first_exception: nil,
|
|
148
|
-
attachments: []
|
|
150
|
+
attachments: [],
|
|
151
|
+
rt_labels: {},
|
|
152
|
+
rt_links: [],
|
|
153
|
+
rt_parameters: [],
|
|
154
|
+
rt_tags: [],
|
|
155
|
+
rt_behavior: {},
|
|
156
|
+
rt_severity: nil,
|
|
157
|
+
rt_owner: nil,
|
|
158
|
+
rt_description: nil,
|
|
159
|
+
flaky: false,
|
|
160
|
+
muted: false
|
|
149
161
|
}
|
|
150
162
|
@scratch[test_case.object_id] = scratch
|
|
163
|
+
Kensho::Cucumber::State.current = scratch
|
|
151
164
|
end
|
|
152
165
|
|
|
153
166
|
def on_test_step_finished(event)
|
|
@@ -243,8 +256,35 @@ module Kensho
|
|
|
243
256
|
|
|
244
257
|
case_obj['attachments'] = scratch[:attachments] unless scratch[:attachments].empty?
|
|
245
258
|
|
|
259
|
+
# Runtime annotations (Kensho.* helpers) win over tag-derived values.
|
|
260
|
+
unless scratch[:rt_labels].empty?
|
|
261
|
+
case_obj['labels'] = (case_obj['labels'] || {}).merge(scratch[:rt_labels])
|
|
262
|
+
end
|
|
263
|
+
unless scratch[:rt_links].empty?
|
|
264
|
+
case_obj['links'] = (case_obj['links'] || []) + scratch[:rt_links]
|
|
265
|
+
end
|
|
266
|
+
unless scratch[:rt_parameters].empty?
|
|
267
|
+
case_obj['parameters'] = (case_obj['parameters'] || []) + scratch[:rt_parameters]
|
|
268
|
+
end
|
|
269
|
+
unless scratch[:rt_tags].empty?
|
|
270
|
+
existing = case_obj['tags'] || []
|
|
271
|
+
merged = existing.dup
|
|
272
|
+
scratch[:rt_tags].each { |t| merged << t unless merged.include?(t) }
|
|
273
|
+
case_obj['tags'] = merged
|
|
274
|
+
end
|
|
275
|
+
unless scratch[:rt_behavior].empty?
|
|
276
|
+
case_obj['behavior'] = (case_obj['behavior'] || {}).merge(scratch[:rt_behavior])
|
|
277
|
+
end
|
|
278
|
+
case_obj['severity'] = scratch[:rt_severity] if scratch[:rt_severity]
|
|
279
|
+
case_obj['owner'] = scratch[:rt_owner] if scratch[:rt_owner]
|
|
280
|
+
case_obj['description'] = scratch[:rt_description] if scratch[:rt_description]
|
|
281
|
+
case_obj['flaky'] = true if scratch[:flaky]
|
|
282
|
+
case_obj['muted'] = true if scratch[:muted]
|
|
283
|
+
|
|
246
284
|
@cases_by_id[case_obj['id']] = case_obj
|
|
247
285
|
write_case(case_obj)
|
|
286
|
+
ensure
|
|
287
|
+
Kensho::Cucumber::State.current = nil
|
|
248
288
|
end
|
|
249
289
|
|
|
250
290
|
def on_test_run_finished
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../_schema'
|
|
4
|
+
require_relative 'state'
|
|
5
|
+
|
|
6
|
+
# Public helper API usable from inside Cucumber step definitions.
|
|
7
|
+
#
|
|
8
|
+
# Kensho.label('team', 'growth')
|
|
9
|
+
# Kensho.link('https://example.com/docs', 'Docs')
|
|
10
|
+
# Kensho.jira_link('PROJ-123')
|
|
11
|
+
# Kensho.epic('Checkout'); Kensho.feature('Cart'); Kensho.story('Empty cart')
|
|
12
|
+
# Kensho.severity('critical'); Kensho.owner('alice')
|
|
13
|
+
# Kensho.flaky; Kensho.muted; Kensho.known_issue('PROJ-1')
|
|
14
|
+
#
|
|
15
|
+
# All helpers are no-ops outside a running scenario, so they're safe to call
|
|
16
|
+
# from shared support code. Runtime annotations win over tag-derived values.
|
|
17
|
+
|
|
18
|
+
module Kensho
|
|
19
|
+
class << self
|
|
20
|
+
def label(key, value)
|
|
21
|
+
scratch = Kensho::Cucumber::State.current
|
|
22
|
+
return if scratch.nil? || key.nil? || key.to_s.empty?
|
|
23
|
+
|
|
24
|
+
(scratch[:rt_labels] ||= {})[key.to_s] = value.to_s
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Add a hyperlink. Positional `name` is the human label. Kind 'link'.
|
|
29
|
+
def link(url, name = nil, kind: nil, label: nil)
|
|
30
|
+
add_link(url, kind: kind || 'link', label: name || label)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# A Jira/issue link. `id_or_url` may be a bare ticket id or a full URL.
|
|
34
|
+
def jira_link(id_or_url, label = nil)
|
|
35
|
+
add_link(id_or_url, kind: 'issue', label: label || id_or_url)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# A reference/documentation link. Kind 'reference'.
|
|
39
|
+
def reference_link(url, label = nil)
|
|
40
|
+
add_link(url, kind: 'reference', label: label)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# behavior.epic + labels.epic
|
|
44
|
+
def epic(name)
|
|
45
|
+
apply_behavior_runtime('epic', 'epic', name)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# behavior.feature + labels.feature
|
|
49
|
+
def feature(name)
|
|
50
|
+
apply_behavior_runtime('feature', 'feature', name)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# behavior.scenario + labels.story
|
|
54
|
+
def story(name)
|
|
55
|
+
apply_behavior_runtime('scenario', 'story', name)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Set case.severity. Only the five canonical names are accepted.
|
|
59
|
+
def severity(value)
|
|
60
|
+
scratch = Kensho::Cucumber::State.current
|
|
61
|
+
return if scratch.nil? || value.nil?
|
|
62
|
+
|
|
63
|
+
v = value.to_s
|
|
64
|
+
scratch[:rt_severity] = v if Kensho::Schema::SEVERITY.include?(v)
|
|
65
|
+
nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Set case.owner.
|
|
69
|
+
def owner(value)
|
|
70
|
+
scratch = Kensho::Cucumber::State.current
|
|
71
|
+
return if scratch.nil? || value.nil?
|
|
72
|
+
|
|
73
|
+
scratch[:rt_owner] = value.to_s
|
|
74
|
+
nil
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Set case.description.
|
|
78
|
+
def description(text)
|
|
79
|
+
scratch = Kensho::Cucumber::State.current
|
|
80
|
+
return if scratch.nil? || text.nil?
|
|
81
|
+
|
|
82
|
+
scratch[:rt_description] = text.to_s
|
|
83
|
+
nil
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Add a tag. Strips a leading '@' and de-dupes.
|
|
87
|
+
def tag(name)
|
|
88
|
+
scratch = Kensho::Cucumber::State.current
|
|
89
|
+
return if scratch.nil? || name.nil?
|
|
90
|
+
|
|
91
|
+
t = name.to_s.sub(/\A@/, '')
|
|
92
|
+
return if t.empty?
|
|
93
|
+
|
|
94
|
+
tags = (scratch[:rt_tags] ||= [])
|
|
95
|
+
tags << t unless tags.include?(t)
|
|
96
|
+
nil
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Add a parameter (name/value). No kind.
|
|
100
|
+
def parameter(name, value)
|
|
101
|
+
scratch = Kensho::Cucumber::State.current
|
|
102
|
+
return if scratch.nil? || name.nil? || name.to_s.empty?
|
|
103
|
+
|
|
104
|
+
(scratch[:rt_parameters] ||= []) << { 'name' => name.to_s, 'value' => value.to_s }
|
|
105
|
+
nil
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Mark the running scenario flaky.
|
|
109
|
+
def flaky
|
|
110
|
+
scratch = Kensho::Cucumber::State.current
|
|
111
|
+
return if scratch.nil?
|
|
112
|
+
|
|
113
|
+
scratch[:flaky] = true
|
|
114
|
+
nil
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Mark the running scenario muted (known failure not counted by the gate).
|
|
118
|
+
def muted
|
|
119
|
+
scratch = Kensho::Cucumber::State.current
|
|
120
|
+
return if scratch.nil?
|
|
121
|
+
|
|
122
|
+
scratch[:muted] = true
|
|
123
|
+
nil
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# A known issue: mutes the scenario and records an 'issue' link.
|
|
127
|
+
def known_issue(id_or_url, label = nil)
|
|
128
|
+
scratch = Kensho::Cucumber::State.current
|
|
129
|
+
return if scratch.nil?
|
|
130
|
+
|
|
131
|
+
scratch[:muted] = true
|
|
132
|
+
jira_link(id_or_url, label)
|
|
133
|
+
nil
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def current_case_id
|
|
137
|
+
scratch = Kensho::Cucumber::State.current
|
|
138
|
+
scratch && scratch[:case_obj] ? scratch[:case_obj]['id'] : nil
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
private
|
|
142
|
+
|
|
143
|
+
def add_link(url, kind:, label:)
|
|
144
|
+
scratch = Kensho::Cucumber::State.current
|
|
145
|
+
return if scratch.nil? || url.nil? || url.to_s.empty?
|
|
146
|
+
|
|
147
|
+
entry = { 'url' => url.to_s }
|
|
148
|
+
entry['kind'] = kind.to_s if kind && !kind.to_s.empty?
|
|
149
|
+
entry['label'] = label.to_s if label && !label.to_s.empty?
|
|
150
|
+
(scratch[:rt_links] ||= []) << entry
|
|
151
|
+
nil
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def apply_behavior_runtime(behavior_key, label_key, value)
|
|
155
|
+
scratch = Kensho::Cucumber::State.current
|
|
156
|
+
return if scratch.nil? || value.nil? || value.to_s.empty?
|
|
157
|
+
|
|
158
|
+
(scratch[:rt_behavior] ||= {})[behavior_key] = value.to_s
|
|
159
|
+
(scratch[:rt_labels] ||= {})[label_key] = value.to_s
|
|
160
|
+
nil
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Per-scenario state pointer used by the public Kensho.* helper API.
|
|
4
|
+
#
|
|
5
|
+
# The formatter stores its per-scenario scratch (a plain Hash) and points
|
|
6
|
+
# State.current at it on :test_case_started, clearing it on
|
|
7
|
+
# :test_case_finished. While a scenario runs the Kensho.label / Kensho.link /
|
|
8
|
+
# Kensho.flaky / etc. helpers mutate that Hash directly so the formatter can
|
|
9
|
+
# fold the data into the case when it finalizes.
|
|
10
|
+
#
|
|
11
|
+
# Cucumber-Ruby runs scenarios sequentially; we still key off Thread.current
|
|
12
|
+
# so step definitions running on a fixture thread (rare) don't race.
|
|
13
|
+
|
|
14
|
+
module Kensho
|
|
15
|
+
module Cucumber
|
|
16
|
+
module State
|
|
17
|
+
THREAD_KEY = :__kensho_cucumber_scratch__
|
|
18
|
+
|
|
19
|
+
def self.current
|
|
20
|
+
Thread.current[THREAD_KEY]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.current=(scratch)
|
|
24
|
+
Thread.current[THREAD_KEY] = scratch
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/kensho/cucumber.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kensho-cucumber-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- KaizenReport
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cucumber
|
|
@@ -38,6 +38,8 @@ files:
|
|
|
38
38
|
- lib/kensho/_schema.rb
|
|
39
39
|
- lib/kensho/cucumber.rb
|
|
40
40
|
- lib/kensho/cucumber/formatter.rb
|
|
41
|
+
- lib/kensho/cucumber/helpers.rb
|
|
42
|
+
- lib/kensho/cucumber/state.rb
|
|
41
43
|
- lib/kensho/cucumber/version.rb
|
|
42
44
|
homepage: https://github.com/brandon1794/kensho
|
|
43
45
|
licenses:
|