locator 0.0.1
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/README.textile +5 -0
- data/Rakefile +19 -0
- data/lib/core_ext/string/underscore.rb +5 -0
- data/lib/locator/boolean.rb +50 -0
- data/lib/locator/dom/nokogiri/element.rb +49 -0
- data/lib/locator/dom/nokogiri/page.rb +25 -0
- data/lib/locator/dom/nokogiri.rb +10 -0
- data/lib/locator/dom.rb +21 -0
- data/lib/locator/element/area.rb +9 -0
- data/lib/locator/element/button.rb +11 -0
- data/lib/locator/element/elements_list.rb +15 -0
- data/lib/locator/element/field.rb +10 -0
- data/lib/locator/element/form.rb +9 -0
- data/lib/locator/element/label.rb +9 -0
- data/lib/locator/element/labeled_element.rb +17 -0
- data/lib/locator/element/link.rb +9 -0
- data/lib/locator/element/select.rb +9 -0
- data/lib/locator/element/select_option.rb +9 -0
- data/lib/locator/element/text_area.rb +9 -0
- data/lib/locator/element.rb +45 -0
- data/lib/locator/version.rb +3 -0
- data/lib/locator/xpath.rb +38 -0
- data/lib/locator.rb +52 -0
- data/test/all.rb +3 -0
- data/test/locator/boolean_test.rb +40 -0
- data/test/locator/element/button_test.rb +26 -0
- data/test/locator/element/field_test.rb +60 -0
- data/test/locator/element/form_test.rb +30 -0
- data/test/locator/element/label_test.rb +26 -0
- data/test/locator/element/link_test.rb +34 -0
- data/test/locator/element/select_option_test.rb +34 -0
- data/test/locator/element/select_test.rb +26 -0
- data/test/locator/element/text_area_test.rb +26 -0
- data/test/locator/element_test.rb +40 -0
- data/test/locator/xpath_test.rb +50 -0
- data/test/locator_test.rb +31 -0
- data/test/test_helper.rb +46 -0
- metadata +104 -0
    
        data/README.textile
    ADDED
    
    | @@ -0,0 +1,5 @@ | |
| 1 | 
            +
            h1. Locator
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            This library aims to extract common html element selection from testing tools such as "Webrat":http://github.com/brynary/webrat/blob/master/lib/webrat/core/locators.rb, "Capybara":http://github.com/jnicklas/capybara/blob/master/lib/capybara/xpath.rb or "Steam":http://github.com/svenfuchs/steam/blob/master/lib/steam/locators.rb.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            At its core it constructs "XPath":http://github.com/svenfuchs/locator/blob/master/lib/locator/xpath.rb objects using a simple "boolean expression engine":http://github.com/svenfuchs/locator/blob/master/lib/locator/boolean.rb in order to locate elements in a Nokogiri DOM. It provides a bunch of "Element classes":http://github.com/svenfuchs/locator/blob/master/lib/locator/element.rb that are targeted at implementing a Webrat-style DSL for convenience.
         | 
    
        data/Rakefile
    ADDED
    
    | @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            require 'rake/testtask'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require File.expand_path("../lib/locator/version", __FILE__)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            begin
         | 
| 6 | 
            +
              require 'jeweler'
         | 
| 7 | 
            +
              Jeweler::Tasks.new do |s|
         | 
| 8 | 
            +
                s.name = "locator"
         | 
| 9 | 
            +
                s.version = Locator::VERSION
         | 
| 10 | 
            +
                s.summary = "Generic html element locators for integration testing"
         | 
| 11 | 
            +
                s.email = "svenfuchs@artweb-design.de"
         | 
| 12 | 
            +
                s.homepage = "http://github.com/svenfuchs/locator"
         | 
| 13 | 
            +
                s.description = "Generic html element locators for integration testing"
         | 
| 14 | 
            +
                s.authors = ['Sven Fuchs']
         | 
| 15 | 
            +
                s.files =  FileList["[A-Z]*", "{lib,test,vendor}/**/*"]
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            rescue LoadError
         | 
| 18 | 
            +
              puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            class Locator
         | 
| 2 | 
            +
              module Boolean
         | 
| 3 | 
            +
                class Terms < Array
         | 
| 4 | 
            +
                  def and!(other)
         | 
| 5 | 
            +
                    replace(self.dup.and(other))
         | 
| 6 | 
            +
                  end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  def and(other)
         | 
| 9 | 
            +
                    other.empty? ? self : And.new(self, other)
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
                  alias & and
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def or!(other)
         | 
| 14 | 
            +
                    replace(self.dup.or(other))
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def or(other)
         | 
| 18 | 
            +
                    other.empty? ? self : Or.new(self, other)
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                  alias | and
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def to_s
         | 
| 23 | 
            +
                    flatten.join(Or.operator)
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                module Accessors
         | 
| 28 | 
            +
                  def operator=(operator); @operator = operator end
         | 
| 29 | 
            +
                  def operator; @operator end
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                class And < Terms
         | 
