locator 0.0.5 → 0.0.6

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