/
html.rb
175 lines (148 loc) · 5.01 KB
/
html.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
module XPath
module HTML
include XPath::DSL::TopLevel
extend self
# Match an `a` link element.
#
# @param [String] locator
# Text, id, title, or image alt attribute of the link
#
def link(locator)
locator = locator.to_s
link = descendant(:a)[attr(:href)]
link[attr(:id).equals(locator) | string.n.is(locator) | attr(:title).is(locator) | descendant(:img)[attr(:alt).is(locator)]]
end
# Match a `submit`, `image`, or `button` element.
#
# @param [String] locator
# Value, title, id, or image alt attribute of the button
#
def button(locator)
locator = locator.to_s
button = descendant(:input)[attr(:type).one_of('submit', 'reset', 'image', 'button')][attr(:id).equals(locator) | attr(:value).is(locator) | attr(:title).is(locator)]
button += descendant(:button)[attr(:id).equals(locator) | attr(:value).is(locator) | string.n.is(locator) | attr(:title).is(locator)]
button += descendant(:input)[attr(:type).equals('image')][attr(:alt).is(locator)]
end
# Match anything returned by either {#link} or {#button}.
#
# @param [String] locator
# Text, id, title, or image alt attribute of the link or button
#
def link_or_button(locator)
link(locator) + button(locator)
end
# Match any `fieldset` element.
#
# @param [String] locator
# Legend or id of the fieldset
#
def fieldset(locator)
locator = locator.to_s
descendant(:fieldset)[attr(:id).equals(locator) | child(:legend)[string.n.is(locator)]]
end
# Match any `input`, `textarea`, or `select` element that doesn't have a
# type of `submit`, `image`, or `hidden`.
#
# @param [String] locator
# Label, id, or name of field to match
#
def field(locator)
locator = locator.to_s
xpath = descendant(:input, :textarea, :select)[~attr(:type).one_of('submit', 'image', 'hidden')]
xpath = locate_field(xpath, locator)
xpath
end
# Match any `input` or `textarea` element that can be filled with text.
# This excludes any inputs with a type of `submit`, `image`, `radio`,
# `checkbox`, `hidden`, or `file`.
#
# @param [String] locator
# Label, id, or name of field to match
#
def fillable_field(locator)
locator = locator.to_s
xpath = descendant(:input, :textarea)[~attr(:type).one_of('submit', 'image', 'radio', 'checkbox', 'hidden', 'file')]
xpath = locate_field(xpath, locator)
xpath
end
# Match any `select` element.
#
# @param [String] locator
# Label, id, or name of the field to match
#
def select(locator)
locator = locator.to_s
locate_field(descendant(:select), locator)
end
# Match any `input` element of type `checkbox`.
#
# @param [String] locator
# Label, id, or name of the checkbox to match
#
def checkbox(locator)
locator = locator.to_s
locate_field(descendant(:input)[attr(:type).equals('checkbox')], locator)
end
# Match any `input` element of type `radio`.
#
# @param [String] locator
# Label, id, or name of the radio button to match
#
def radio_button(locator)
locator = locator.to_s
locate_field(descendant(:input)[attr(:type).equals('radio')], locator)
end
# Match any `input` element of type `file`.
#
# @param [String] locator
# Label, id, or name of the file field to match
#
def file_field(locator)
locator = locator.to_s
locate_field(descendant(:input)[attr(:type).equals('file')], locator)
end
# Match an `optgroup` element.
#
# @param [String] name
# Label for the option group
#
def optgroup(locator)
locator = locator.to_s
descendant(:optgroup)[attr(:label).is(locator)]
end
# Match an `option` element.
#
# @param [String] name
# Visible text of the option
#
def option(locator)
locator = locator.to_s
descendant(:option)[string.n.is(locator)]
end
# Match any `table` element.
#
# @param [String] locator
# Caption or id of the table to match
# @option options [Array] :rows
# Content of each cell in each row to match
#
def table(locator)
locator = locator.to_s
descendant(:table)[attr(:id).equals(locator) | descendant(:caption).is(locator)]
end
# Match any 'dd' element.
#
# @param [String] locator
# Id of the 'dd' element or text from preciding 'dt' element content
def definition_description(locator)
locator = locator.to_s
descendant(:dd)[attr(:id).equals(locator) | previous_sibling(:dt)[string.n.equals(locator)] ]
end
protected
def locate_field(xpath, locator)
locate_field = xpath[attr(:id).equals(locator) | attr(:name).equals(locator) | attr(:placeholder).equals(locator) | attr(:id).equals(anywhere(:label)[string.n.is(locator)].attr(:for))]
locate_field += descendant(:label)[string.n.is(locator)].descendant(xpath)
locate_field
end
end
end