| 33 | 
            +
                  extend Accessors
         | 
| 34 | 
            +
                  self.operator = ' AND '
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  def initialize(lft, rgt)
         | 
| 37 | 
            +
                    replace(lft.map { |l| rgt.map { |r| "#{l}#{self.class.operator}#{r}" } })
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                class Or < Terms
         | 
| 42 | 
            +
                  extend Accessors
         | 
| 43 | 
            +
                  self.operator = ' OR '
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  def initialize(lft, rgt)
         | 
| 46 | 
            +
                    replace([lft, rgt])
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,49 @@ | |
| 1 | 
            +
            class Locator
         | 
| 2 | 
            +
              module Dom
         | 
| 3 | 
            +
                module Nokogiri
         | 
| 4 | 
            +
                  class Element
         | 
| 5 | 
            +
                    attr_reader :element
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                    def initialize(element)
         | 
| 8 | 
            +
                      @element = element
         | 
| 9 | 
            +
                    end
         | 
| 10 | 
            +
                    
         | 
| 11 | 
            +
                    def xpath
         | 
| 12 | 
            +
                      element.path.to_s
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                    
         | 
| 15 | 
            +
                    def css_path
         | 
| 16 | 
            +
                      element.css_path.to_s
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    def inner_html
         | 
| 20 | 
            +
                      element.inner_html
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    def to_s
         | 
| 24 | 
            +
                      element.to_s
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    def tag_name
         | 
| 28 | 
            +
                      element.description.name
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    def ancestor_of?(other)
         | 
| 32 | 
            +
                      other.element.ancestors.include?(element)
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    def attribute(name)
         | 
| 36 | 
            +
                      element.attribute(name).to_s
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    def attributes(names)
         | 
| 40 | 
            +
                      names.map { |name| attribute(name) }
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                    
         | 
| 43 | 
            +
                    def elements_by_xpath(xpath)
         | 
| 44 | 
            +
                      element.xpath(xpath).map { |element| Element.new(element) }
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
            end
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            class Locator
         | 
| 2 | 
            +
              module Dom
         | 
| 3 | 
            +
                module Nokogiri
         | 
| 4 | 
            +
                  class Page
         | 
| 5 | 
            +
                    attr_reader :dom
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                    def initialize(html)
         | 
| 8 | 
            +
                      @dom = ::Nokogiri::HTML::Document.parse(html)
         | 
| 9 | 
            +
                    end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    def element_by_id(id)
         | 
| 12 | 
            +
                      elements_by_xpath("//*[@id='#{id}']").first
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    def elements_by_xpath(xpath)
         | 
| 16 | 
            +
                      @dom.xpath(xpath).map { |element| Element.new(element) }
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    def to_s
         | 
| 20 | 
            +
                      @dom.to_s
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
            end
         | 
    
        data/lib/locator/dom.rb
    ADDED
    
    | @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            require 'nokogiri'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class Locator
         | 
| 4 | 
            +
              module Dom
         | 
| 5 | 
            +
                autoload :Nokogiri, 'locator/dom/nokogiri'
         | 
| 6 | 
            +
                
         | 
| 7 | 
            +
                class << self
         | 
| 8 | 
            +
                  def adapter
         | 
| 9 | 
            +
                    @@adapter ||= Nokogiri
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  def adapter=(adapter)
         | 
| 13 | 
            +
                    @@adapter = adapter
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def page(html)
         | 
| 17 | 
            +
                    adapter::Page.new(html)
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            class Locator
         | 
| 2 | 
            +
              class Element
         | 
| 3 | 
            +
                class Button < ElementsList
         | 
| 4 | 
            +
                  def initialize
         | 
| 5 | 
            +
                    input  = Element.new('input',  [:id, :name, :value, :alt], :type => %w(submit button image))
         | 
| 6 | 
            +
                    button = Element.new('button', [:id, :name, :content])
         | 
| 7 | 
            +
                    super(input, button)
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            class Locator
         | 
| 2 | 
            +
              class Element
         | 
| 3 | 
            +
                class LabeledElement < Element
         | 
| 4 | 
            +
                  attr_reader :labeled
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def initialize(name = '*', locatables = [], attributes = {})
         | 
| 7 | 
            +
                    @labeled = Element.new(name, [], attributes)
         | 
| 8 | 
            +
                    super
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def compose(selector, attributes)
         | 
| 12 | 
            +
                    super
         | 
| 13 | 
            +
                    replace(self + labeled.and("[@id=//label[contains(.,\"#{selector}\")]/@for]")) if selector
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            class Locator
         | 
| 2 | 
            +
              class Element < Xpath
         | 
| 3 | 
            +
                autoload :Area,           'locator/element/area'
         | 
| 4 | 
            +
                autoload :Button,         'locator/element/button'
         | 
| 5 | 
            +
                autoload :ElementsList,   'locator/element/elements_list'
         | 
| 6 | 
            +
                autoload :Field,          'locator/element/field'
         | 
