locator 0.0.2 → 0.0.3
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/locator/dom/nokogiri/element.rb +15 -3
- data/lib/locator/dom/nokogiri/page.rb +5 -19
- data/lib/locator/element/area.rb +1 -1
- data/lib/locator/element/button.rb +2 -2
- data/lib/locator/element/file.rb +1 -1
- data/lib/locator/element/form.rb +1 -1
- data/lib/locator/element/input.rb +1 -1
- data/lib/locator/element/label.rb +1 -1
- data/lib/locator/element/link.rb +1 -1
- data/lib/locator/element/select.rb +1 -1
- data/lib/locator/element/select_option.rb +1 -1
- data/lib/locator/element/text_area.rb +1 -1
- data/lib/locator/element.rb +9 -8
- data/lib/locator/version.rb +1 -1
- data/lib/locator/xpath.rb +8 -6
- data/test/locator/element_test.rb +28 -18
- data/test/locator_test.rb +10 -2
- metadata +2 -2
@@ -13,6 +13,10 @@ module Locator
|
|
13
13
|
to_s.length <=> other.to_s.length
|
14
14
|
end
|
15
15
|
|
16
|
+
def name
|
17
|
+
@element.name
|
18
|
+
end
|
19
|
+
|
16
20
|
def xpath
|
17
21
|
element.path.to_s
|
18
22
|
end
|
@@ -20,7 +24,7 @@ module Locator
|
|
20
24
|
def css_path
|
21
25
|
element.css_path.to_s
|
22
26
|
end
|
23
|
-
|
27
|
+
|
24
28
|
def content
|
25
29
|
element.content
|
26
30
|
end
|
@@ -49,8 +53,16 @@ module Locator
|
|
49
53
|
names.map { |name| attribute(name) }
|
50
54
|
end
|
51
55
|
|
52
|
-
def
|
53
|
-
|
56
|
+
def element_by_id(id)
|
57
|
+
elements_by_xpath("//*[@id='#{id}']").first
|
58
|
+
end
|
59
|
+
|
60
|
+
def elements_by_css(*rules)
|
61
|
+
element.css(*rules).map { |element| Element.new(element) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def elements_by_xpath(*xpaths)
|
65
|
+
element.xpath(*xpaths).map { |element| Element.new(element) }
|
54
66
|
end
|
55
67
|
end
|
56
68
|
end
|
@@ -1,27 +1,13 @@
|
|
1
1
|
module Locator
|
2
2
|
module Dom
|
3
3
|
module Nokogiri
|
4
|
-
class Page
|
5
|
-
attr_reader :dom
|
6
|
-
|
4
|
+
class Page < Element
|
7
5
|
def initialize(html)
|
8
|
-
|
6
|
+
super(::Nokogiri::HTML::Document.parse(html))
|
9
7
|
end
|
10
|
-
|
11
|
-
def
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
def elements_by_css(*rules)
|
16
|
-
@dom.css(*rules).map { |element| Element.new(element) }
|
17
|
-
end
|
18
|
-
|
19
|
-
def elements_by_xpath(*xpaths)
|
20
|
-
@dom.xpath(*xpaths).map { |element| Element.new(element) }
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_s
|
24
|
-
@dom.to_s
|
8
|
+
|
9
|
+
def dom
|
10
|
+
element
|
25
11
|
end
|
26
12
|
end
|
27
13
|
end
|
data/lib/locator/element/area.rb
CHANGED
@@ -2,8 +2,8 @@ module Locator
|
|
2
2
|
class Element
|
3
3
|
class Button < ElementsList
|
4
4
|
def initialize
|
5
|
-
input = Element.new(
|
6
|
-
button = Element.new(
|
5
|
+
input = Element.new(:input, { :equals => [:id, :name], :matches => [:value] }, :type => %w(submit button image))
|
6
|
+
button = Element.new(:button, :equals => [:id, :name], :matches => [:content])
|
7
7
|
super(input, button)
|
8
8
|
end
|
9
9
|
end
|
data/lib/locator/element/file.rb
CHANGED
data/lib/locator/element/form.rb
CHANGED
@@ -4,7 +4,7 @@ module Locator
|
|
4
4
|
def initialize(attributes = {})
|
5
5
|
attributes = { :type => [:text, :password , :email, :url, :search, :tel, :color] }.merge(attributes)
|
6
6
|
matchables = { :equals => [:id, :name] }
|
7
|
-
super(
|
7
|
+
super(:input, { :equals => [:id, :name] }, attributes)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
data/lib/locator/element/link.rb
CHANGED
data/lib/locator/element.rb
CHANGED
@@ -18,10 +18,10 @@ module Locator
|
|
18
18
|
autoload :SelectOption, 'locator/element/select_option'
|
19
19
|
autoload :TextArea, 'locator/element/text_area'
|
20
20
|
|
21
|
-
attr_reader :name, :locatables, :attributes
|
21
|
+
attr_reader :name, :css, :locatables, :attributes
|
22
22
|
|
23
23
|
def initialize(name = nil, locatables = nil, attributes = nil)
|
24
|
-
@name = name
|
24
|
+
@name = name
|
25
25
|
@locatables = { :equals => :id, :matches => :content }.merge(locatables || {})
|
26
26
|
@attributes = attributes || {}
|
27
27
|
end
|
@@ -30,22 +30,23 @@ module Locator
|
|
30
30
|
all(*args).first
|
31
31
|
end
|
32
32
|
|
33
|
-
def all(
|
33
|
+
def all(scope, *args)
|
34
34
|
attributes, selector = args.last.is_a?(Hash) ? args.pop : {}, args.pop
|
35
|
-
result = lookup(
|
35
|
+
result = lookup(scope, selector, attributes)
|
36
36
|
result.sort! if selector
|
37
37
|
result
|
38
38
|
end
|
39
39
|
|
40
40
|
def xpath(attributes = {})
|
41
|
-
Xpath.new(name, self.attributes.merge(attributes)).to_s
|
41
|
+
@xpath ||= Xpath.new(name || '*', self.attributes.merge(attributes)).to_s
|
42
42
|
end
|
43
43
|
|
44
44
|
protected
|
45
45
|
|
46
|
-
def lookup(
|
47
|
-
|
48
|
-
|
46
|
+
def lookup(scope, selector, attributes = {})
|
47
|
+
scope = scope.respond_to?(:elements_by_xpath) ? scope : Locator::Dom.page(scope)
|
48
|
+
xpath, css = attributes.delete(:xpath), attributes.delete(:css)
|
49
|
+
elements = css ? scope.elements_by_css(css) : scope.elements_by_xpath(xpath || xpath(attributes))
|
49
50
|
Result.new(elements).filter!(selector, locatables)
|
50
51
|
end
|
51
52
|
end
|
data/lib/locator/version.rb
CHANGED
data/lib/locator/xpath.rb
CHANGED
@@ -2,8 +2,14 @@ module Locator
|
|
2
2
|
Boolean::Or.operator, Boolean::And.operator = ' | ', ''
|
3
3
|
|
4
4
|
class Xpath < Array
|
5
|
+
class << self
|
6
|
+
def xpath?(string)
|
7
|
+
string =~ %r(^\.?//)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
5
11
|
def initialize(name = nil, attributes = {})
|
6
|
-
super(Array(name || '*').map { |name| xpath?(name) ? name : ".//#{name}" })
|
12
|
+
super(Array(name || '*').map { |name| self.class.xpath?(name) ? name : ".//#{name}" })
|
7
13
|
|
8
14
|
attributes.each do |name, value|
|
9
15
|
case name
|
@@ -47,11 +53,7 @@ module Locator
|
|
47
53
|
protected
|
48
54
|
|
49
55
|
def quote(value)
|
50
|
-
xpath?(value) ? value : "\"#{value}\""
|
51
|
-
end
|
52
|
-
|
53
|
-
def xpath?(string)
|
54
|
-
string =~ %r(^\.?//)
|
56
|
+
self.class.xpath?(value) ? value : "\"#{value}\""
|
55
57
|
end
|
56
58
|
end
|
57
59
|
end
|
@@ -2,56 +2,56 @@ require File.expand_path('../../test_helper', __FILE__)
|
|
2
2
|
|
3
3
|
class LocatorElementTest < Test::Unit::TestCase
|
4
4
|
include Locator
|
5
|
-
|
5
|
+
|
6
6
|
# xpath
|
7
|
-
|
7
|
+
|
8
8
|
test "xpath without further arguments given" do
|
9
9
|
assert_equal './/*', Element.new.xpath
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
test "xpath with a node name" do
|
13
13
|
xpath = Element.new(:div).xpath
|
14
14
|
assert_equal './/div', xpath
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
test "xpath with attributes" do
|
18
18
|
xpath = Element.new(nil, nil, :type => 'type', :class => 'class').xpath
|
19
19
|
assert_equal ".//*[@type=\"type\"][contains(concat(' ', @class, ' '), concat(' ', \"class\", ' '))]", xpath
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
test "xpath with node name and attributes" do
|
23
23
|
xpath = Element.new(:div, nil, :type => 'type', :class => 'class').xpath
|
24
24
|
assert_equal ".//div[@type=\"type\"][contains(concat(' ', @class, ' '), concat(' ', \"class\", ' '))]", xpath
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
# all
|
28
|
-
|
28
|
+
|
29
29
|
test "all selects all elements when given no attributes" do
|
30
30
|
html = '<a class="foo"></a><p class="bar"></p>'
|
31
31
|
elements = Element.new.all(html)
|
32
32
|
assert_equal %w(html body a p), elements.map { |element| element.tag_name }
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
test "all selects all nodes with given node name" do
|
36
36
|
html = '<a class="foo"></a><p class="bar"></p>'
|
37
37
|
elements = Element.new('a').all(html)
|
38
38
|
assert_equal %w(a), elements.map { |element| element.tag_name }
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
test "all selects all nodes with attribute given to initialize" do
|
42
42
|
html = '<a class="foo"></a><p class="bar"></p>'
|
43
43
|
elements = Element.new(nil, nil, :class => 'foo').all(html)
|
44
44
|
assert_equal %w(a), elements.map { |element| element.tag_name }
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
test "all selects all nodes with attribute given to all" do
|
48
48
|
html = '<a class="foo"></a><p class="bar"></p>'
|
49
49
|
elements = Element.new.all(html, :class => 'foo')
|
50
50
|
assert_equal %w(a), elements.map { |element| element.tag_name }
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# locate
|
54
|
-
|
54
|
+
|
55
55
|
test "locate selects an element based on the length of the matching value" do
|
56
56
|
html = %(
|
57
57
|
<a href="#">the link with extra text</a>
|
@@ -60,7 +60,7 @@ class LocatorElementTest < Test::Unit::TestCase
|
|
60
60
|
element = Element.new.locate(html, 'the link')
|
61
61
|
assert_equal 'the link ...', element.content
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
test "locate selects an element containing whitespace" do
|
65
65
|
html = %(
|
66
66
|
<a href="#">
|
@@ -70,29 +70,39 @@ class LocatorElementTest < Test::Unit::TestCase
|
|
70
70
|
)
|
71
71
|
assert Element.new.locate(html, 'the link')
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
test "locate selects an element containing extra tags" do
|
75
75
|
html = '<a href="#">the <span>link</span></a>'
|
76
76
|
assert Element.new.locate(html, 'the link')
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
test "locate selects an element containing extra text (1)" do
|
80
80
|
html = '<a href="#">the link »</label>'
|
81
81
|
assert Element.new.locate(html, 'the link')
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
test "locate selects an element containing extra text (2)" do
|
85
85
|
html = '<a href="#">(the link)</label>'
|
86
86
|
assert Element.new.locate(html, 'the link')
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
test "does not find a link when id does not match" do
|
90
90
|
html = '<a href="" id="bar"></a>'
|
91
91
|
assert_nil Element.new.locate(html, :id => 'foo')
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
test "does not find a link when class does not match" do
|
95
95
|
html = '<a href="" class="bar"></a>'
|
96
96
|
assert_nil Element.new.locate(html, :class => 'foo')
|
97
97
|
end
|
98
|
+
|
99
|
+
test "locate using an xpath" do
|
100
|
+
html = '<a class="foo" href="#"></a><a class="bar" href="#"></a>'
|
101
|
+
assert_equal 'bar', Element::Link.new.locate(html, :xpath => '//a[@class="bar"]').attribute('class')
|
102
|
+
end
|
103
|
+
|
104
|
+
test "locate using a css selector" do
|
105
|
+
html = '<a class="foo" href="#"></a><a class="bar" href="#"></a>'
|
106
|
+
assert_equal 'bar', Element::Link.new.locate(html, :css => '.bar').attribute('class')
|
107
|
+
end
|
98
108
|
end
|
data/test/locator_test.rb
CHANGED
@@ -18,12 +18,20 @@ class LocatorTest < Test::Unit::TestCase
|
|
18
18
|
assert_equal './/form[@id="bar"]', xpath
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
# locate
|
22
|
+
|
23
|
+
test "locates an element by node name" do
|
24
|
+
html = '<html><body><form></form></body></html>'
|
23
25
|
element = Locator.locate(html, :form)
|
24
26
|
assert_equal 'form', element.tag_name
|
25
27
|
end
|
26
28
|
|
29
|
+
test "locates an element by xpath" do
|
30
|
+
html = '<html><body><form></form></body></html>'
|
31
|
+
element = Locator.locate(html, :xpath => '//form')
|
32
|
+
assert_equal 'form', element.tag_name
|
33
|
+
end
|
34
|
+
|
27
35
|
# within
|
28
36
|
|
29
37
|
test "within scopes to a locator" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: locator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Fuchs
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-13 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|