cucumber-salad 0.2.2 → 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.
- data/lib/cucumber/salad/boot.rb +9 -0
- data/lib/cucumber/salad/dsl.rb +36 -0
- data/lib/cucumber/salad/version.rb +1 -1
- data/lib/cucumber/salad/widget_container.rb +25 -0
- data/lib/cucumber/salad/widget_name.rb +59 -0
- data/lib/cucumber/salad/widgets/auto_table.rb +11 -0
- data/lib/cucumber/salad/widgets/document.rb +18 -0
- data/lib/cucumber/salad/widgets/form.rb +12 -2
- data/lib/cucumber/salad/widgets/list.rb +2 -2
- data/lib/cucumber/salad/widgets/widget.rb +33 -43
- data/lib/cucumber/salad/widgets.rb +0 -2
- data/lib/cucumber/salad.rb +6 -0
- metadata +23 -3
- data/lib/cucumber/salad/widgets/action.rb +0 -9
@@ -0,0 +1,36 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Salad
|
3
|
+
module DSL
|
4
|
+
attr_writer :widget_lookup_scope
|
5
|
+
|
6
|
+
# @return [Widgets::Document] the current document with the class of the
|
7
|
+
# current object set as the widget lookup scope.
|
8
|
+
def document
|
9
|
+
Widgets::Document.new(widget_lookup_scope: widget_lookup_scope)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Boolean] Whether one or more widgets exist in the current
|
13
|
+
# document.
|
14
|
+
def has_widget?(name)
|
15
|
+
document.has_widget?(name)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns a widget instance for the given name.
|
19
|
+
#
|
20
|
+
# @param name [String, Symbol]
|
21
|
+
def widget(name, options = {})
|
22
|
+
document.widget(name, options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def widget_lookup_scope
|
26
|
+
@widget_lookup_scope ||= default_widget_lookup_scope
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def default_widget_lookup_scope
|
32
|
+
Module === self ? self : self.class
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Salad
|
3
|
+
module WidgetContainer
|
4
|
+
def has_widget?(name)
|
5
|
+
widget_class(name).has_instance?(root)
|
6
|
+
end
|
7
|
+
|
8
|
+
def widget(name, options = {})
|
9
|
+
widget_class(name).in_node(root, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
attr_writer :widget_lookup_scope
|
15
|
+
|
16
|
+
def widget_class(name)
|
17
|
+
WidgetName.new(name).to_class(widget_lookup_scope)
|
18
|
+
end
|
19
|
+
|
20
|
+
def widget_lookup_scope
|
21
|
+
@widget_lookup_scope || self.class
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Salad
|
3
|
+
# The name of a widget in a format-independent representation.
|
4
|
+
class WidgetName < String
|
5
|
+
CAMEL_CASE_FORMAT = /\A([A-Z][a-z]*)+\Z/
|
6
|
+
SNAKE_CASE_FORMAT = /\A\w+\Z/
|
7
|
+
|
8
|
+
# Constructs the widget name.
|
9
|
+
#
|
10
|
+
# @param name [String, Symbol] the name of the widget in primitive form
|
11
|
+
def initialize(name)
|
12
|
+
@name = name
|
13
|
+
@canonical = canonical(@name)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the class for this widget name, in the given scope.
|
17
|
+
def to_class(scope = Object)
|
18
|
+
const = scope.const_get(@canonical)
|
19
|
+
|
20
|
+
raise TypeError, "`#{@canonical}' is not a widget in this scope" \
|
21
|
+
unless const < Widgets::Widget
|
22
|
+
|
23
|
+
const
|
24
|
+
rescue NameError
|
25
|
+
raise UnknownWidgetError,
|
26
|
+
"couldn't find `#{@name}' widget in this scope"
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_sym
|
30
|
+
@canonical.to_sym
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def canonical(name)
|
36
|
+
str = name.to_s
|
37
|
+
|
38
|
+
case str
|
39
|
+
when SNAKE_CASE_FORMAT
|
40
|
+
camel_case_from_snake_case(str)
|
41
|
+
when CAMEL_CASE_FORMAT
|
42
|
+
str
|
43
|
+
else
|
44
|
+
raise ArgumentError, "can't convert `#{str.inspect}' to canonical form"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def camel_case_from_snake_case(name)
|
49
|
+
capitalize_word = ->(word) { word[0].upcase + word[1..-1] }
|
50
|
+
word_separator = '_'
|
51
|
+
|
52
|
+
name
|
53
|
+
.split(word_separator)
|
54
|
+
.map(&capitalize_word)
|
55
|
+
.join
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -2,6 +2,13 @@ module Cucumber
|
|
2
2
|
module Salad
|
3
3
|
module Widgets
|
4
4
|
class AutoTable < BaseTable
|
5
|
+
|
6
|
+
# don't include footer in to_table, because footer column configuration is very
|
7
|
+
# often different from the headers & values.
|
8
|
+
def footers
|
9
|
+
@footers ||= root.all(footer_selector).map { |n| node_text(n) }
|
10
|
+
end
|
11
|
+
|
5
12
|
protected
|
6
13
|
|
7
14
|
def ensure_table_loaded
|
@@ -35,6 +42,10 @@ module Cucumber
|
|
35
42
|
@headers ||= root.all(header_selector).map { |n| node_text(n).downcase }
|
36
43
|
end
|
37
44
|
|
45
|
+
def footer_selector
|
46
|
+
'tfoot td'
|
47
|
+
end
|
48
|
+
|
38
49
|
def values
|
39
50
|
@values ||= data_rows.map(&:values)
|
40
51
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Salad
|
3
|
+
module Widgets
|
4
|
+
class Document
|
5
|
+
include WidgetContainer
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
self.widget_lookup_scope =
|
9
|
+
options.delete(:widget_lookup_scope) or raise "No scope given"
|
10
|
+
end
|
11
|
+
|
12
|
+
def root
|
13
|
+
Capybara.current_session
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -20,7 +20,7 @@ module Cucumber
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def self.
|
23
|
+
def self.select(name, *args)
|
24
24
|
opts = args.extract_options!
|
25
25
|
label, = args
|
26
26
|
|
@@ -36,7 +36,7 @@ module Cucumber
|
|
36
36
|
new.fill_all(attrs).submit
|
37
37
|
end
|
38
38
|
|
39
|
-
def self.
|
39
|
+
def self.text_field(name, label = nil)
|
40
40
|
define_method "#{name}=" do |val|
|
41
41
|
l = label || name_to_locator(name)
|
42
42
|
|
@@ -73,6 +73,16 @@ module Cucumber
|
|
73
73
|
self
|
74
74
|
end
|
75
75
|
|
76
|
+
# Submit form with +attrs+.
|
77
|
+
#
|
78
|
+
# @param attrs [Hash] the form fields and their values
|
79
|
+
#
|
80
|
+
# @return self
|
81
|
+
def submit_with(attrs)
|
82
|
+
fill_all attrs
|
83
|
+
submit
|
84
|
+
end
|
85
|
+
|
76
86
|
private
|
77
87
|
|
78
88
|
def label(name)
|
@@ -2,11 +2,11 @@ module Cucumber
|
|
2
2
|
module Salad
|
3
3
|
module Widgets
|
4
4
|
class List < Widget
|
5
|
-
DEFAULT_TYPE =
|
5
|
+
DEFAULT_TYPE = Widget
|
6
6
|
|
7
7
|
include Enumerable
|
8
8
|
|
9
|
-
def_delegators :items, :size, :include?, :each, :empty?, :first
|
9
|
+
def_delegators :items, :size, :include?, :each, :empty?, :first, :last
|
10
10
|
|
11
11
|
def self.item(selector, type = DEFAULT_TYPE, &item_for)
|
12
12
|
define_method :item_selector do
|
@@ -5,36 +5,46 @@ module Cucumber
|
|
5
5
|
extend Forwardable
|
6
6
|
|
7
7
|
include Salad::Conversions
|
8
|
+
include WidgetContainer
|
8
9
|
|
9
|
-
def self.action(name, selector,
|
10
|
-
|
11
|
-
|
12
|
-
widget wname, selector, type: options[:type] || Action
|
10
|
+
def self.action(name, selector, parent = Widget)
|
11
|
+
widget name, selector, parent
|
13
12
|
|
14
13
|
define_method name do
|
15
|
-
|
14
|
+
widget(name).click
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
18
|
+
def self.has_instance?(parent_node)
|
19
|
+
parent_node.has_selector?(selector)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.in_node(node, options = {})
|
23
|
+
new(options.merge(root: node.find(selector)))
|
24
|
+
end
|
25
|
+
|
19
26
|
def self.root(selector)
|
20
|
-
|
21
|
-
|
22
|
-
end
|
27
|
+
@selector = selector
|
28
|
+
end
|
23
29
|
|
24
|
-
|
30
|
+
def self.selector
|
31
|
+
@selector
|
25
32
|
end
|
26
33
|
|
27
|
-
def self.widget(name, selector,
|
28
|
-
type =
|
29
|
-
|
34
|
+
def self.widget(name, selector, parent = Widget, &block)
|
35
|
+
type = Class.new(parent) {
|
36
|
+
root selector
|
30
37
|
|
31
|
-
|
32
|
-
|
33
|
-
|
38
|
+
instance_eval(&block) if block
|
39
|
+
}
|
40
|
+
|
41
|
+
const_set(Salad::WidgetName.new(name).to_sym, type)
|
34
42
|
end
|
35
43
|
|
44
|
+
def_delegators :root, :click
|
45
|
+
|
36
46
|
def initialize(settings = {})
|
37
|
-
self.root = settings
|
47
|
+
self.root = settings.fetch(:root)
|
38
48
|
end
|
39
49
|
|
40
50
|
def inspect
|
@@ -44,6 +54,12 @@ module Cucumber
|
|
44
54
|
Nokogiri::XML(xml, &:noblanks).to_xhtml
|
45
55
|
end
|
46
56
|
|
57
|
+
def to_s
|
58
|
+
node_text(root)
|
59
|
+
end
|
60
|
+
|
61
|
+
alias_method :w, :widget
|
62
|
+
|
47
63
|
protected
|
48
64
|
|
49
65
|
def node_text(node)
|
@@ -52,37 +68,11 @@ module Cucumber
|
|
52
68
|
|
53
69
|
private
|
54
70
|
|
55
|
-
|
56
|
-
|
57
|
-
def default_root_selector
|
58
|
-
raise NotImplementedError,
|
59
|
-
"#{self.class.name}: default root selector undefined"
|
60
|
-
end
|
71
|
+
attr_accessor :root
|
61
72
|
|
62
73
|
def page
|
63
74
|
Capybara.current_session
|
64
75
|
end
|
65
|
-
|
66
|
-
def root
|
67
|
-
@root || page.find(root_selector)
|
68
|
-
end
|
69
|
-
|
70
|
-
def root=(selector_or_node)
|
71
|
-
case selector_or_node
|
72
|
-
when String
|
73
|
-
self.root_selector = selector_or_node
|
74
|
-
when Capybara::Node::Element, Capybara::Node::Simple
|
75
|
-
@root = selector_or_node
|
76
|
-
else
|
77
|
-
msg = "can't convert #{selector_or_node.inspect} to root node"
|
78
|
-
|
79
|
-
raise ArgumentError, msg
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def root_selector
|
84
|
-
@root_selector || default_root_selector
|
85
|
-
end
|
86
76
|
end
|
87
77
|
end
|
88
78
|
end
|
data/lib/cucumber/salad.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
require 'chronic'
|
2
2
|
|
3
|
+
require 'cucumber/salad/widget_container'
|
3
4
|
require 'cucumber/salad/conversions'
|
4
5
|
require 'cucumber/salad/instance_conversions'
|
5
6
|
require 'cucumber/salad/node_text'
|
7
|
+
require 'cucumber/salad/widget_name'
|
6
8
|
require 'cucumber/salad/widgets'
|
7
9
|
require 'cucumber/salad/table'
|
8
10
|
require 'cucumber/salad/table/mapping'
|
9
11
|
require 'cucumber/salad/table/void_mapping'
|
10
12
|
require 'cucumber/salad/table/transformations'
|
11
13
|
require 'cucumber/salad/table/cell_text'
|
14
|
+
require 'cucumber/salad/widgets/document'
|
15
|
+
require 'cucumber/salad/dsl'
|
16
|
+
|
17
|
+
class UnknownWidgetError < StandardError; end
|
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: cucumber-salad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.3.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- David Leal
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -75,6 +75,22 @@ dependencies:
|
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: 2.11.0
|
77
77
|
none: false
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
none: false
|
85
|
+
name: sinatra
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
requirement: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
none: false
|
78
94
|
description: See https://github.com/mojotech/cucumber-salad/README.md
|
79
95
|
email:
|
80
96
|
- dleal@mojotech.com
|
@@ -83,7 +99,9 @@ extensions: []
|
|
83
99
|
extra_rdoc_files: []
|
84
100
|
files:
|
85
101
|
- lib/cucumber/salad.rb
|
102
|
+
- lib/cucumber/salad/boot.rb
|
86
103
|
- lib/cucumber/salad/conversions.rb
|
104
|
+
- lib/cucumber/salad/dsl.rb
|
87
105
|
- lib/cucumber/salad/instance_conversions.rb
|
88
106
|
- lib/cucumber/salad/node_text.rb
|
89
107
|
- lib/cucumber/salad/table.rb
|
@@ -92,11 +110,13 @@ files:
|
|
92
110
|
- lib/cucumber/salad/table/transformations.rb
|
93
111
|
- lib/cucumber/salad/table/void_mapping.rb
|
94
112
|
- lib/cucumber/salad/version.rb
|
113
|
+
- lib/cucumber/salad/widget_container.rb
|
114
|
+
- lib/cucumber/salad/widget_name.rb
|
95
115
|
- lib/cucumber/salad/widgets.rb
|
96
|
-
- lib/cucumber/salad/widgets/action.rb
|
97
116
|
- lib/cucumber/salad/widgets/atom.rb
|
98
117
|
- lib/cucumber/salad/widgets/auto_table.rb
|
99
118
|
- lib/cucumber/salad/widgets/base_table.rb
|
119
|
+
- lib/cucumber/salad/widgets/document.rb
|
100
120
|
- lib/cucumber/salad/widgets/form.rb
|
101
121
|
- lib/cucumber/salad/widgets/list.rb
|
102
122
|
- lib/cucumber/salad/widgets/table.rb
|