| 7 | 
            +
                autoload :Form,           'locator/element/form'
         | 
| 8 | 
            +
                autoload :Label,          'locator/element/label'
         | 
| 9 | 
            +
                autoload :LabeledElement, 'locator/element/labeled_element'
         | 
| 10 | 
            +
                autoload :Link,           'locator/element/link'
         | 
| 11 | 
            +
                autoload :Select,         'locator/element/select'
         | 
| 12 | 
            +
                autoload :SelectOption,   'locator/element/select_option'
         | 
| 13 | 
            +
                autoload :TextArea,       'locator/element/text_area'
         | 
| 14 | 
            +
                
         | 
| 15 | 
            +
                attr_reader :locatables
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def initialize(name = '*', locatables = [], attributes = {})
         | 
| 18 | 
            +
                  super(name)
         | 
| 19 | 
            +
                  @content = !!locatables.delete(:content)
         | 
| 20 | 
            +
                  @locatables = locatables
         | 
| 21 | 
            +
                  @attributes = attributes
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def xpath(*args)
         | 
| 25 | 
            +
                  attributes = Hash === args.last ? args.pop : {}
         | 
| 26 | 
            +
                  compose(args.pop, attributes)
         | 
| 27 | 
            +
                  to_s
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                protected
         | 
| 31 | 
            +
                
         | 
| 32 | 
            +
                  def content?
         | 
| 33 | 
            +
                    @content
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  def compose(selector, attributes)
         | 
| 37 | 
            +
                    attributes = @attributes.merge(attributes)
         | 
| 38 | 
            +
                    attributes.each { |name, value| and! equals(name, value) }
         | 
| 39 | 
            +
                    terms = []
         | 
| 40 | 
            +
                    terms << equals(locatables, selector) if selector
         | 
| 41 | 
            +
                    terms << contains(selector) if content? && selector
         | 
| 42 | 
            +
                    and!(terms) unless terms.empty?
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            class Locator
         | 
| 2 | 
            +
              autoload :Boolean, 'locator/boolean'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              Boolean::Or.operator, Boolean::And.operator = ' | ', ''
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              class Xpath < Boolean::Terms
         | 
| 7 | 
            +
                def initialize(name = nil, attributes = {})
         | 
| 8 | 
            +
                  names = Array(name || '*').map { |name| xpath?(name) ? name : ".//#{name}" }
         | 
| 9 | 
            +
                  super(names)
         | 
| 10 | 
            +
                  attributes.each { |name, value| and!(equals(name, value)) }
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def equals(names, values)
         | 
| 14 | 
            +
                  case values
         | 
| 15 | 
            +
                  when TrueClass
         | 
| 16 | 
            +
                    "[@#{names}]"
         | 
| 17 | 
            +
                  else
         | 
| 18 | 
            +
                    values = Array(values).map { |value| xpath?(value) ? value : "\"#{value}\"" }
         | 
| 19 | 
            +
                    expr = Array(names).map { |name| values.map { |value| "@#{name}=#{value}" } }
         | 
| 20 | 
            +
                    expr.empty? ? '' : '[' + expr.flatten.join(' or ') + ']'
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def matches(name, value)
         | 
| 25 | 
            +
                  "[contains(@#{name},\"#{value}\")]"
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def contains(value)
         | 
| 29 | 
            +
                  "/descendant-or-self::*[contains(.,\"#{value}\")]"
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                protected
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def xpath?(string)
         | 
| 35 | 
            +
                    string.to_s[0, 1] == '/'
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
            end
         | 
    
        data/lib/locator.rb
    ADDED
    
    | @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            require 'core_ext/string/underscore'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class Locator
         | 
| 4 | 
            +
              autoload :Actions, 'locator/actions'
         | 
| 5 | 
            +
              autoload :Dom,     'locator/dom'
         | 
| 6 | 
            +
              autoload :Element, 'locator/element'
         | 
| 7 | 
            +
              autoload :Xpath,   'locator/xpath'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              class << self
         | 
| 10 | 
            +
                def [](type)
         | 
| 11 | 
            +
                  locators[type.to_sym]
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def xpath(type, *args)
         | 
| 15 | 
            +
                  Locator[type].new.xpath(*args)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                protected
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def locators
         | 
| 21 | 
            +
                    @locators ||= Hash[*Element.constants.map do |name|
         | 
| 22 | 
            +
                      [name.underscore.to_sym, Element.const_get(name)]
         | 
| 23 | 
            +
                    end.flatten]
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              attr_reader :dom, :scopes
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def initialize(dom)
         | 
| 30 | 
            +
                @dom = dom.respond_to?(:elements_by_xpath) ? dom : Dom.page(dom)
         | 
| 31 | 
            +
                @scopes = []
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def locate(type, *args)
         | 
| 35 | 
            +
                options = Hash === args.last ? args.last : {}
         | 
| 36 | 
            +
                if scope = options.delete(:within)
         | 
