locator 0.0.5 → 0.0.6

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/Rakefile CHANGED
@@ -1,10 +1,21 @@
1
+ require 'rubygems'
2
+ require 'rake'
1
3
  require 'rake/testtask'
4
+ require 'rake/rdoctask'
2
5
 
3
- require File.expand_path("../lib/locator/version", __FILE__)
6
+ desc 'Default: run unit tests.'
7
+ task :default => :test
8
+
9
+ desc 'Run all tests.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ load 'test/all.rb'
12
+ end
4
13
 
5
14
  begin
6
15
  require 'jeweler'
7
16
  Jeweler::Tasks.new do |s|
17
+ require File.expand_path("../lib/locator/version", __FILE__)
18
+
8
19
  s.name = "locator"
9
20
  s.version = Locator::VERSION
10
21
  s.summary = "Generic html element locators for integration testing"
@@ -13,6 +24,7 @@ begin
13
24
  s.description = "Generic html element locators for integration testing"
14
25
  s.authors = ['Sven Fuchs']
15
26
  s.files = FileList["[A-Z]*", "{lib,test,vendor}/**/*"]
27
+ s.add_dependency 'htmlentities'
16
28
  end
17
29
  rescue LoadError
18
30
  puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
data/lib/locator.rb CHANGED
@@ -1,12 +1,15 @@
1
1
  require 'core_ext/string/underscore'
2
2
 
3
3
  module Locator
4
- autoload :Boolean, 'locator/boolean'
5
- autoload :Dom, 'locator/dom'
6
- autoload :Element, 'locator/element'
7
- autoload :Matcher, 'locator/matcher'
8
- autoload :Result, 'locator/result'
9
- autoload :Xpath, 'locator/xpath'
4
+ autoload :Boolean, 'locator/boolean'
5
+ autoload :Dom, 'locator/dom'
6
+ autoload :Decoding, 'locator/decoding'
7
+ autoload :Element, 'locator/element'
8
+ autoload :Matcher, 'locator/matcher'
9
+ autoload :Result, 'locator/result'
10
+ autoload :Xpath, 'locator/xpath'
11
+
12
+ extend Decoding
10
13
 
11
14
  class ElementNotFound < StandardError
12
15
  def initialize(*args)
@@ -28,7 +31,7 @@ module Locator
28
31
 
29
32
  def locators
30
33
  @locators ||= Hash[*Element.constants.map do |name|
31
- [name.underscore.to_sym, Element.const_get(name)]
34
+ [name.to_s.underscore.to_sym, Element.const_get(name)]
32
35
  end.flatten]
33
36
  end
34
37
  end
@@ -97,4 +100,4 @@ module Locator
97
100
  end
98
101
 
99
102
  extend(self)
100
- end
103
+ end
@@ -34,7 +34,7 @@ module Locator
34
34
  self.operator = ' AND '
35
35
 
36
36
  def initialize(lft, rgt)
37
- replace(lft.map { |l| rgt.map { |r| "#{l}#{self.class.operator}#{r}" } })
37
+ replace(Array(lft).map { |l| Array(rgt).map { |r| "#{l}#{self.class.operator}#{r}" } })
38
38
  end
39
39
  end
40
40
 
@@ -47,4 +47,4 @@ module Locator
47
47
  end
48
48
  end
49
49
  end
50
- end
50
+ end
@@ -0,0 +1,28 @@
1
+ module Locator
2
+ module Decoding
3
+ def decode_entities?
4
+ @decode_entities ||= true
5
+ end
6
+
7
+ def decode_entities=(decode_entities)
8
+ @decode_entities = decode_entities
9
+ end
10
+
11
+ def decode_attributes(hash)
12
+ Hash[*hash.map { |name, value| [name, decode(value)] }.flatten]
13
+ end
14
+
15
+ def decode(value)
16
+ value.is_a?(String) ? html_entities.decode(value) : value
17
+ end
18
+
19
+ protected
20
+
21
+ def html_entities
22
+ html_entities ||= begin
23
+ require 'htmlentities'
24
+ HTMLEntities.new
25
+ end
26
+ end
27
+ end
28
+ end
@@ -25,10 +25,6 @@ module Locator
25
25
  element.css_path.to_s
26
26
  end
27
27
 
28
- def content
29
- element.content
30
- end
31
-
32
28
  def value
33
29
  case name
34
30
  when 'input'
@@ -45,6 +41,10 @@ module Locator
45
41
  checked ? checked.value : nil
46
42
  end
47
43
 
44
+ def content
45
+ element.content
46
+ end
47
+
48
48
  def inner_html
