locator 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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