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 |  |