49
49
  element.inner_html
50
50
  end
@@ -52,6 +52,8 @@ module Locator
52
52
  protected
53
53
 
54
54
  def lookup(scope, selector, attributes = {})
55
+ attributes = Locator.decode_attributes(attributes) if Locator.decode_entities?
56
+
55
57
  scope = scope.respond_to?(:elements_by_xpath) ? scope : Locator::Dom.page(scope)
56
58
  xpath = xpath(attributes)
57
59
  xpath = ".#{xpath}" unless xpath[0, 1] == '.'
@@ -8,6 +8,7 @@ module Locator
8
8
 
9
9
  class << self
10
10
  def matches?(name, value, selector)
11
+ value, selector = Locator.decode(value), Locator.decode(selector) if Locator.decode_entities?
11
12
  value = normalize_whitespace(value)
12
13
  case selector
13
14
  when Regexp
@@ -1,3 +1,3 @@
1
1
  module Locator
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
data/lib/locator/xpath.rb CHANGED
@@ -7,7 +7,7 @@ module Locator
7
7
  string =~ %r(^\.?//)
8
8
  end
9
9
  end
10
-
10
+
11
11
  def initialize(name = nil, attributes = {})
12
12
  super(Array(name || '*').map { |name| self.class.xpath?(name) ? name : ".//#{name}" })
13
13
 
@@ -43,7 +43,7 @@ module Locator
43
43
  end
44
44
 
45
45
  def and!(other)
46
- replace(self.map { |l| other.map { |r| "#{l}#{r}" } })
46
+ replace(self.map { |l| Array(other).map { |r| "#{l}#{r}" } }.flatten)
47
47
  end
48
48
 
49
49
  def or!(other)
@@ -60,4 +60,4 @@ module Locator
60
60
  self.class.xpath?(value) ? value : "\"#{value}\""
61
61
  end
62
62
  end
63
- end
63
+ end
data/test/all.rb CHANGED
@@ -2,5 +2,5 @@ files = Dir[File.dirname(__FILE__) + '/**/*_test.rb']
2
2
  # files.reject! { |file| file.include?('htmlunit') }
3
3
 
4
4
  files.each do |filename|
5
- require filename unless filename.include?('_locator')
5
+ require filename # unless filename.include?('_locator')
6
6
  end
@@ -1,77 +1,81 @@
1
1
  require File.expand_path('../../../test_helper', __FILE__)
2
2
 
3
3
  $: << '~/Development/projects/steam/lib'
4
- require 'steam'
5
- include Steam
4
+ begin
5
+ require 'steam'
6
+ include Steam
6
7
 
7
- Java.load(Dir["#{Steam.config[:html_unit][:java_path]}/*.jar"].join(':'))
8
- Java.import 'com.gargoylesoftware.htmlunit.WebClient'
9
- Java.import 'com.gargoylesoftware.htmlunit.BrowserVersion'
8
+ Java.load(Dir["#{Steam.config[:html_unit][:java_path]}/*.jar"].join(':'))
9
+ Java.import 'com.gargoylesoftware.htmlunit.WebClient'
10
+ Java.import 'com.gargoylesoftware.htmlunit.BrowserVersion'
10
11
 
11
- class HtmlunitElementTest < Test::Unit::TestCase
12
- include Locator, Java::Com::Gargoylesoftware::Htmlunit
12
+ class HtmlunitElementTest < Test::Unit::TestCase
13
+ include Locator, Java::Com::Gargoylesoftware::Htmlunit
13
14
 
14
- def setup
15
- connection = Connection::Mock.new
16
- client = WebClient.new(BrowserVersion.FIREFOX_3)
17
- client.setWebConnection(Rjb::bind(Browser::HtmlUnit::Connection.new(connection), 'com.gargoylesoftware.htmlunit.WebConnection'))
15
+ def setup
16
+ connection = Connection::Mock.new
17
+ client = WebClient.new(BrowserVersion.FIREFOX_3)
18
+ client.setWebConnection(Rjb::bind(Browser::HtmlUnit::Connection.new(connection), 'com.gargoylesoftware.htmlunit.WebConnection'))
18
19
 
19
- connection.mock(:get, 'http://localhost:3000/', '<a href="#" class="foo">the link</a><div id="bar"></div>')
20
- @dom = Dom::Htmlunit::Page.new(client.getPage('http://localhost:3000/'))
21
- end
20
+ connection.mock(:get, 'http://localhost:3000/', '<a href="#" class="foo">the link</a><div id="bar"></div>')
21
+ @dom = Dom::Htmlunit::Page.new(client.getPage('http://localhost:3000/'))
22
+ end
22
23
 
23
- test "Element takes a Htmlunit::Page adapter" do
24
- element = Element::Link.new.locate(@dom, 'the link', :class => 'foo')
25
- assert element.name
26
- end
24
+ test "Element takes a Htmlunit::Page adapter" do
25
+ element = Element::Link.new.locate(@dom, 'the link', :class => 'foo')
26
+ assert element.name
27
+ end
27
28
 
28
- test "responds to name" do
29
- element = Element::Link.new.locate(@dom, 'the link')
30
- assert_equal 'a', element.name
31
- end
29
+ test "responds to name" do
30
+ element = Element::Link.new.locate(@dom, 'the link')
31
+ assert_equal 'a', element.name
32
+ end
32
33
 
33
- test "responds to xpath" do
34
- element = Element::Link.new.locate(@dom, 'the link')
35
- assert_equal '/html/body/a', element.xpath
36
- end
34
+ test "responds to xpath" do
35
+ element = Element::Link.new.locate(@dom, 'the link')
36
+ assert_equal '/html/body/a', element.xpath
37
+ end
37
38
 
38
- test "responds to to_s" do
39
- element = Element::Link.new.locate(@dom, 'the link')
40
- assert_equal "<a href=\"#\" class=\"foo\">\n the link\n</a>\n", element.to_s
41
- end
39
+ test "responds to to_s" do
40
+ element = Element::Link.new.locate(@dom, 'the link')
41
+ assert_equal "<a href=\"#\" class=\"foo\">\n the link\n</a>\n", element.to_s
42
+ end
42
43
 
43
- test "responds to content" do
44
- element = Element::Link.new.locate(@dom, 'the link')
45
- assert_equal "the link", element.content
46
- end
44
+ test "responds to content" do
45
+ element = Element::Link.new.locate(@dom, 'the link')
46
+ assert_equal "the link", element.content
47
+ end
47
48
 
48
- test "responds to attribute" do
49
- element = Element::Link.new.locate(@dom, 'the link')
50
- assert_equal 'foo', element.attribute('class')
51
- end
49
+ test "responds to attribute" do
50
+ element = Element::Link.new.locate(@dom, 'the link')
51
+ assert_equal 'foo', element.attribute('class')
52
+ end
52
53
 
53
- test "responds to element_by_id" do
54
- element = Element.new(:html).locate(@dom)
55
- assert_equal 'bar', element.element_by_id('bar').attribute('id')
56
- end
54
+ test "responds to element_by_id" do
55
+ element = Element.new(:html).locate(@dom)
56
+ assert_equal 'bar', element.element_by_id('bar').attribute('id')
57
+ end
57
58
 
58
- test "responds to element_by_xpath" do
59
- element = Element.new(:html).locate(@dom)
60
- assert_equal 'bar', element.element_by_xpath('//html/body/div[@id="bar"]').attribute('id')
61
- end
59
+ test "responds to element_by_xpath" do
60
+ element = Element.new(:html).locate(@dom)
61
+ assert_equal 'bar', element.element_by_xpath('//html/body/div[@id="bar"]').attribute('id')
62
+ end
62
63
 
63
- test "responds to elements_by_xpath" do
64
- element = Element::Link.new.locate(@dom, 'the link')
65
- assert_equal 'foo', element.attribute('class')
66
- end
64
+ test "responds to elements_by_xpath" do
65
+ element = Element::Link.new.locate(@dom, 'the link')
66
+ assert_equal 'foo', element.attribute('class')
67
+ end
67
68
 
68
- test "responds to ancestors" do
69
- element = Element.new(:a).locate(@dom)
70
- assert_equal %w(html body), element.ancestors.map { |e| e.name }
71
- end
69
+ test "responds to ancestors" do
70
+ element = Element.new(:a).locate(@dom)
71
+ assert_equal %w(html body), element.ancestors.map { |e| e.name }
72
+ end
72
73
 
73
- test "responds to ancestor_of?" do
74
- element = Element.new(:a).locate(@dom)
75
- assert_equal %w(html body), element.ancestors.map { |e| e.name }
74
+ test "responds to ancestor_of?" do
75
+ element = Element.new(:a).locate(@dom)
76
+ assert_equal %w(html body), element.ancestors.map { |e| e.name }
77
+ end
76
78
  end
79
+ rescue LoadError
80
+ puts "skipping HtmlUnit tests because Steam is not available"
77
81
  end
@@ -13,4 +13,30 @@ class NokogiriTest < Test::Unit::TestCase
13
13
  dom = Locator::Dom::Nokogiri::Page.new('<a href="#">the link</a>')
14
14
  assert Element.new.locate(dom, 'the link')
15
15
  end
16
+
17
+ # test "Nokogiri and Umlauts" do
18
+ # encoded = '<p>&ouml;</p>'
19
+ # unencoded = '<p>ö</p>'
20
+ #
21
+ # # this is ok
22
+ # fragment = Nokogiri::HTML.fragment(encoded)
23
+ # assert_equal encoded, fragment.to_s
24
+ #
25
+ # # this seems weird ... wtf experiences ahead
26
+ # fragment = Nokogiri::HTML.fragment(unencoded)
27
+ # assert_equal encoded, fragment.to_s
28
+ #
29
+ # options =
30
+ # Nokogiri::XML::ParseOptions::RECOVER |
31
+ # Nokogiri::XML::ParseOptions::NOERROR |
32
+ # Nokogiri::XML::ParseOptions::NOWARNING
33
+ #
34
+ # # this is ok
35
+ # node = Nokogiri::HTML.parse(encoded, nil, nil, options)
36
+ # assert_equal encoded, node.xpath('//p').first.to_s
37
+ #
38
+ # # this is ok
39
+ # node = Nokogiri::HTML.parse(unencoded, nil, 'utf-8', options)
40
+ # assert_equal unencoded, node.xpath('//p').first.to_s
41
+ # end
16
42
  end
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require File.expand_path('../../test_helper', __FILE__)
2
3
 
3
4
  class LocatorElementTest < Test::Unit::TestCase
@@ -122,4 +123,14 @@ class LocatorElementTest < Test::Unit::TestCase
122
123
  html = '<a class="foo" href="#"></a><a class="bar" href="#"></a>'
123
124
  assert_equal 'bar', Element::Link.new.locate(html, :css => '.bar').attribute('class')
124
125
  end
126
+
127
+ test "locate selects an element containing an umlaut" do
128
+ html = '<a href="#">the lünk</a>'
129
+ assert Element.new.locate(html, 'the lünk')
130
+ end
131
+
132
+ test "locate selects an element with an attribute containing an umlaut" do
133
+ html = '<input type="text" value="München" />'
134
+ assert Element.new.locate(html, :value => 'München')
135
+ end
125
136
  end
@@ -19,8 +19,8 @@ class XpathTest < Test::Unit::TestCase
19
19
  end
20
20
 
21
21
  test "xpath with attributes" do
22
- path = Xpath.new(['input', 'button'], :type => 'text', :id => 'foo').to_s
23
- assert_equal %(.//input[@type="text"][@id="foo"] | .//button[@type="text"][@id="foo"]), path
22
+ path = Xpath.new(['input', 'button'], :type => 'text', :id => 'foo')
23
+ assert_equal %(.//input[@type="text"][@id="foo"] | .//button[@type="text"][@id="foo"]), path.to_s
24
24
  end
25
25
 
26
26
  test "xpath with alternate nodenames and attributes" do
data/test/locator_test.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require File.expand_path('../test_helper', __FILE__)
2
3
 
3
4
  class LocatorTest < Test::Unit::TestCase
@@ -86,4 +87,46 @@ class LocatorTest < Test::Unit::TestCase
86
87
  html = '<form></form><div><form><p id="foo"><p></form></div>'
87
88
  assert_nil locate(html, :div) { locate(html, :form, :class => 'bar') { locate(html, :p) } }
88
89
  end
90
+
91
+ # locate with umlauts
92
+
93
+ test "locates an element by encoded selector from html containing an encoded umlaut" do
94
+ html = '<span>Berlin</span><span>M&uuml;nchen</span>'
95
+ assert_equal 'München', locate(html, 'M&uuml;nchen').content
96
+ end
97
+
98
+ test "locates an element by encoded selector from html containing an non-encoded umlaut" do
99
+ html = '<span>Berlin</span><span>München</span>'
100
+ assert_equal 'München', locate(html, 'M&uuml;nchen').content
101
+ end
102
+
103
+ test "locates an element by non-encoded selector from html containing an encoded umlaut" do
104
+ html = '<span>Berlin</span><span>M&uuml;nchen</span>'
105
+ assert_equal 'München', locate(html, 'München').content
106
+ end
107
+
108
+ test "locates an element by non-encoded selector from html containing a non-encoded umlaut" do
109
+ html = '<span>Berlin</span><span>München</span>'
110
+ assert_equal 'München', locate(html, 'München').content
111
+ end
112
+
113
+ test "locates an element by encoded attribute from html containing an encoded umlaut" do
114
+ html = '<input type="text" value="M&uuml;nchen">'
115
+ assert_equal 'München', locate(html, :value => 'M&uuml;nchen').value
116
+ end
117
+
118
+ test "locates an element by encoded attribute from html containing an non-encoded umlaut" do
119
+ html = '<input type="text" value="München">'
120
+ assert_equal 'München', locate(html, :value => 'M&uuml;nchen').value
121
+ end
122
+
123
+ test "locates an element by non-encoded attribute from html containing an encoded umlaut" do
124
+ html = '<input type="text" value="M&uuml;nchen">'
125
+ assert_equal 'München', locate(html, :value => 'München').value
126
+ end
127
+
128
+ test "locates an element by non-encoded attribute from html containing a non-encoded umlaut" do
129
+ html = '<input type="text" value="München">'
130
+ assert_equal 'München', locate(html, :value => 'München').value
131
+ end
89
132
  end
data/test/test_helper.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  $:.unshift File.expand_path("../lib", File.dirname(__FILE__))
2
- $:.unshift(File.expand_path(File.dirname(__FILE__)))
3
2
 
4
3
  require 'test/unit'
5
4
  require 'locator'
@@ -7,7 +6,7 @@ require 'locator'
7
6
  module TestMethod
8
7
  def self.included(base)
9
8
  base.class_eval do
10
- def test(name, &block)
9
+ def self.test(name, &block)
11
10
  test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
12
11
  defined = instance_method(test_name) rescue false
13
12
  raise "#{test_name} is already defined in #{self}" if defined
@@ -29,4 +28,4 @@ end
29
28
 
30
29
  class Test::Unit::TestCase
31
30
  include TestMethod
32
- end
31
+ end
data/test/webrat.rb ADDED
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../test_helper', __FILE__)
3
+ require 'action_pack'
4
+ require 'webrat'
5
+ require 'rack/test'
6
+
7
+ Webrat.configure do |config|
8
+ config.mode = :rack
9
+ end
10
+
11
+ class WebratBehaviorTest < Test::Unit::TestCase
12
+ include Webrat::Methods
13
+
14
+ def last_response
15
+ @last_response ||= Rack::Response.new
16
+ end
17
+
18
+ def with_html(html)
19
+ last_response.body = html
20
+ end
21
+
22
+ test "foo" do
23
+ with_html '<span>München</span>'
24
+ field = field_by_xpath(".//span")
25
+ p field.element.to_s
26
+ end
27
+ end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: locator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 6
9
+ version: 0.0.6
5
10
  platform: ruby
6
11
  authors:
7
12
  - Sven Fuchs
@@ -9,10 +14,21 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-02-28 00:00:00 +01:00
17
+ date: 2010-04-02 00:00:00 +02:00
13
18
  default_executable:
14
- dependencies: []
15
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: htmlentities
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
16
32
  description: Generic html element locators for integration testing
17
33
  email: svenfuchs@artweb-design.de
18
34
  executables: []
@@ -31,6 +47,7 @@ files:
31
47
  - lib/core_ext/string/underscore.rb
32
48
  - lib/locator.rb
33
49
  - lib/locator/boolean.rb
50
+ - lib/locator/decoding.rb
34
51
  - lib/locator/dom.rb
35
52
  - lib/locator/dom/htmlunit.rb
36
53
  - lib/locator/dom/htmlunit/element.rb
@@ -81,6 +98,7 @@ files:
81
98
  - test/locator/xpath_test.rb
82
99
  - test/locator_test.rb
83
100
  - test/test_helper.rb
101
+ - test/webrat.rb
84
102
  has_rdoc: true
85
103
  homepage: http://github.com/svenfuchs/locator
86
104
  licenses: []
@@ -94,18 +112,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
94
112
  requirements:
95
113
  - - ">="
96
114
  - !ruby/object:Gem::Version
115
+ segments:
116
+ - 0
97
117
  version: "0"
98
- version:
99
118
  required_rubygems_version: !ruby/object:Gem::Requirement
100
119
  requirements:
101
120
  - - ">="
102
121
  - !ruby/object:Gem::Version
122
+ segments:
123
+ - 0
103
124
  version: "0"
104
- version:
105
125
  requirements: []
106
126
 
107
127
  rubyforge_project:
108
- rubygems_version: 1.3.5
128
+ rubygems_version: 1.3.6
109
129
  signing_key:
110
130
  specification_version: 3
111
131
  summary: Generic html element locators for integration testing
@@ -129,3 +149,4 @@ test_files:
129
149
  - test/locator/xpath_test.rb
130
150
  - test/locator_test.rb
131
151
  - test/test_helper.rb
152
+ - test/webrat.rb