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.
@@ -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 elements_by_xpath(xpath)
53
- element.xpath(xpath).map { |element| Element.new(element) }
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
- @dom = ::Nokogiri::HTML::Document.parse(html)
6
+ super(::Nokogiri::HTML::Document.parse(html))
9
7
  end
10
-
11
- def element_by_id(id)
12
- elements_by_xpath("//*[@id='#{id}']").first
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
@@ -2,7 +2,7 @@ module Locator
2
2
  class Element
3
3
  class Area < Element
4
4
  def initialize
5
- super('area', :equals => [:id], :matches => [:alt])
5
+ super(:area, :equals => [:id], :matches => [:alt])
6
6
  end
7
7
  end
8
8
  end
@@ -2,8 +2,8 @@ module Locator
2
2
  class Element
3
3
  class Button < ElementsList
4
4
  def initialize
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])
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
@@ -2,7 +2,7 @@ module Locator
2
2
  class Element
3
3
  class File < Input
4
4
  def initialize
5
- super('input', :type => :file)
5
+ super(:input, :type => :file)
6
6
  end
7
7
  end
8
8
  end
@@ -2,7 +2,7 @@ module Locator
2
2
  class Element
3
3
  class Form < Element
4
4
  def initialize
5
- super('form', :equals => [:id, :name])
5
+ super(:form, :equals => [:id, :name])
6
6
  end
7
7
  end
8
8
  end
@@ -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('input', { :equals => [:id, :name] }, attributes)
7
+ super(:input, { :equals => [:id, :name] }, attributes)
8
8
  end
9
9
  end
10
10
  end
@@ -2,7 +2,7 @@ module Locator
2
2
  class Element
3
3
  class Label < Element
4
4
  def initialize
5
- super('label', :equals => [:id, :content])
5
+ super(:label, :equals => [:id, :content])
6
6
  end
7
7
  end
8
8
  end
@@ -2,7 +2,7 @@ module Locator
2
2
  class Element
3
3
  class Link < Element
4
4
  def initialize
5
- super('a', nil, :href => true)
5
+ super(:a, nil, :href => true)
6
6
  end
7
7
  end
8
8
  end
@@ -2,7 +2,7 @@ module Locator
2
2
  class Element
3
3
  class Select < FormElement
4
4
  def initialize
5
- super('select', :equals => [:id, :name])
5
+ super(:select, :equals => [:id, :name])
6
6
  end
7
7
  end
8
8
  end
@@ -2,7 +2,7 @@ module Locator
2
2
  class Element
3
3
  class SelectOption < Element
4
4
  def initialize
5
- super('option', :equals => [:id, :value, :content])
5
+ super(:option, :equals => [:id, :value, :content])
6
6
  end
7
7
  end
8
8
  end
@@ -2,7 +2,7 @@ module Locator
2
2
  class Element
3
3
  class TextArea < FormElement
4
4
  def initialize
5
- super('textarea', :equals => [:id, :name])
5
+ super(:textarea, :equals => [:id, :name])
6
6
  end
7
7
  end
8
8
  end
@@ -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(dom, *args)
33
+ def all(scope, *args)
34
34
  attributes, selector = args.last.is_a?(Hash) ? args.pop : {}, args.pop
35
- result = lookup(dom, selector, attributes)
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(dom, selector, attributes = {})
47
- dom = dom.respond_to?(:elements_by_xpath) ? dom : Locator::Dom.page(dom)
48
- elements = dom.elements_by_xpath(xpath(attributes))
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
@@ -1,3 +1,3 @@
1
1
  module Locator
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
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 &raquo;</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
- test "locates an element from html" do
22
- html = '<html><body><p></p><form class="bar"></form></body></html>'
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.2
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-09 00:00:00 +01:00
12
+ date: 2010-02-13 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15