unobtainium-cucumber 0.1.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 +7 -0
- data/.codeclimate.yml +34 -0
- data/.gitignore +57 -0
- data/.rspec +2 -0
- data/.rubocop.yml +78 -0
- data/.travis.yml +11 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +106 -0
- data/LICENSE +30 -0
- data/README.md +150 -0
- data/Rakefile +29 -0
- data/config/config.yml +28 -0
- data/features/action.feature +12 -0
- data/features/action_support.feature +17 -0
- data/features/driver_reset.feature +17 -0
- data/features/extensions.feature +7 -0
- data/features/status_actions.feature +115 -0
- data/features/step_definitions/action.rb +61 -0
- data/features/step_definitions/action_support.rb +40 -0
- data/features/step_definitions/driver_reset.rb +85 -0
- data/features/step_definitions/extensions.rb +19 -0
- data/features/step_definitions/mocks/scenario.rb +18 -0
- data/features/step_definitions/status_actions.rb +358 -0
- data/features/support/env.rb +27 -0
- data/features/support/utils.rb +47 -0
- data/lib/unobtainium-cucumber/action/content.rb +40 -0
- data/lib/unobtainium-cucumber/action/screenshot.rb +37 -0
- data/lib/unobtainium-cucumber/action/support/naming.rb +44 -0
- data/lib/unobtainium-cucumber/driver_reset.rb +34 -0
- data/lib/unobtainium-cucumber/status_actions.rb +272 -0
- data/lib/unobtainium-cucumber/version.rb +14 -0
- data/lib/unobtainium-cucumber.rb +20 -0
- data/unobtainium-cucumber.gemspec +54 -0
- metadata +244 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
# Code coverage first
|
11
|
+
require 'simplecov'
|
12
|
+
SimpleCov.start do
|
13
|
+
add_filter 'features'
|
14
|
+
end
|
15
|
+
|
16
|
+
# Other requires after SimpleCov
|
17
|
+
require "unobtainium-cucumber"
|
18
|
+
|
19
|
+
# Extensions used for testing
|
20
|
+
module MyExtensions
|
21
|
+
def method_from_own_extension(*args, &block); end
|
22
|
+
end # module MyExtensions
|
23
|
+
|
24
|
+
World(MyExtensions)
|
25
|
+
|
26
|
+
# Utility code for testing
|
27
|
+
require_relative './utils'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
TIMESTAMP_REGEX ||= /\d{4}_\d{2}_\d{2}T\d{2}_\d{2}_\d{2}Z/
|
11
|
+
|
12
|
+
##
|
13
|
+
# Given a file name, extrat and convert timestamps
|
14
|
+
def timestamp_from_filename(filename)
|
15
|
+
# First, check if we can find the file name matching a timestamp
|
16
|
+
parts = File.split(filename)
|
17
|
+
parts = parts[-1].split('-')
|
18
|
+
timestamp = parts[0]
|
19
|
+
if not TIMESTAMP_REGEX.match(timestamp)
|
20
|
+
return
|
21
|
+
end
|
22
|
+
|
23
|
+
# Great, then fix the formatting...
|
24
|
+
timestamp[4] = '-'
|
25
|
+
timestamp[7] = '-'
|
26
|
+
timestamp[13] = ':'
|
27
|
+
timestamp[16] = ':'
|
28
|
+
|
29
|
+
return Time.parse(timestamp)
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Given a match pattern and optional timeout, finds files matching the pattern
|
34
|
+
# that have been created within the given timeout from now.
|
35
|
+
def timeout_match_files(pattern, timeout = 5)
|
36
|
+
now = Time.now.utc
|
37
|
+
|
38
|
+
Dir[pattern].each do |fname|
|
39
|
+
ts = timestamp_from_filename(fname)
|
40
|
+
if (now - ts).abs <= timeout
|
41
|
+
return fname
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
raise "No file matching '#{pattern}' with a timestamp in the last #{timeout} "\
|
46
|
+
"seconds was found!"
|
47
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'unobtainium-cucumber/action/support/naming'
|
11
|
+
|
12
|
+
module Unobtainium
|
13
|
+
module Cucumber
|
14
|
+
|
15
|
+
##
|
16
|
+
# Namespace for built-in status actions
|
17
|
+
module Action
|
18
|
+
|
19
|
+
class << self
|
20
|
+
include Support
|
21
|
+
|
22
|
+
##
|
23
|
+
# Status action function that stores the page content (main page only)
|
24
|
+
def store_content(world, scenario)
|
25
|
+
# Make sure the content directory exists.
|
26
|
+
basedir = File.join(Dir.pwd, 'content')
|
27
|
+
FileUtils.mkdir_p(basedir)
|
28
|
+
|
29
|
+
# Store content. Note that not all drivers may support this.
|
30
|
+
filename = File.join(basedir, base_filename(scenario))
|
31
|
+
filename += '.txt'
|
32
|
+
|
33
|
+
File.open(filename, 'w') do |file|
|
34
|
+
file.write(world.driver.page_source)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end # class << self
|
38
|
+
end # module Action
|
39
|
+
end # module Cucumber
|
40
|
+
end # module Unobtainium
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'unobtainium-cucumber/action/support/naming'
|
11
|
+
|
12
|
+
module Unobtainium
|
13
|
+
module Cucumber
|
14
|
+
|
15
|
+
##
|
16
|
+
# Namespace for built-in status actions
|
17
|
+
module Action
|
18
|
+
|
19
|
+
class << self
|
20
|
+
include Support
|
21
|
+
|
22
|
+
##
|
23
|
+
# Status action function that takes a screenshot.
|
24
|
+
def store_screenshot(world, scenario)
|
25
|
+
# Make sure the screenshots directory exists.
|
26
|
+
basedir = File.join(Dir.pwd, 'screenshots')
|
27
|
+
FileUtils.mkdir_p(basedir)
|
28
|
+
|
29
|
+
# Take screenshot.
|
30
|
+
filename = File.join(basedir, base_filename(scenario))
|
31
|
+
filename += '.png'
|
32
|
+
world.driver.save_screenshot(filename)
|
33
|
+
end
|
34
|
+
end # class << self
|
35
|
+
end # module Action
|
36
|
+
end # module Cucumber
|
37
|
+
end # module Unobtainium
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
module Unobtainium
|
10
|
+
module Cucumber
|
11
|
+
module Action
|
12
|
+
|
13
|
+
##
|
14
|
+
# Support functions for actions
|
15
|
+
module Support
|
16
|
+
|
17
|
+
##
|
18
|
+
# Given a cucumber scenario, this function returns a timestamped
|
19
|
+
# base filename (without extension) that reflects parts of the scenario
|
20
|
+
# name.
|
21
|
+
# Note that the optional tag is not related to cucumber tags. It's just
|
22
|
+
# a way to distinguish two filenames for the same scenario at the same
|
23
|
+
# timestamp.
|
24
|
+
# We use '_' as a replacement for unrenderable characters, and
|
25
|
+
# '-' as a separator between file name components.
|
26
|
+
def base_filename(scenario, tag = nil, timestamp = nil)
|
27
|
+
# Build base name from parameters
|
28
|
+
require 'time'
|
29
|
+
timestamp ||= Time.now.utc.iso8601
|
30
|
+
timestamp.tr!('-', '_')
|
31
|
+
scenario_name = scenario.name
|
32
|
+
base_name = [timestamp, tag, scenario_name].reject(&:nil?).join('-')
|
33
|
+
|
34
|
+
# Make base name filename safe
|
35
|
+
base_name.gsub!(/^.*(\\|\/)/, '')
|
36
|
+
base_name.gsub!(/[^0-9A-Za-z.\-]+/, '_')
|
37
|
+
|
38
|
+
return base_name
|
39
|
+
end
|
40
|
+
|
41
|
+
end # module Support
|
42
|
+
end # module Action
|
43
|
+
end # module Cucumber
|
44
|
+
end # module Unobtainium
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
After do |_|
|
11
|
+
if not driver.respond_to? :reset
|
12
|
+
next
|
13
|
+
end
|
14
|
+
|
15
|
+
# Covering this would require two separate test suites. I'm not sure I'm
|
16
|
+
# ready for that.
|
17
|
+
# :nocov:
|
18
|
+
if config['cucumber.driver_reset'] == false
|
19
|
+
next
|
20
|
+
end
|
21
|
+
# :nocov:
|
22
|
+
|
23
|
+
begin
|
24
|
+
driver.reset
|
25
|
+
rescue => error
|
26
|
+
# :nocov:
|
27
|
+
# If driver reset isn't possible, it doesn't make sense to continue
|
28
|
+
puts "DRIVER RESET WASN'T POSSIBLE DUE TO #{error} - BUT IS REQUIRED "\
|
29
|
+
"FOR BEFORE NEXT SCENARIO. WILL EXIT THE PROGRAM"
|
30
|
+
driver.quit
|
31
|
+
Kernel.exit(2)
|
32
|
+
# :nocov:
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,272 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'unobtainium-cucumber/action/screenshot'
|
11
|
+
require 'unobtainium-cucumber/action/content'
|
12
|
+
|
13
|
+
module Unobtainium
|
14
|
+
module Cucumber
|
15
|
+
##
|
16
|
+
# The StatusActions module contains all functionality for registering
|
17
|
+
# actions to be run when a scenario or outline ended with a particular
|
18
|
+
# status.
|
19
|
+
module StatusActions
|
20
|
+
# Key for storing actions in unobtainium's runtime instance.
|
21
|
+
RUNTIME_KEY = 'unobtainium-cucumber-status-actions'.freeze
|
22
|
+
|
23
|
+
# Default status actions
|
24
|
+
DEFAULTS = {
|
25
|
+
failed?: [
|
26
|
+
'::Unobtainium::Cucumber::Action.store_screenshot',
|
27
|
+
]
|
28
|
+
}.freeze
|
29
|
+
|
30
|
+
##
|
31
|
+
# Register a action for a :passed? or :failed? scenario.
|
32
|
+
# The :type parameter may either be :scenario or :outline.
|
33
|
+
# The action will be passed the matching scenario. If no
|
34
|
+
# explicit action is given, a block is also acceptable.
|
35
|
+
def register_action(status, action = nil, options = nil, &block)
|
36
|
+
# If the action is a Hash, then the options should be nil. If that's
|
37
|
+
# the case, we have no action and instead got passed options.
|
38
|
+
if action.is_a? Hash
|
39
|
+
if not options.nil?
|
40
|
+
raise "Can't pass a Hash as an action!"
|
41
|
+
end
|
42
|
+
options = action
|
43
|
+
action = nil
|
44
|
+
end
|
45
|
+
|
46
|
+
# Parameter checks!
|
47
|
+
if not [:passed?, :failed?].include?(status)
|
48
|
+
raise "Status may be one of :passed? or :failed? only!"
|
49
|
+
end
|
50
|
+
|
51
|
+
options ||= {}
|
52
|
+
type = options[:type] || :scenario
|
53
|
+
if not [:scenario, :outline].include?(type)
|
54
|
+
raise "The :type option may be one of :scenario or :outline only!"
|
55
|
+
end
|
56
|
+
|
57
|
+
if action.nil? and block.nil?
|
58
|
+
raise "Must provide either an action method or a block!"
|
59
|
+
end
|
60
|
+
if not action.nil? and not block.nil?
|
61
|
+
raise "Cannot provide both an action method and a block!"
|
62
|
+
end
|
63
|
+
|
64
|
+
callback = action || block
|
65
|
+
|
66
|
+
# The key to store callbacks under is comprised of the status
|
67
|
+
# and the type. That way we can match precisely when actions are to
|
68
|
+
# be executed.
|
69
|
+
key = [status, type]
|
70
|
+
|
71
|
+
# Retrieve existing actions
|
72
|
+
actions = {}
|
73
|
+
if ::Unobtainium::Runtime.instance.has?(RUNTIME_KEY)
|
74
|
+
actions = ::Unobtainium::Runtime.instance.fetch(RUNTIME_KEY)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Add the callback
|
78
|
+
actions[key] ||= []
|
79
|
+
actions[key] |= [callback]
|
80
|
+
|
81
|
+
# And store the callback actions again.
|
82
|
+
::Unobtainium::Runtime.instance.store(RUNTIME_KEY, actions)
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# For a given scenario, return the matching key for the actions.
|
87
|
+
def action_key(scenario)
|
88
|
+
return [
|
89
|
+
(scenario.passed? ? :passed? : :failed?),
|
90
|
+
(scenario.outline? ? :outline : :scenario)
|
91
|
+
]
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Automatically register all configured status actions.
|
96
|
+
# This is largely an internal function, run after the first scenario
|
97
|
+
# and before status actions are executed.
|
98
|
+
def register_config_actions(world)
|
99
|
+
to_register = world.config['cucumber.status_actions'] || DEFAULTS
|
100
|
+
|
101
|
+
[:passed?, :failed?].each do |status|
|
102
|
+
for_status = to_register[status]
|
103
|
+
if for_status.nil?
|
104
|
+
# :nocov:
|
105
|
+
next
|
106
|
+
# :nocov:
|
107
|
+
end
|
108
|
+
|
109
|
+
# If the entry for the status is an Array, it applies to scenarios
|
110
|
+
# and outlines equally. Otherwise we'll have to find a Hash with
|
111
|
+
# entries for either or both.
|
112
|
+
actions = {}
|
113
|
+
if for_status.is_a?(Array)
|
114
|
+
actions[:scenario] = for_status
|
115
|
+
actions[:outline] = for_status
|
116
|
+
elsif for_status.is_a?(Hash)
|
117
|
+
actions[:scenario] = for_status[:scenario] || []
|
118
|
+
actions[:outline] = for_status[:outline] || []
|
119
|
+
else
|
120
|
+
# :nocov:
|
121
|
+
raise "Cannot interpret status action configuration for status "\
|
122
|
+
"#{status}; it should be an Array or Hash, but instead it was"\
|
123
|
+
" this: #{for_status}"
|
124
|
+
# :nocov:
|
125
|
+
end
|
126
|
+
|
127
|
+
# Now we have actions for the statuses, we can register them.
|
128
|
+
[:scenario, :outline].each do |type|
|
129
|
+
actions[type].each do |action|
|
130
|
+
register_action(status, action, type: type)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Given an action and a scenario, execute the action. This includes
|
138
|
+
# late/lazy resolution of String or Symbol actions.
|
139
|
+
def execute_action(world, action, scenario)
|
140
|
+
# Simplest case first: the action is already callable.
|
141
|
+
if action.respond_to?(:call)
|
142
|
+
return action.call(world, scenario)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Symbols are almost as easy to handle: they must resolve to a
|
146
|
+
# method, either globally or on the world object.
|
147
|
+
if action.is_a? Symbol
|
148
|
+
meth = resolve_action(Object, world, action)
|
149
|
+
if meth.nil?
|
150
|
+
raise NoMethodError, "Symbol :#{action} could not be resolved "\
|
151
|
+
"either globally or as part of the cucumber World object, "\
|
152
|
+
"aborting!"
|
153
|
+
end
|
154
|
+
return meth.call(world, scenario)
|
155
|
+
end
|
156
|
+
|
157
|
+
# At this point, the action better be a String.
|
158
|
+
if not action.is_a? String
|
159
|
+
raise "Action '#{action}' is not callable, and not a method name. "\
|
160
|
+
"Aborting!"
|
161
|
+
end
|
162
|
+
|
163
|
+
# Split module and method name
|
164
|
+
module_name, method_name = split_string_action(action)
|
165
|
+
|
166
|
+
# If we have no discernable module, use Object instead.
|
167
|
+
the_module = Object
|
168
|
+
if not module_name.nil? and not module_name.empty?
|
169
|
+
the_module = Object.const_get(module_name)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Try the module we found (i.e. possibly Object) and world for
|
173
|
+
# resolving the method name.
|
174
|
+
meth = resolve_action(the_module, world, method_name)
|
175
|
+
if meth.nil?
|
176
|
+
raise NoMethodError, "Action '#{action}' could not be resolved!"
|
177
|
+
end
|
178
|
+
|
179
|
+
return meth.call(world, scenario)
|
180
|
+
end
|
181
|
+
|
182
|
+
##
|
183
|
+
# For a given status and type, return the registered actions.
|
184
|
+
def registered_actions(status, type)
|
185
|
+
if not ::Unobtainium::Runtime.instance.has?(RUNTIME_KEY)
|
186
|
+
return []
|
187
|
+
end
|
188
|
+
|
189
|
+
actions = ::Unobtainium::Runtime.instance.fetch(RUNTIME_KEY)
|
190
|
+
return actions[[status, type]] || []
|
191
|
+
end
|
192
|
+
|
193
|
+
##
|
194
|
+
# Partially for testing purposes, clears the action registry.
|
195
|
+
def clear_actions
|
196
|
+
if not ::Unobtainium::Runtime.instance.has?(RUNTIME_KEY)
|
197
|
+
# :nocov:
|
198
|
+
return
|
199
|
+
# :nocov:
|
200
|
+
end
|
201
|
+
|
202
|
+
::Unobtainium::Runtime.instance.delete(RUNTIME_KEY)
|
203
|
+
end
|
204
|
+
|
205
|
+
##
|
206
|
+
# Resolves the given symbol in either of the given namespace or the
|
207
|
+
# world object. Returns nil if neither contained the symbol.
|
208
|
+
def resolve_action(namespace, world, method_name)
|
209
|
+
method_sym = method_name.to_sym
|
210
|
+
|
211
|
+
[namespace, world].each do |receiver|
|
212
|
+
begin
|
213
|
+
return receiver.method(method_sym)
|
214
|
+
rescue NameError
|
215
|
+
next
|
216
|
+
end
|
217
|
+
end
|
218
|
+
return nil
|
219
|
+
end
|
220
|
+
|
221
|
+
##
|
222
|
+
# Splits a string action into a module prefix and a method name
|
223
|
+
def split_string_action(action)
|
224
|
+
# Try to see whether we have a fully qualified name that requires us
|
225
|
+
# to query a particular module for the method.
|
226
|
+
split_action = action.split(/::/)
|
227
|
+
method_name = split_action.pop
|
228
|
+
|
229
|
+
# If the method name contains a dot, it uses 'Module.method' notation.
|
230
|
+
# rubocop:disable Lint/EmptyWhen
|
231
|
+
split_method = method_name.split(/\./)
|
232
|
+
case split_method.length
|
233
|
+
when 1
|
234
|
+
# Do nothing; the method name did not contain a dot
|
235
|
+
when 2
|
236
|
+
# We have a method name and a module part
|
237
|
+
split_action << split_method[0]
|
238
|
+
method_name = split_method[1]
|
239
|
+
else
|
240
|
+
raise "Too many dots in method name: #{method_name}"
|
241
|
+
end
|
242
|
+
# rubocop:enable Lint/EmptyWhen
|
243
|
+
|
244
|
+
# Re-join the module name
|
245
|
+
module_name = split_action.join('::')
|
246
|
+
|
247
|
+
return module_name, method_name
|
248
|
+
end
|
249
|
+
end # module StatusActions
|
250
|
+
end # module Cucumber
|
251
|
+
end # module Unobtainium
|
252
|
+
|
253
|
+
##
|
254
|
+
# In the Before hook, we register configured actions.
|
255
|
+
Before do |_|
|
256
|
+
# Register all configured actions.
|
257
|
+
register_config_actions(self)
|
258
|
+
end
|
259
|
+
|
260
|
+
##
|
261
|
+
# The After hook with cucumber defined here will execute all matching,
|
262
|
+
# registered actions.
|
263
|
+
After do |scenario|
|
264
|
+
# Fetch actions applying to this scenario
|
265
|
+
key = action_key(scenario)
|
266
|
+
applicable_actions = registered_actions(key[0], key[1])
|
267
|
+
|
268
|
+
# Execute all actions applying to this scenario
|
269
|
+
applicable_actions.each do |action|
|
270
|
+
execute_action(self, action, scenario)
|
271
|
+
end
|
272
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
module Unobtainium
|
10
|
+
module Cucumber
|
11
|
+
# The current release version
|
12
|
+
VERSION = "0.1.0".freeze
|
13
|
+
end # module Cucumber
|
14
|
+
end # module Unobtainium
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'unobtainium'
|
11
|
+
require 'unobtainium-cucumber/version'
|
12
|
+
|
13
|
+
# First things first: extend the World. Otherwise nothing in this file will
|
14
|
+
# work.
|
15
|
+
World(Unobtainium::World)
|
16
|
+
|
17
|
+
require 'unobtainium-cucumber/driver_reset.rb'
|
18
|
+
require 'unobtainium-cucumber/status_actions.rb'
|
19
|
+
|
20
|
+
World(Unobtainium::Cucumber::StatusActions)
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
lib = File.expand_path('../lib', __FILE__)
|
11
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
12
|
+
require 'unobtainium-cucumber/version'
|
13
|
+
|
14
|
+
# rubocop:disable Style/UnneededPercentQ, Style/ExtraSpacing
|
15
|
+
# rubocop:disable Style/SpaceAroundOperators
|
16
|
+
# rubocop:disable Metrics/BlockLength
|
17
|
+
Gem::Specification.new do |spec|
|
18
|
+
spec.name = "unobtainium-cucumber"
|
19
|
+
spec.version = Unobtainium::Cucumber::VERSION
|
20
|
+
spec.authors = ["Jens Finkhaeuser"]
|
21
|
+
spec.email = ["jens@finkhaeuser.de"]
|
22
|
+
spec.description = %q(
|
23
|
+
The unobtainium-cucucmber gem adds some convenient cucumber specific hooks
|
24
|
+
for use with unobtainium.
|
25
|
+
)
|
26
|
+
spec.summary = %q(
|
27
|
+
Cucumber hooks for unobtainium.
|
28
|
+
)
|
29
|
+
spec.homepage = "https://github.com/jfinkhaeuser/unobtainium-cucumber"
|
30
|
+
spec.license = "MITNFA"
|
31
|
+
|
32
|
+
spec.files = `git ls-files -z`.split("\x0")
|
33
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
34
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
35
|
+
spec.require_paths = ["lib"]
|
36
|
+
|
37
|
+
spec.required_ruby_version = '>= 2.0'
|
38
|
+
|
39
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
40
|
+
spec.add_development_dependency "rubocop", "~> 0.46"
|
41
|
+
spec.add_development_dependency "rake", "~> 11.2"
|
42
|
+
spec.add_development_dependency "simplecov", "~> 0.12"
|
43
|
+
spec.add_development_dependency "yard", "~> 0.9"
|
44
|
+
spec.add_development_dependency "appium_lib"
|
45
|
+
spec.add_development_dependency "selenium-webdriver"
|
46
|
+
spec.add_development_dependency "chromedriver-helper"
|
47
|
+
spec.add_development_dependency "phantomjs"
|
48
|
+
|
49
|
+
spec.add_dependency "unobtainium", "~> 0.10"
|
50
|
+
spec.add_dependency "cucumber", "~> 2.0"
|
51
|
+
end
|
52
|
+
# rubocop:enable Metrics/BlockLength
|
53
|
+
# rubocop:enable Style/SpaceAroundOperators
|
54
|
+
# rubocop:enable Style/UnneededPercentQ, Style/ExtraSpacing
|