| 37 | 
            +
                  within(scope) { locate(type, *args) }
         | 
| 38 | 
            +
                else
         | 
| 39 | 
            +
                  path = type.is_a?(Symbol) ? Locator.xpath(type, *args) : type
         | 
| 40 | 
            +
                  scope = scopes.pop || dom
         | 
| 41 | 
            +
                  scope.elements_by_xpath(path).first
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              # TODO currently only take an xpath or element
         | 
| 46 | 
            +
              def within(scope, &block)
         | 
| 47 | 
            +
                scope = scope.is_a?(Hash) ? scope.delete(:xpath) : scope
         | 
| 48 | 
            +
                scope = locate(scope) unless scope.respond_to?(:xpath)
         | 
| 49 | 
            +
                scopes.push(scope)
         | 
| 50 | 
            +
                instance_eval(&block)
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
    
        data/test/all.rb
    ADDED
    
    
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            require File.expand_path('../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/xpath'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class XpathBooleanTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              Or, And = Locator::Boolean::Or, Locator::Boolean::And
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def setup
         | 
| 8 | 
            +
                Or.operator, And.operator = ' | ', ' & '
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              test "a | b => a | b" do
         | 
| 12 | 
            +
                path = Or.new('a', 'b').to_s
         | 
| 13 | 
            +
                assert_equal "a | b", path
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              test "a & b => a & b" do
         | 
| 17 | 
            +
                path = And.new('a', 'b').to_s
         | 
| 18 | 
            +
                assert_equal "a & b", path
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              test "(a & b) | c => a & b | c" do
         | 
| 22 | 
            +
                path = And.new('a', 'b').or('c').to_s
         | 
| 23 | 
            +
                assert_equal "a & b | c", path
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              test "(a | b) & c => a & c | b & c" do
         | 
| 27 | 
            +
                path = Or.new('a', 'b').and('c').to_s
         | 
| 28 | 
            +
                assert_equal "a & c | b & c", path
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              test "(a & b | c) & d => a & b & d | c & d" do
         | 
| 32 | 
            +
                path = And.new('a', 'b').or('c').and('d').to_s
         | 
| 33 | 
            +
                assert_equal "a & b & d | c & d", path
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              test "(a & b | c) & (d | e) => a & b & d | a & b & e | c & d | c & e" do
         | 
| 37 | 
            +
                path = And.new('a', 'b').or('c').and(Or.new('d', 'e')).to_s
         | 
| 38 | 
            +
                assert_equal "a & b & d | a & b & e | c & d | c & e", path
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ElementButtonTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              Button = Locator::Element::Button
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              test "finds a button" do
         | 
| 8 | 
            +
                assert_locate '<button></button>', Button.new.xpath
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              test "finds a submit input" do
         | 
| 12 | 
            +
                assert_locate '<input type="submit">', Button.new.xpath
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              test "finds a button input" do
         | 
| 16 | 
            +
                assert_locate '<input type="button">', Button.new.xpath
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              test "finds an image input" do
         | 
| 20 | 
            +
                assert_locate '<input type="image">', Button.new.xpath
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              test "does not find a checkbox input" do
         | 
| 24 | 
            +
                assert_no_locate '<input type="checkbox">', Button.new.xpath
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ElementFieldTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              Field = Locator::Element::Field
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              test "finds a textarea" do
         | 
| 8 | 
            +
                assert_locate '<textarea></textarea>', Field.new.xpath
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
              
         | 
| 11 | 
            +
              test "finds a text input" do
         | 
| 12 | 
            +
                assert_locate '<input type="text">', Field.new.xpath
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
              test "finds a password input" do
         | 
| 16 | 
            +
                assert_locate '<input type="password">', Field.new.xpath
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
              
         | 
| 19 | 
            +
              test "finds an email input" do
         | 
| 20 | 
            +
                assert_locate '<input type="email">', Field.new.xpath
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
              
         | 
| 23 | 
            +
              test "finds a url input" do
         | 
| 24 | 
            +
                assert_locate '<input type="url">', Field.new.xpath
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
              
         | 
| 27 | 
            +
              test "finds a search input" do
         | 
| 28 | 
            +
                assert_locate '<input type="search">', Field.new.xpath
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
              
         | 
| 31 | 
            +
              test "finds a tel input" do
         | 
| 32 | 
            +
                assert_locate '<input type="tel">', Field.new.xpath
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
              
         | 
| 35 | 
            +
              test "finds a color input" do
         | 
| 36 | 
            +
                assert_locate '<input type="color">', Field.new.xpath
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              test "finds a text input by name" do
         | 
| 40 | 
            +
                assert_locate '<input type="text" name="foo">', Field.new.xpath('foo')
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              test "finds a text input by class attribute" do
         | 
| 44 | 
            +
                assert_locate '<input type="text" class="foo">', Field.new.xpath(:class => 'foo')
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
              test "finds an input by label content" do
         | 
| 48 | 
            +
                html = '<label for="bar">foo</label><input type="text" id="bar">'
         | 
| 49 | 
            +
                assert_locate html, Field.new.xpath('foo'), '<input type="text" id="bar">'
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              test "finds an input by label content and input class" do
         | 
| 53 | 
            +
                html = '<label for="bar">foo</label><input type="text" id="bar" class="baz">'
         | 
| 54 | 
            +
                assert_locate html, Field.new.xpath('foo', :class => 'baz'), '<input type="text" id="bar" class="baz">'
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              test "does not find a checkbox input" do
         | 
| 58 | 
            +
                assert_no_locate '<input type="checkbox">', Field.new.xpath
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ElementFormTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              Form = Locator::Element::Form
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              test "finds a form" do
         | 
| 8 | 
            +
                assert_locate '<form></form>', Form.new.xpath
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              test "finds a form by id" do
         | 
| 12 | 
            +
                assert_locate '<form id="foo"></form>', Form.new.xpath('foo')
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              test "finds a form by name" do
         | 
| 16 | 
            +
                assert_locate '<form name="foo"></form>', Form.new.xpath('foo')
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              test "finds a form by class" do
         | 
| 20 | 
            +
                assert_locate '<form class="foo"></form>', Form.new.xpath(:class => 'foo')
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              test "does not find a form when id does not match" do
         | 
| 24 | 
            +
                assert_no_locate '<form id="bar"></form>', Form.new.xpath(:class => 'foo')
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              test "does not find a form when class does not match" do
         | 
| 28 | 
            +
                assert_no_locate '<form class="bar"></form>', Form.new.xpath(:class => 'foo')
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ElementLabelTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              Label = Locator::Element::Label
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              test "finds a label" do
         | 
| 8 | 
            +
                assert_locate '<label></label>', Label.new.xpath
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              test "finds a label by id" do
         | 
| 12 | 
            +
                assert_locate '<label id="foo"></label>', Label.new.xpath('foo')
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              test "finds a label by class" do
         | 
| 16 | 
            +
                assert_locate '<label class="foo"></label>', Label.new.xpath(:class => 'foo')
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              test "does not find a label when id does not match" do
         | 
| 20 | 
            +
                assert_no_locate '<label id="bar"></label>', Label.new.xpath(:class => 'foo')
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              test "does not find a label when class does not match" do
         | 
| 24 | 
            +
                assert_no_locate '<label class="bar"></label>', Label.new.xpath(:class => 'foo')
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ElementLinkTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              Link = Locator::Element::Link
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              test "finds a link" do
         | 
| 8 | 
            +
                assert_locate '<a href=""></a>', Link.new.xpath
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              test "finds a link by id" do
         | 
| 12 | 
            +
                assert_locate '<a href="" id="foo"></a>', Link.new.xpath('foo')
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              test "finds a link by class" do
         | 
| 16 | 
            +
                assert_locate '<a href="" class="foo"></a>', Link.new.xpath(:class => 'foo')
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              test "finds an link by content" do
         | 
| 20 | 
            +
                assert_locate '<a href="">foo</a>', Link.new.xpath('foo')
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              test "does not find an anchor" do
         | 
| 24 | 
            +
                assert_no_locate '<a name=""></a>', Link.new.xpath
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              test "does not find a link when id does not match" do
         | 
| 28 | 
            +
                assert_no_locate '<a href="" id="bar"></a>', Link.new.xpath(:class => 'foo')
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              test "does not find a link when class does not match" do
         | 
| 32 | 
            +
                assert_no_locate '<a href="" class="bar"></a>', Link.new.xpath(:class => 'foo')
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ElementSelectOptionOptionTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              SelectOption = Locator::Element::SelectOption
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              test "finds an option" do
         | 
| 8 | 
            +
                assert_locate '<option></option>', SelectOption.new.xpath
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              test "finds an option by id" do
         | 
| 12 | 
            +
                assert_locate '<option id="foo"></option>', SelectOption.new.xpath('foo')
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              test "finds an option by value" do
         | 
| 16 | 
            +
                assert_locate '<option value="foo"></option>', SelectOption.new.xpath('foo')
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              test "finds an option by content" do
         | 
| 20 | 
            +
                assert_locate '<option>foo</option>', SelectOption.new.xpath('foo')
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              test "finds an option by class attribute" do
         | 
| 24 | 
            +
                assert_locate '<option class="foo"></option>', SelectOption.new.xpath(:class => 'foo')
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              test "does not find an option when id does not match" do
         | 
| 28 | 
            +
                assert_no_locate '<option id="bar"></option>', SelectOption.new.xpath(:class => 'foo')
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              test "does not find an option when class does not match" do
         | 
| 32 | 
            +
                assert_no_locate '<option class="bar"></option>', SelectOption.new.xpath(:class => 'foo')
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ElementSelectTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              Select = Locator::Element::Select
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              test "finds a select" do
         | 
| 8 | 
            +
                assert_locate '<select></select>', Select.new.xpath
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              test "finds a select by id" do
         | 
| 12 | 
            +
                assert_locate '<select id="foo"></select>', Select.new.xpath('foo')
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              test "finds a select by class" do
         | 
| 16 | 
            +
                assert_locate '<select class="foo"></select>', Select.new.xpath(:class => 'foo')
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              test "does not find a select when id does not match" do
         | 
| 20 | 
            +
                assert_no_locate '<select id="bar"></select>', Select.new.xpath(:class => 'foo')
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              test "does not find a select when class does not match" do
         | 
| 24 | 
            +
                assert_no_locate '<select class="bar"></select>', Select.new.xpath(:class => 'foo')
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ElementTextAreaTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              TextArea = Locator::Element::TextArea
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              test "finds a textarea" do
         | 
| 8 | 
            +
                assert_locate '<textarea></textarea>', TextArea.new.xpath
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              test "finds a textarea by id" do
         | 
| 12 | 
            +
                assert_locate '<textarea id="foo"></textarea>', TextArea.new.xpath('foo')
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              test "finds a textarea by class" do
         | 
| 16 | 
            +
                assert_locate '<textarea class="foo"></textarea>', TextArea.new.xpath(:class => 'foo')
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              test "does not find a textarea when id does not match" do
         | 
| 20 | 
            +
                assert_no_locate '<textarea id="bar"></textarea>', TextArea.new.xpath(:class => 'foo')
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              test "does not find a textarea when class does not match" do
         | 
| 24 | 
            +
                assert_no_locate '<textarea class="bar"></textarea>', TextArea.new.xpath(:class => 'foo')
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            require File.expand_path('../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ElementTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              def xpath(*args)
         | 
| 6 | 
            +
                Locator::Element.new('foo', [:id, :content]).xpath(*args)
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              test "no selector given => finds all element" do
         | 
| 10 | 
            +
                assert_locate '<foo></foo><foo></foo>', xpath, ['<foo></foo>', '<foo></foo>']
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
              
         | 
| 13 | 
            +
              test "given selector equals content => finds the element" do
         | 
| 14 | 
            +
                assert_locate '<foo>foo</foo>', xpath('foo')
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
              
         | 
| 17 | 
            +
              test "given selector contained in content => finds the element" do
         | 
| 18 | 
            +
                assert_locate '<foo>foo!</foo>', xpath('foo')
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
              
         | 
| 21 | 
            +
              test "given selector equals id => finds the element" do
         | 
| 22 | 
            +
                assert_locate '<foo id="foo"></foo>', xpath('foo')
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
              
         | 
| 25 | 
            +
              test "given selector contained in id => does not find the element" do
         | 
| 26 | 
            +
                assert_no_locate '<foo id="foobar"></foo>', xpath('foo')
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
              
         | 
| 29 | 
            +
              test "given attribute equals attribute => finds the element" do
         | 
| 30 | 
            +
                assert_locate '<foo class="foo">a</foo>', xpath(:class => 'foo')
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
              
         | 
| 33 | 
            +
              test "given attribute contained in attribute => does not find the element" do
         | 
| 34 | 
            +
                assert_no_locate '<foo class="foo-bar">a</foo>', xpath(:class => 'foo')
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
              
         | 
| 37 | 
            +
              test "selector + attributes => finds the element" do
         | 
| 38 | 
            +
                assert_locate '<foo class="foo" title="bar">bar</foo>', xpath('bar', :class => 'foo', :title => 'bar')
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            require File.expand_path('../../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/xpath'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class XpathTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              Xpath = Locator::Xpath
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def setup
         | 
| 8 | 
            +
                Locator::Boolean::Or.operator, Locator::Boolean::And.operator = ' | ', ''
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              test "simple xpath" do
         | 
| 12 | 
            +
                path = Xpath.new('input').to_s
         | 
| 13 | 
            +
                assert_equal ".//input", path
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              test "xpath with alternate nodenames" do
         | 
| 17 | 
            +
                path = Xpath.new(['input', 'button']).to_s
         | 
| 18 | 
            +
                assert_equal ".//input | .//button", path
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 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
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              test "xpath with alternate nodenames and attributes" do
         | 
| 27 | 
            +
                path = Xpath.new(['input', 'button']).to_s
         | 
| 28 | 
            +
                assert_equal ".//input | .//button", path
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              test "xpath or xpath" do
         | 
| 32 | 
            +
                path = Xpath.new('input', :type => 'text').or!(Xpath.new('textarea')).to_s
         | 
| 33 | 
            +
                assert_equal %(.//input[@type="text"] | .//textarea), path
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
              
         | 
| 36 | 
            +
              test "attribute equals to one of multiple values" do
         | 
| 37 | 
            +
                path = Xpath.new('input', :type => [:text, :password]).to_s
         | 
| 38 | 
            +
                assert_equal %(.//input[@type="text" or @type="password"]), path
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
              
         | 
| 41 | 
            +
              test "one of multiple attributes equals to value" do
         | 
| 42 | 
            +
                path = Xpath.new('input', [:id, :name] => 'foo').to_s
         | 
| 43 | 
            +
                assert_equal %(.//input[@id="foo" or @name="foo"]), path
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
              
         | 
| 46 | 
            +
              test "one of multiple attributes equals to one of multiple values" do
         | 
| 47 | 
            +
                path = Xpath.new('input', [:id, :name] => ['foo', 'bar']).to_s
         | 
| 48 | 
            +
                assert_equal %(.//input[@id="foo" or @id="bar" or @name="foo" or @name="bar"]), path
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            require File.expand_path('../test_helper', __FILE__)
         | 
| 2 | 
            +
            require 'locator/element'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class LocatorTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              test "looks up a locator/element class by type" do
         | 
| 6 | 
            +
                assert_equal Locator::Element::Field, Locator[:field]
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              test "generates an xpath for type and given args" do
         | 
| 10 | 
            +
                path = Locator.xpath(:form, 'foo', :class => 'bar')
         | 
| 11 | 
            +
                assert_equal './/form[@class="bar"][@id="foo" or @name="foo"]', path
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              test "locates an element from html" do
         | 
| 15 | 
            +
                html = '<html><body><h1></h1><form class="bar"></form></body></html>'
         | 
| 16 | 
            +
                element = Locator.new(html).locate(:form, :class => 'bar')
         | 
| 17 | 
            +
                assert_equal '<form class="bar"></form>', element.to_s
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              test "within scopes to an xpath" do
         | 
| 21 | 
            +
                html = '<form id="foo"></form><div id="bar"><form></form></div>'
         | 
| 22 | 
            +
                element = Locator.new(html).within(:xpath => '//div[@id="bar"]') { locate(:form) }
         | 
| 23 | 
            +
                assert_equal '<form></form>', element.to_s
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              test "locates scopes to :within option" do
         | 
| 27 | 
            +
                html = '<form id="foo"></form><div id="bar"><form></form></div>'
         | 
| 28 | 
            +
                element = Locator.new(html).locate(:form, :within => '//div[@id="bar"]')
         | 
| 29 | 
            +
                assert_equal '<form></form>', element.to_s
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
    
        data/test/test_helper.rb
    ADDED
    
    | @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            $:.unshift File.expand_path("../lib", File.dirname(__FILE__))
         | 
| 2 | 
            +
            $:.unshift(File.expand_path(File.dirname(__FILE__)))
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'test/unit'
         | 
| 5 | 
            +
            require 'locator'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module TestMethod
         | 
| 8 | 
            +
              def self.included(base)
         | 
| 9 | 
            +
                base.class_eval do
         | 
| 10 | 
            +
                  def test(name, &block)
         | 
| 11 | 
            +
                    test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
         | 
| 12 | 
            +
                    defined = instance_method(test_name) rescue false
         | 
| 13 | 
            +
                    raise "#{test_name} is already defined in #{self}" if defined
         | 
| 14 | 
            +
                    if block_given?
         | 
| 15 | 
            +
                      define_method(test_name, &block)
         | 
| 16 | 
            +
                    else
         | 
| 17 | 
            +
                      define_method(test_name) do
         | 
| 18 | 
            +
                        flunk "No implementation provided for #{name}"
         | 
| 19 | 
            +
                      end
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            class Module
         | 
| 27 | 
            +
              include TestMethod
         | 
| 28 | 
            +
            end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            class Test::Unit::TestCase
         | 
| 31 | 
            +
              include TestMethod
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              def dom(html)
         | 
| 34 | 
            +
                Locator::Dom.page(html)
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
              
         | 
| 37 | 
            +
              def assert_locate(html, path, elements = nil)
         | 
| 38 | 
            +
                expected = Array(elements || html)
         | 
| 39 | 
            +
                result   = dom(html).elements_by_xpath(path).map(&:to_s)
         | 
| 40 | 
            +
                assert_equal expected, result
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
              
         | 
| 43 | 
            +
              def assert_no_locate(html, path)
         | 
| 44 | 
            +
                assert_locate(html, path, [])
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,104 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification 
         | 
| 2 | 
            +
            name: locator
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              version: 0.0.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors: 
         | 
| 7 | 
            +
            - Sven Fuchs
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            date: 2010-02-04 00:00:00 +01:00
         | 
| 13 | 
            +
            default_executable: 
         | 
| 14 | 
            +
            dependencies: []
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            description: Generic html element locators for integration testing
         | 
| 17 | 
            +
            email: svenfuchs@artweb-design.de
         | 
| 18 | 
            +
            executables: []
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            extensions: []
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            extra_rdoc_files: 
         | 
| 23 | 
            +
            - README.textile
         | 
| 24 | 
            +
            files: 
         | 
| 25 | 
            +
            - README.textile
         | 
| 26 | 
            +
            - Rakefile
         | 
| 27 | 
            +
            - lib/core_ext/string/underscore.rb
         | 
| 28 | 
            +
            - lib/locator.rb
         | 
| 29 | 
            +
            - lib/locator/boolean.rb
         | 
| 30 | 
            +
            - lib/locator/dom.rb
         | 
| 31 | 
            +
            - lib/locator/dom/nokogiri.rb
         | 
| 32 | 
            +
            - lib/locator/dom/nokogiri/element.rb
         | 
| 33 | 
            +
            - lib/locator/dom/nokogiri/page.rb
         | 
| 34 | 
            +
            - lib/locator/element.rb
         | 
| 35 | 
            +
            - lib/locator/element/area.rb
         | 
| 36 | 
            +
            - lib/locator/element/button.rb
         | 
| 37 | 
            +
            - lib/locator/element/elements_list.rb
         | 
| 38 | 
            +
            - lib/locator/element/field.rb
         | 
| 39 | 
            +
            - lib/locator/element/form.rb
         | 
| 40 | 
            +
            - lib/locator/element/label.rb
         | 
| 41 | 
            +
            - lib/locator/element/labeled_element.rb
         | 
| 42 | 
            +
            - lib/locator/element/link.rb
         | 
| 43 | 
            +
            - lib/locator/element/select.rb
         | 
| 44 | 
            +
            - lib/locator/element/select_option.rb
         | 
| 45 | 
            +
            - lib/locator/element/text_area.rb
         | 
| 46 | 
            +
            - lib/locator/version.rb
         | 
| 47 | 
            +
            - lib/locator/xpath.rb
         | 
| 48 | 
            +
            - test/all.rb
         | 
| 49 | 
            +
            - test/locator/boolean_test.rb
         | 
| 50 | 
            +
            - test/locator/element/button_test.rb
         | 
| 51 | 
            +
            - test/locator/element/field_test.rb
         | 
| 52 | 
            +
            - test/locator/element/form_test.rb
         | 
| 53 | 
            +
            - test/locator/element/label_test.rb
         | 
| 54 | 
            +
            - test/locator/element/link_test.rb
         | 
| 55 | 
            +
            - test/locator/element/select_option_test.rb
         | 
| 56 | 
            +
            - test/locator/element/select_test.rb
         | 
| 57 | 
            +
            - test/locator/element/text_area_test.rb
         | 
| 58 | 
            +
            - test/locator/element_test.rb
         | 
| 59 | 
            +
            - test/locator/xpath_test.rb
         | 
| 60 | 
            +
            - test/locator_test.rb
         | 
| 61 | 
            +
            - test/test_helper.rb
         | 
| 62 | 
            +
            has_rdoc: true
         | 
| 63 | 
            +
            homepage: http://github.com/svenfuchs/locator
         | 
| 64 | 
            +
            licenses: []
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            post_install_message: 
         | 
| 67 | 
            +
            rdoc_options: 
         | 
| 68 | 
            +
            - --charset=UTF-8
         | 
| 69 | 
            +
            require_paths: 
         | 
| 70 | 
            +
            - lib
         | 
| 71 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 72 | 
            +
              requirements: 
         | 
| 73 | 
            +
              - - ">="
         | 
| 74 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 75 | 
            +
                  version: "0"
         | 
| 76 | 
            +
              version: 
         | 
| 77 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 78 | 
            +
              requirements: 
         | 
| 79 | 
            +
              - - ">="
         | 
| 80 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 81 | 
            +
                  version: "0"
         | 
| 82 | 
            +
              version: 
         | 
| 83 | 
            +
            requirements: []
         | 
| 84 | 
            +
             | 
| 85 | 
            +
            rubyforge_project: 
         | 
| 86 | 
            +
            rubygems_version: 1.3.5
         | 
| 87 | 
            +
            signing_key: 
         | 
| 88 | 
            +
            specification_version: 3
         | 
| 89 | 
            +
            summary: Generic html element locators for integration testing
         | 
| 90 | 
            +
            test_files: 
         | 
| 91 | 
            +
            - test/all.rb
         | 
| 92 | 
            +
            - test/locator/boolean_test.rb
         | 
| 93 | 
            +
            - test/locator/element/button_test.rb
         | 
| 94 | 
            +
            - test/locator/element/field_test.rb
         | 
| 95 | 
            +
            - test/locator/element/form_test.rb
         | 
| 96 | 
            +
            - test/locator/element/label_test.rb
         | 
| 97 | 
            +
            - test/locator/element/link_test.rb
         | 
| 98 | 
            +
            - test/locator/element/select_option_test.rb
         | 
| 99 | 
            +
            - test/locator/element/select_test.rb
         | 
| 100 | 
            +
            - test/locator/element/text_area_test.rb
         | 
| 101 | 
            +
            - test/locator/element_test.rb
         | 
| 102 | 
            +
            - test/locator/xpath_test.rb
         | 
| 103 | 
            +
            - test/locator_test.rb
         | 
| 104 | 
            +
            - test/test_helper.rb
         |