selenium_plus 0.0.4 → 0.0.5
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/features/drivers.feature +19 -1
- data/features/finders.feature +4 -0
- data/features/select.feature +28 -0
- data/features/step_definitions/drivers_steps.rb +30 -0
- data/features/step_definitions/finder_steps.rb +5 -1
- data/features/step_definitions/general_steps.rb +0 -3
- data/features/step_definitions/select_steps.rb +36 -0
- data/features/step_definitions/tables_steps.rb +15 -0
- data/features/support/env.rb +2 -1
- data/features/tables.feature +14 -5
- data/lib/selenium_plus.rb +11 -2
- data/lib/selenium_plus/driver.rb +4 -28
- data/lib/selenium_plus/finders.rb +19 -3
- data/lib/selenium_plus/page_obj/page.rb +0 -8
- data/lib/selenium_plus/page_obj/section.rb +0 -9
- data/lib/selenium_plus/selenium/element.rb +2 -14
- data/lib/selenium_plus/selenium/select.rb +58 -0
- data/lib/selenium_plus/selenium/table.rb +11 -11
- data/lib/selenium_plus/version.rb +1 -1
- data/selenium_plus.gemspec +2 -1
- data/test_site/html/home.html +48 -7
- data/test_site/pages/home_page.rb +2 -1
- data/test_site/sections/info_section.rb +2 -0
- metadata +29 -11
    
        data/features/drivers.feature
    CHANGED
    
    | @@ -8,4 +8,22 @@ Feature: Verify drivers | |
| 8 8 | 
             
              @chrome
         | 
| 9 9 | 
             
              Scenario: navigate using @chrome tag calls chrome driver
         | 
| 10 10 | 
             
                When I login to home page
         | 
| 11 | 
            -
                Then Current browser should be chrome
         | 
| 11 | 
            +
                Then Current browser should be chrome
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              Scenario: Verify execute script
         | 
| 14 | 
            +
                When I login to home page
         | 
| 15 | 
            +
                And I execute script: document.activeElement.style.border='2px solid red'
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              Scenario: Verify evaluate script
         | 
| 18 | 
            +
                When I login to home page
         | 
| 19 | 
            +
                Then I evaluate script: document.getElementById('home_title').textContent
         | 
| 20 | 
            +
                And Evaluate value should be: Test Home Page
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              Scenario: Verify save a screen shot
         | 
| 23 | 
            +
                When I login to home page
         | 
| 24 | 
            +
                Then I save a screenshot
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              Scenario: Verify save a screen shot
         | 
| 27 | 
            +
                When I login to home page
         | 
| 28 | 
            +
                And I click show button
         | 
| 29 | 
            +
                Then Active element value should be: Show
         | 
    
        data/features/finders.feature
    CHANGED
    
    | @@ -8,6 +8,10 @@ Feature: Verify finders | |
| 8 8 | 
             
                When I login to home page
         | 
| 9 9 | 
             
                And Title outside div#info should be: Test Home Page
         | 
| 10 10 |  | 
| 11 | 
            +
              Scenario: Verify element existence
         | 
| 12 | 
            +
                When I login to home page
         | 
| 13 | 
            +
                And Element show_btn should exist
         | 
| 14 | 
            +
             | 
| 11 15 | 
             
              Scenario: Verify find elements using driver.all
         | 
| 12 16 | 
             
                When I login to home page
         | 
| 13 17 | 
             
                And Titles should be:
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            Feature: Verify Select Element
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              Scenario: Verify Select Options
         | 
| 4 | 
            +
                When I login to home page
         | 
| 5 | 
            +
                Then Single select 'select_options' should be:
         | 
| 6 | 
            +
                | Volvo | Saab | Mercedes | Audi |
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              Scenario: Verify Select Options Value
         | 
| 9 | 
            +
                When I login to home page
         | 
| 10 | 
            +
                Then Single select 'select_value' should be:
         | 
| 11 | 
            +
                  | 1 | 2 | 3 | 4 |
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              Scenario: Verify Select first selected option
         | 
| 14 | 
            +
                When I login to home page
         | 
| 15 | 
            +
                Then Single select 'first_selected_option' should be: Mercedes
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              Scenario: Verify Multi Selected Options
         | 
| 18 | 
            +
                When I login to home page
         | 
| 19 | 
            +
                And I select Volvo in multi select
         | 
| 20 | 
            +
                And I select Mercedes in multi select
         | 
| 21 | 
            +
                Then Multi select 'selected_options' should be:
         | 
| 22 | 
            +
                  | Volvo | Mercedes |
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              Scenario: Verify Single Selected Option
         | 
| 25 | 
            +
                When I login to home page
         | 
| 26 | 
            +
                And I select Audi in single select
         | 
| 27 | 
            +
                Then Single select 'selected_options' should be:
         | 
| 28 | 
            +
                  | Audi |
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            When /^Current browser should be (firefox|chrome)$/ do |browser|
         | 
| 3 | 
            +
              SeleniumPlus.driver.native.browser.should == browser.to_sym
         | 
| 4 | 
            +
            end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            When /^I execute script: (.+)$/ do |script|
         | 
| 7 | 
            +
              SeleniumPlus.driver.execute_script(script)
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            When /^I evaluate script: (.+)$/ do |script|
         | 
| 11 | 
            +
              @evaluate_value = SeleniumPlus.driver.evaluate_script(script)
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            Then /^Evaluate value should be: (.+)$/ do |value|
         | 
| 15 | 
            +
              @evaluate_value.should == value
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            Then /^I save a screenshot$/ do
         | 
| 19 | 
            +
              path = "#{File.dirname(__FILE__)}/../../screen_shots"
         | 
| 20 | 
            +
              Dir.mkdir(path) unless File.exists?(path)
         | 
| 21 | 
            +
              SeleniumPlus.driver.save_screenshot("#{path}/test_screenshot.png")
         | 
| 22 | 
            +
            end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            When /^I click show button/ do
         | 
| 25 | 
            +
              @site.home_page.show_btn.click
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            Then /^Active element value should be: (.+)$/ do |value|
         | 
| 29 | 
            +
              SeleniumPlus.driver.active_element[:value].should == value
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            When /^I select (.+) in (single|multi) select$/ do |value, type|
         | 
| 2 | 
            +
              case type
         | 
| 3 | 
            +
                when 'single'
         | 
| 4 | 
            +
                  @site.home_page.single_select.select(value)
         | 
| 5 | 
            +
                when 'multi'
         | 
| 6 | 
            +
                  @site.home_page.multi_select.select(value)
         | 
| 7 | 
            +
                else
         | 
| 8 | 
            +
                  # Skipped
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
            end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            Then /^Single select '(select_options|select_value)' should be:$/ do |type, table|
         | 
| 13 | 
            +
              case type
         | 
| 14 | 
            +
                when 'select_options'
         | 
| 15 | 
            +
                  @site.home_page.single_select.select_options.should == table.raw.first
         | 
| 16 | 
            +
                when 'select_value'
         | 
| 17 | 
            +
                  @site.home_page.single_select.select_values.should == table.raw.first
         | 
| 18 | 
            +
                else
         | 
| 19 | 
            +
                  # Skipped
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            Then /^Single select 'first_selected_option' should be: (.+)$/ do |option|
         | 
| 24 | 
            +
              @site.home_page.single_select.first_selected_option.should == option
         | 
| 25 | 
            +
            end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            Then /^(Single|Multi) select 'selected_options' should be:$/ do |type, table|
         | 
| 28 | 
            +
              case type
         | 
| 29 | 
            +
                when 'Single'
         | 
| 30 | 
            +
                  @site.home_page.single_select.selected_options.should == table.raw.first
         | 
| 31 | 
            +
                when 'Multi'
         | 
| 32 | 
            +
                  @site.home_page.multi_select.selected_options.should == table.raw.first
         | 
| 33 | 
            +
                else
         | 
| 34 | 
            +
                  # Skipped
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
            end
         | 
| @@ -3,8 +3,12 @@ When /^I show first table$/ do | |
| 3 3 | 
             
            end
         | 
| 4 4 |  | 
| 5 5 | 
             
            Then /^Horizontal table text should be:$/ do |h_table|
         | 
| 6 | 
            +
              # Match using headers and rows
         | 
| 6 7 | 
             
              @site.home_page.info_section.h_table.headers_text.should == h_table.headers
         | 
| 7 8 | 
             
              @site.home_page.info_section.h_table.rows_text.should == h_table.rows
         | 
| 9 | 
            +
              # Match using raw
         | 
| 10 | 
            +
              @site.home_page.info_section.h_table.table_raw_text.should == h_table.raw
         | 
| 11 | 
            +
             | 
| 8 12 | 
             
            end
         | 
| 9 13 |  | 
| 10 14 | 
             
            Then /^Horizontal table hashes should be:$/ do |h_table|
         | 
| @@ -18,3 +22,14 @@ Then /^Vertical table text should be:$/ do |h_table| | |
| 18 22 | 
             
              @site.home_page.info_section.v_table.rows_text.should == h_table.rows
         | 
| 19 23 | 
             
            end
         | 
| 20 24 |  | 
| 25 | 
            +
            Then /^Table without (headers|body) should be:$/ do |type, table|
         | 
| 26 | 
            +
              case type
         | 
| 27 | 
            +
                when 'headers'
         | 
| 28 | 
            +
                  @site.home_page.info_section.no_headers_table.headers_text.should == table.headers
         | 
| 29 | 
            +
                when 'body'
         | 
| 30 | 
            +
                  @site.home_page.info_section.no_body_table.rows_text.should == table.raw
         | 
| 31 | 
            +
                else
         | 
| 32 | 
            +
                  # Skipped
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| 35 | 
            +
             | 
    
        data/features/support/env.rb
    CHANGED
    
    
    
        data/features/tables.feature
    CHANGED
    
    | @@ -1,13 +1,15 @@ | |
| 1 1 | 
             
            Feature: Verify HTML Tables
         | 
| 2 2 |  | 
| 3 | 
            +
              Background:
         | 
| 4 | 
            +
                When I login to home page
         | 
| 5 | 
            +
             | 
| 3 6 | 
             
              # Actual Html table:
         | 
| 4 7 | 
             
              # | ID: | Name: | Company: |
         | 
| 5 8 | 
             
              # | 1   | Smith | VMware   |
         | 
| 6 9 | 
             
              # | 2   | James | EMC      |
         | 
| 7 10 | 
             
              #
         | 
| 8 11 | 
             
              Scenario: Verify HTML Table with horizontal header
         | 
| 9 | 
            -
                When I  | 
| 10 | 
            -
                And I show first table
         | 
| 12 | 
            +
                When I show first table
         | 
| 11 13 | 
             
                Then Horizontal table text should be:
         | 
| 12 14 | 
             
                  | ID: | Name: | Company: |
         | 
| 13 15 | 
             
                  | 1   | Smith | VMware   |
         | 
| @@ -19,7 +21,6 @@ Feature: Verify HTML Tables | |
| 19 21 | 
             
              # | Company:  | Eric | Microsoft |
         | 
| 20 22 | 
             
              #
         | 
| 21 23 | 
             
              Scenario: Verify HTML Table with vertical header
         | 
| 22 | 
            -
                When I login to home page
         | 
| 23 24 | 
             
                Then Vertical table text should be:
         | 
| 24 25 | 
             
                  | ID: | Name: | Company:  |
         | 
| 25 26 | 
             
                  | 1   | Alex  | Google    |
         | 
| @@ -31,8 +32,7 @@ Feature: Verify HTML Tables | |
| 31 32 | 
             
              # | 2   | James  | EMC       |
         | 
| 32 33 | 
             
              #
         | 
| 33 34 | 
             
              Scenario: Verify HTML Table using hashes
         | 
| 34 | 
            -
                When I  | 
| 35 | 
            -
                And I show first table
         | 
| 35 | 
            +
                When I show first table
         | 
| 36 36 | 
             
                Then Horizontal table hashes should be:
         | 
| 37 37 | 
             
                  | ID: | Name: |
         | 
| 38 38 | 
             
                  | 1   | Smith |
         | 
| @@ -51,3 +51,12 @@ Feature: Verify HTML Tables | |
| 51 51 | 
             
                And Horizontal table hashes should be:
         | 
| 52 52 | 
             
                  | Name: | Company: |
         | 
| 53 53 | 
             
                  | Smith | VMware   |
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              Scenario: Verify HTML Table without header
         | 
| 56 | 
            +
                Then Table without headers should be:
         | 
| 57 | 
            +
                  | ID: | Name: | Company: |
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              Scenario: Verify HTML Table without body
         | 
| 60 | 
            +
                Then Table without body should be:
         | 
| 61 | 
            +
                  | 1   | Smith | VMware   |
         | 
| 62 | 
            +
                  | 2   | James | EMC      |
         | 
    
        data/lib/selenium_plus.rb
    CHANGED
    
    | @@ -1,4 +1,12 @@ | |
| 1 1 | 
             
            $:.unshift(File.dirname(__FILE__))
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'simplecov'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            SimpleCov.start do
         | 
| 6 | 
            +
              add_group 'Libraries', 'lib'
         | 
| 7 | 
            +
              add_group 'Features', 'features'
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
             | 
| 2 10 | 
             
            require 'logger'
         | 
| 3 11 | 
             
            require 'selenium-webdriver'
         | 
| 4 12 | 
             
            require 'selenium_plus/version'
         | 
| @@ -10,8 +18,10 @@ require 'selenium_plus/page_obj/container' | |
| 10 18 | 
             
            require 'selenium_plus/page_obj/page'
         | 
| 11 19 | 
             
            require 'selenium_plus/page_obj/section'
         | 
| 12 20 | 
             
            require 'selenium_plus/selenium/table'
         | 
| 21 | 
            +
            require 'selenium_plus/selenium/select'
         | 
| 13 22 | 
             
            require 'selenium_plus/selenium/element'
         | 
| 14 23 |  | 
| 24 | 
            +
             | 
| 15 25 | 
             
            module SeleniumPlus
         | 
| 16 26 |  | 
| 17 27 | 
             
              class << self
         | 
| @@ -85,7 +95,6 @@ module SeleniumPlus | |
| 85 95 | 
             
                  end
         | 
| 86 96 | 
             
                end
         | 
| 87 97 | 
             
              end
         | 
| 88 | 
            -
             | 
| 89 98 | 
             
            end
         | 
| 90 99 |  | 
| 91 100 | 
             
            SeleniumPlus.configure do |config|
         | 
| @@ -103,4 +112,4 @@ end | |
| 103 112 |  | 
| 104 113 | 
             
            SeleniumPlus.register_driver :ie do
         | 
| 105 114 | 
             
              SeleniumPlus::Driver.new(:browser => :ie)
         | 
| 106 | 
            -
            end
         | 
| 115 | 
            +
            end
         | 
    
        data/lib/selenium_plus/driver.rb
    CHANGED
    
    | @@ -35,34 +35,6 @@ module SeleniumPlus | |
| 35 35 | 
             
                  native.get(url)
         | 
| 36 36 | 
             
                end
         | 
| 37 37 |  | 
| 38 | 
            -
                #def find(*args)
         | 
| 39 | 
            -
                #  if self.class.superclass == SeleniumPlus::Section
         | 
| 40 | 
            -
                #    @el =root_element.find_element(*args)
         | 
| 41 | 
            -
                #  else
         | 
| 42 | 
            -
                #    @el = native.find_element(*args)
         | 
| 43 | 
            -
                #  end
         | 
| 44 | 
            -
                #  highlight_element(@el) if SeleniumPlus.enable_highlight_element
         | 
| 45 | 
            -
                #  @el
         | 
| 46 | 
            -
                #end
         | 
| 47 | 
            -
                #
         | 
| 48 | 
            -
                #def all(*args)
         | 
| 49 | 
            -
                #  if self.class.superclass == SeleniumPlus::Section
         | 
| 50 | 
            -
                #    root_element.find_elements(*args)
         | 
| 51 | 
            -
                #  else
         | 
| 52 | 
            -
                #    native.find_elements(*args)
         | 
| 53 | 
            -
                #  end
         | 
| 54 | 
            -
                #end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                #def find(*args)
         | 
| 57 | 
            -
                #  el = native.find_element(*args)
         | 
| 58 | 
            -
                #  highlight_element(el) if SeleniumPlus.enable_highlight_element
         | 
| 59 | 
            -
                #  el
         | 
| 60 | 
            -
                #end
         | 
| 61 | 
            -
                #
         | 
| 62 | 
            -
                #def all(*args)
         | 
| 63 | 
            -
                #  native.find_elements(*args)
         | 
| 64 | 
            -
                #end
         | 
| 65 | 
            -
             | 
| 66 38 | 
             
                def active_element
         | 
| 67 39 | 
             
                  native.switch_to.active_element
         | 
| 68 40 | 
             
                end
         | 
| @@ -79,6 +51,10 @@ module SeleniumPlus | |
| 79 51 | 
             
                  native.execute_script("return #{script}")
         | 
| 80 52 | 
             
                end
         | 
| 81 53 |  | 
| 54 | 
            +
                def save_screenshot(path, options={})
         | 
| 55 | 
            +
                  native.save_screenshot(path)
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 82 58 | 
             
                def reset!
         | 
| 83 59 | 
             
                  # Use instance variable directly so we avoid starting the browser just to reset the session
         | 
| 84 60 | 
             
                  if @native
         | 
| @@ -1,8 +1,10 @@ | |
| 1 1 | 
             
            module SeleniumPlus
         | 
| 2 2 | 
             
              module Finders
         | 
| 3 3 | 
             
                def find(*args)
         | 
| 4 | 
            -
                  if self.class | 
| 5 | 
            -
                    @el = | 
| 4 | 
            +
                  if self.class == Selenium::WebDriver::Element
         | 
| 5 | 
            +
                    @el = self.find_element(*args)
         | 
| 6 | 
            +
                  elsif self.class.superclass == SeleniumPlus::Section
         | 
| 7 | 
            +
                    @el = root_element.find_element(*args)
         | 
| 6 8 | 
             
                  else
         | 
| 7 9 | 
             
                    @el = SeleniumPlus.driver.native.find_element(*args)
         | 
| 8 10 | 
             
                  end
         | 
| @@ -11,11 +13,25 @@ module SeleniumPlus | |
| 11 13 | 
             
                end
         | 
| 12 14 |  | 
| 13 15 | 
             
                def all(*args)
         | 
| 14 | 
            -
                  if self.class | 
| 16 | 
            +
                  if self.class == Selenium::WebDriver::Element
         | 
| 17 | 
            +
                    self.find_elements(*args)
         | 
| 18 | 
            +
                  elsif self.class.superclass == SeleniumPlus::Section
         | 
| 15 19 | 
             
                    root_element.find_elements(*args)
         | 
| 16 20 | 
             
                  else
         | 
| 17 21 | 
             
                    SeleniumPlus.driver.native.find_elements(*args)
         | 
| 18 22 | 
             
                  end
         | 
| 19 23 | 
             
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def not_find(*args)
         | 
| 26 | 
            +
                  begin
         | 
| 27 | 
            +
                    if self.class.superclass == SeleniumPlus::Section
         | 
| 28 | 
            +
                      root_element.find_element(*args)
         | 
| 29 | 
            +
                    else
         | 
| 30 | 
            +
                      SeleniumPlus.driver.native.find_element(*args)
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                  rescue Selenium::WebDriver::Error::NoSuchElementError
         | 
| 33 | 
            +
                    # Expected
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 20 36 | 
             
              end
         | 
| 21 37 | 
             
            end
         | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            # Public: Add extension method to Element class
         | 
| 2 2 | 
             
            #
         | 
| 3 3 | 
             
            class Selenium::WebDriver::Element
         | 
| 4 | 
            -
             # include SeleniumPlus::Finders
         | 
| 5 4 | 
             
              include SeleniumPlus::Elements::Table
         | 
| 5 | 
            +
              include SeleniumPlus::Elements::Select
         | 
| 6 6 |  | 
| 7 7 | 
             
              # Retrieve the given attribute
         | 
| 8 8 | 
             
              #
         | 
| @@ -22,10 +22,6 @@ class Selenium::WebDriver::Element | |
| 22 22 | 
             
                self.disaplyed?
         | 
| 23 23 | 
             
              end
         | 
| 24 24 |  | 
| 25 | 
            -
              def focused?
         | 
| 26 | 
            -
                self == SeleniumPlus.driver.active_element
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
             | 
| 29 25 | 
             
              # Set the value of the element to the given value.
         | 
| 30 26 | 
             
              #
         | 
| 31 27 | 
             
              # Examples:
         | 
| @@ -43,7 +39,7 @@ class Selenium::WebDriver::Element | |
| 43 39 | 
             
                if tag_name == 'input' and type == 'radio'
         | 
| 44 40 | 
             
                  click
         | 
| 45 41 | 
             
                elsif tag_name == 'input' and type == 'checkbox'
         | 
| 46 | 
            -
                  click if value ^ native.attribute('checked').to_s.eql?( | 
| 42 | 
            +
                  click if value ^ native.attribute('checked').to_s.eql?('true')
         | 
| 47 43 | 
             
                elsif tag_name == 'input' and type == 'file'
         | 
| 48 44 | 
             
                  path_names = value.to_s.empty? ? [] : value
         | 
| 49 45 | 
             
                  self.send_keys(*path_names)
         | 
| @@ -77,12 +73,4 @@ class Selenium::WebDriver::Element | |
| 77 73 | 
             
                old = self.text
         | 
| 78 74 | 
             
                self.set(old + text)
         | 
| 79 75 | 
             
              end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
              def find(*args)
         | 
| 82 | 
            -
                self.find_element(*args)
         | 
| 83 | 
            -
              end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
              def all(*args)
         | 
| 86 | 
            -
                self.find_elements(*args)
         | 
| 87 | 
            -
              end
         | 
| 88 76 | 
             
            end
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            module SeleniumPlus
         | 
| 2 | 
            +
              module Elements
         | 
| 3 | 
            +
                module Select
         | 
| 4 | 
            +
                  # Get all options for this select element
         | 
| 5 | 
            +
                  #
         | 
| 6 | 
            +
                  # @return [Array<Selenium::WebDriver::Element>]
         | 
| 7 | 
            +
                  def select_raw
         | 
| 8 | 
            +
                    if self.tag_name == 'select'
         | 
| 9 | 
            +
                      self.all(:css, 'option')
         | 
| 10 | 
            +
                    end
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def multiple?
         | 
| 14 | 
            +
                    self[:multiple]
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  # Select an option by it's text or value
         | 
| 18 | 
            +
                  #
         | 
| 19 | 
            +
                  # @param [String] value             The text or value of option
         | 
| 20 | 
            +
                  #
         | 
| 21 | 
            +
                  def select(value)
         | 
| 22 | 
            +
                    opt = select_raw.select{ |opt| opt[:value] == value || opt.text == value }
         | 
| 23 | 
            +
                    opt.first.send_keys(:control) if multiple?
         | 
| 24 | 
            +
                    opt.first.click unless opt.empty?
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  # Get all options text for this select element
         | 
| 28 | 
            +
                  #
         | 
| 29 | 
            +
                  # @return [Array<String>]
         | 
| 30 | 
            +
                  def select_options
         | 
| 31 | 
            +
                    select_raw.map{ |opt| opt.text}
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  # Get all option's values for this select element
         | 
| 35 | 
            +
                  #
         | 
| 36 | 
            +
                  # @return [Array<String>]
         | 
| 37 | 
            +
                  def select_values
         | 
| 38 | 
            +
                    select_raw.map{ |opt| opt[:value]}
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  # Get all selected options text for this select element
         | 
| 42 | 
            +
                  #
         | 
| 43 | 
            +
                  #
         | 
| 44 | 
            +
                  # @return [Array<String>]
         | 
| 45 | 
            +
                  def selected_options
         | 
| 46 | 
            +
                    select_raw.select { |e| e.selected? }.map{ |e| e.text}
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  # Get the first selected option in this select element
         | 
| 50 | 
            +
                  #
         | 
| 51 | 
            +
                  def first_selected_option
         | 
| 52 | 
            +
                    option = select_raw.find { |e| e.selected? }
         | 
| 53 | 
            +
                    option.text or raise 'no options are selected'
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
            end
         | 
| @@ -14,7 +14,7 @@ module SeleniumPlus | |
| 14 14 | 
             
                  #   #=> [[Element, Element],[Element, Element], [Element, Element]]
         | 
| 15 15 | 
             
                  #
         | 
| 16 16 | 
             
                  # @return [Array[Array<Selenium::WebDriver::Element>]]
         | 
| 17 | 
            -
                  def  | 
| 17 | 
            +
                  def table_raw
         | 
| 18 18 | 
             
                    self.all(:css, 'tr').map{ |row| row.all(:css, 'th,td')}
         | 
| 19 19 | 
             
                  end
         | 
| 20 20 |  | 
| @@ -29,20 +29,20 @@ module SeleniumPlus | |
| 29 29 | 
             
                  #   #=> [['id', 'name'],['1', 'alex'], ['2', 'smith']]
         | 
| 30 30 | 
             
                  #
         | 
| 31 31 | 
             
                  # @return [Array[Array<String>]]
         | 
| 32 | 
            -
                  def  | 
| 33 | 
            -
                     | 
| 32 | 
            +
                  def table_raw_text
         | 
| 33 | 
            +
                    table_raw.map{ |row| row.map{ |cell| cell.text.strip } }
         | 
| 34 34 | 
             
                  end
         | 
| 35 35 |  | 
| 36 36 | 
             
                  # Elements of table header
         | 
| 37 37 | 
             
                  #
         | 
| 38 38 | 
             
                  # @return [Array<Selenium::WebDriver::Element>]
         | 
| 39 39 | 
             
                  def headers
         | 
| 40 | 
            -
                    th_size =  | 
| 40 | 
            +
                    th_size = table_raw.first.select{ |cell| cell.tag_name == 'th'}.size
         | 
| 41 41 | 
             
                    case
         | 
| 42 42 | 
             
                      when th_size == 1 # vertical header
         | 
| 43 | 
            -
                         | 
| 43 | 
            +
                        table_raw.map { |cell| cell[0] }
         | 
| 44 44 | 
             
                      when th_size > 1 # horizontal header
         | 
| 45 | 
            -
                         | 
| 45 | 
            +
                        table_raw.first
         | 
| 46 46 | 
             
                      else
         | 
| 47 47 | 
             
                        nil # no th elements detected
         | 
| 48 48 | 
             
                    end
         | 
| @@ -52,14 +52,14 @@ module SeleniumPlus | |
| 52 52 | 
             
                  #
         | 
| 53 53 | 
             
                  # @return [Array[Array<Selenium::WebDriver::Element>]]
         | 
| 54 54 | 
             
                  def rows
         | 
| 55 | 
            -
                    th_size =  | 
| 55 | 
            +
                    th_size = table_raw.first.select{ |cell| cell.tag_name == 'th'}.size
         | 
| 56 56 | 
             
                    case
         | 
| 57 57 | 
             
                      when th_size == 1 # vertical header
         | 
| 58 | 
            -
                         | 
| 58 | 
            +
                        table_raw.map{ |row| row[1..-1] }.transpose
         | 
| 59 59 | 
             
                      when th_size > 1 # horizontal header
         | 
| 60 | 
            -
                         | 
| 61 | 
            -
                      else
         | 
| 62 | 
            -
                         | 
| 60 | 
            +
                        table_raw[1..-1]
         | 
| 61 | 
            +
                      else  # no header, raw is rows
         | 
| 62 | 
            +
                        table_raw
         | 
| 63 63 | 
             
                    end
         | 
| 64 64 | 
             
                  end
         | 
| 65 65 |  | 
    
        data/selenium_plus.gemspec
    CHANGED
    
    | @@ -10,7 +10,7 @@ Gem::Specification.new do |gem| | |
| 10 10 | 
             
              gem.email         = %w(shipuyao@gmail.com)
         | 
| 11 11 | 
             
              gem.description   = 'SeleniumPlus creates a very thin layer between Selenium and your applications, it gives your a simple and quick way to describe your web site using the Page Object Model.'
         | 
| 12 12 | 
             
              gem.summary       = ''
         | 
| 13 | 
            -
              gem.homepage      = ' | 
| 13 | 
            +
              gem.homepage      = ''
         | 
| 14 14 |  | 
| 15 15 | 
             
              gem.files         = `git ls-files`.split($/)
         | 
| 16 16 | 
             
              gem.executables   = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
         | 
| @@ -20,5 +20,6 @@ Gem::Specification.new do |gem| | |
| 20 20 | 
             
              gem.add_dependency('rake')
         | 
| 21 21 | 
             
              gem.add_dependency('selenium-webdriver', ['>= 2.25.0'])
         | 
| 22 22 | 
             
              gem.add_dependency('rspec', ['>= 2.1.0'])
         | 
| 23 | 
            +
              gem.add_dependency('simplecov', ['>= 0.7.1'])
         | 
| 23 24 | 
             
              gem.add_development_dependency('cucumber', ['>= 1.2.1'])
         | 
| 24 25 | 
             
            end
         | 
    
        data/test_site/html/home.html
    CHANGED
    
    | @@ -4,16 +4,22 @@ | |
| 4 4 | 
             
                <title></title>
         | 
| 5 5 | 
             
                <script type="text/javascript">
         | 
| 6 6 | 
             
                    function showFirstTable(id) {
         | 
| 7 | 
            -
                        document.getElementById(id).style.display =  | 
| 7 | 
            +
                        document.getElementById(id).style.display = "block";
         | 
| 8 8 | 
             
                    }
         | 
| 9 9 | 
             
                </script>
         | 
| 10 | 
            +
                <style type="text/css">
         | 
| 11 | 
            +
                    table, th, td
         | 
| 12 | 
            +
                    {
         | 
| 13 | 
            +
                        border: 1px solid black;
         | 
| 14 | 
            +
                    }
         | 
| 15 | 
            +
                </style>
         | 
| 10 16 | 
             
            </head>
         | 
| 11 17 | 
             
            <body>
         | 
| 12 | 
            -
                <div class= | 
| 13 | 
            -
                <input type= | 
| 14 | 
            -
                <div id= | 
| 15 | 
            -
                    <div class= | 
| 16 | 
            -
                    <table id="first" class= | 
| 18 | 
            +
                <div id="home_title" class="title">Test Home Page</div>
         | 
| 19 | 
            +
                <input type="submit" name="Show First Table" value="Show" onclick="showFirstTable("first")"/>
         | 
| 20 | 
            +
                <div id="info">
         | 
| 21 | 
            +
                    <div class="title">Information tables</div>
         | 
| 22 | 
            +
                    <table id="first" class="horizontal_headers" style="display: none">
         | 
| 17 23 | 
             
                        <tr>
         | 
| 18 24 | 
             
                            <th>ID:</th>
         | 
| 19 25 | 
             
                            <th>Name:</th>
         | 
| @@ -30,7 +36,7 @@ | |
| 30 36 | 
             
                            <td>EMC</td>
         | 
| 31 37 | 
             
                        </tr>
         | 
| 32 38 | 
             
                    </table>
         | 
| 33 | 
            -
                    <table class= | 
| 39 | 
            +
                    <table class="vertical_headers">
         | 
| 34 40 | 
             
                        <tr>
         | 
| 35 41 | 
             
                            <th>ID:</th>
         | 
| 36 42 | 
             
                            <td>1</td>
         | 
| @@ -47,6 +53,41 @@ | |
| 47 53 | 
             
                            <td>Microsoft</td>
         | 
| 48 54 | 
             
                        </tr>
         | 
| 49 55 | 
             
                    </table>
         | 
| 56 | 
            +
                    <div>Table with no header</div>
         | 
| 57 | 
            +
                    <table class="no_headers">
         | 
| 58 | 
            +
                        <tr>
         | 
| 59 | 
            +
                            <th>ID:</th>
         | 
| 60 | 
            +
                            <th>Name:</th>
         | 
| 61 | 
            +
                            <th>Company:</th>
         | 
| 62 | 
            +
                        </tr>
         | 
| 63 | 
            +
                    </table>
         | 
| 64 | 
            +
                    <div>Table with no body</div>
         | 
| 65 | 
            +
                    <table class="no_body">
         | 
| 66 | 
            +
                        <tr>
         | 
| 67 | 
            +
                            <td>1</td>
         | 
| 68 | 
            +
                            <td>Smith</td>
         | 
| 69 | 
            +
                            <td>VMware</td>
         | 
| 70 | 
            +
                        </tr>
         | 
| 71 | 
            +
                        <tr>
         | 
| 72 | 
            +
                            <td>2</td>
         | 
| 73 | 
            +
                            <td>James</td>
         | 
| 74 | 
            +
                            <td>EMC</td>
         | 
| 75 | 
            +
                        </tr>
         | 
| 76 | 
            +
                    </table>
         | 
| 50 77 | 
             
                </div>
         | 
| 78 | 
            +
                <div>Select</div>
         | 
| 79 | 
            +
                <select id="single_select">
         | 
| 80 | 
            +
                    <option value="1">Volvo</option>
         | 
| 81 | 
            +
                    <option value="2">Saab</option>
         | 
| 82 | 
            +
                    <option selected="select" value="3">Mercedes</option>
         | 
| 83 | 
            +
                    <option value="4">Audi</option>
         | 
| 84 | 
            +
                </select>
         | 
| 85 | 
            +
                <select multiple id="multi_select">
         | 
| 86 | 
            +
                    <option value="volvo">Volvo</option>
         | 
| 87 | 
            +
                    <option value="saab">Saab</option>
         | 
| 88 | 
            +
                    <option value="opel">Mercedes</option>
         | 
| 89 | 
            +
                    <option value="audi">Audi</option>
         | 
| 90 | 
            +
                </select>
         | 
| 91 | 
            +
             | 
| 51 92 | 
             
            </body>
         | 
| 52 93 | 
             
            </html>
         | 
| @@ -4,8 +4,9 @@ module Test | |
| 4 4 | 
             
                section(:info_section, InfoSection, :id, 'info')
         | 
| 5 5 |  | 
| 6 6 | 
             
                element(:show_btn, :css, 'input[value=Show]')
         | 
| 7 | 
            -
             | 
| 8 7 | 
             
                element(:title_div, :css, 'div.title')
         | 
| 8 | 
            +
                element(:single_select, :id, 'single_select')
         | 
| 9 | 
            +
                element(:multi_select, :id, 'multi_select')
         | 
| 9 10 | 
             
                elements(:title_divs, :css, 'div.title')
         | 
| 10 11 |  | 
| 11 12 | 
             
                def show_first_table
         | 
| @@ -4,6 +4,8 @@ module Test | |
| 4 4 |  | 
| 5 5 | 
             
                element(:h_table, :css, 'table.horizontal_headers')
         | 
| 6 6 | 
             
                element(:v_table, :css, 'table.vertical_headers')
         | 
| 7 | 
            +
                element(:no_headers_table, :css, 'table.no_headers')
         | 
| 8 | 
            +
                element(:no_body_table, :css, 'table.no_body')
         | 
| 7 9 | 
             
                element(:title_div, :css, 'div.title')
         | 
| 8 10 |  | 
| 9 11 | 
             
                def title
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: selenium_plus
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.5
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,11 +9,11 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2013-03- | 
| 12 | 
            +
            date: 2013-03-08 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: rake
         | 
| 16 | 
            -
              requirement: & | 
| 16 | 
            +
              requirement: &70261806662480 !ruby/object:Gem::Requirement
         | 
| 17 17 | 
             
                none: false
         | 
| 18 18 | 
             
                requirements:
         | 
| 19 19 | 
             
                - - ! '>='
         | 
| @@ -21,10 +21,10 @@ dependencies: | |
| 21 21 | 
             
                    version: '0'
         | 
| 22 22 | 
             
              type: :runtime
         | 
| 23 23 | 
             
              prerelease: false
         | 
| 24 | 
            -
              version_requirements: * | 
| 24 | 
            +
              version_requirements: *70261806662480
         | 
| 25 25 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 26 26 | 
             
              name: selenium-webdriver
         | 
| 27 | 
            -
              requirement: & | 
| 27 | 
            +
              requirement: &70261806661200 !ruby/object:Gem::Requirement
         | 
| 28 28 | 
             
                none: false
         | 
| 29 29 | 
             
                requirements:
         | 
| 30 30 | 
             
                - - ! '>='
         | 
| @@ -32,10 +32,10 @@ dependencies: | |
| 32 32 | 
             
                    version: 2.25.0
         | 
| 33 33 | 
             
              type: :runtime
         | 
| 34 34 | 
             
              prerelease: false
         | 
| 35 | 
            -
              version_requirements: * | 
| 35 | 
            +
              version_requirements: *70261806661200
         | 
| 36 36 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 37 37 | 
             
              name: rspec
         | 
| 38 | 
            -
              requirement: & | 
| 38 | 
            +
              requirement: &70261806660280 !ruby/object:Gem::Requirement
         | 
| 39 39 | 
             
                none: false
         | 
| 40 40 | 
             
                requirements:
         | 
| 41 41 | 
             
                - - ! '>='
         | 
| @@ -43,10 +43,21 @@ dependencies: | |
| 43 43 | 
             
                    version: 2.1.0
         | 
| 44 44 | 
             
              type: :runtime
         | 
| 45 45 | 
             
              prerelease: false
         | 
| 46 | 
            -
              version_requirements: * | 
| 46 | 
            +
              version_requirements: *70261806660280
         | 
| 47 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 48 | 
            +
              name: simplecov
         | 
| 49 | 
            +
              requirement: &70261806659300 !ruby/object:Gem::Requirement
         | 
| 50 | 
            +
                none: false
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - ! '>='
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: 0.7.1
         | 
| 55 | 
            +
              type: :runtime
         | 
| 56 | 
            +
              prerelease: false
         | 
| 57 | 
            +
              version_requirements: *70261806659300
         | 
| 47 58 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 59 | 
             
              name: cucumber
         | 
| 49 | 
            -
              requirement: & | 
| 60 | 
            +
              requirement: &70261806658320 !ruby/object:Gem::Requirement
         | 
| 50 61 | 
             
                none: false
         | 
| 51 62 | 
             
                requirements:
         | 
| 52 63 | 
             
                - - ! '>='
         | 
| @@ -54,7 +65,7 @@ dependencies: | |
| 54 65 | 
             
                    version: 1.2.1
         | 
| 55 66 | 
             
              type: :development
         | 
| 56 67 | 
             
              prerelease: false
         | 
| 57 | 
            -
              version_requirements: * | 
| 68 | 
            +
              version_requirements: *70261806658320
         | 
| 58 69 | 
             
            description: SeleniumPlus creates a very thin layer between Selenium and your applications,
         | 
| 59 70 | 
             
              it gives your a simple and quick way to describe your web site using the Page Object
         | 
| 60 71 | 
             
              Model.
         | 
| @@ -71,8 +82,11 @@ files: | |
| 71 82 | 
             
            - Rakefile
         | 
| 72 83 | 
             
            - features/drivers.feature
         | 
| 73 84 | 
             
            - features/finders.feature
         | 
| 85 | 
            +
            - features/select.feature
         | 
| 86 | 
            +
            - features/step_definitions/drivers_steps.rb
         | 
| 74 87 | 
             
            - features/step_definitions/finder_steps.rb
         | 
| 75 88 | 
             
            - features/step_definitions/general_steps.rb
         | 
| 89 | 
            +
            - features/step_definitions/select_steps.rb
         | 
| 76 90 | 
             
            - features/step_definitions/tables_steps.rb
         | 
| 77 91 | 
             
            - features/support/env.rb
         | 
| 78 92 | 
             
            - features/support/hooks.rb
         | 
| @@ -86,6 +100,7 @@ files: | |
| 86 100 | 
             
            - lib/selenium_plus/page_obj/page.rb
         | 
| 87 101 | 
             
            - lib/selenium_plus/page_obj/section.rb
         | 
| 88 102 | 
             
            - lib/selenium_plus/selenium/element.rb
         | 
| 103 | 
            +
            - lib/selenium_plus/selenium/select.rb
         | 
| 89 104 | 
             
            - lib/selenium_plus/selenium/table.rb
         | 
| 90 105 | 
             
            - lib/selenium_plus/version.rb
         | 
| 91 106 | 
             
            - selenium_plus.gemspec
         | 
| @@ -96,7 +111,7 @@ files: | |
| 96 111 | 
             
            - test_site/sections/info_section.rb
         | 
| 97 112 | 
             
            - test_site/test_project.rb
         | 
| 98 113 | 
             
            - test_site/test_site.rb
         | 
| 99 | 
            -
            homepage:  | 
| 114 | 
            +
            homepage: ''
         | 
| 100 115 | 
             
            licenses: []
         | 
| 101 116 | 
             
            post_install_message: 
         | 
| 102 117 | 
             
            rdoc_options: []
         | 
| @@ -123,8 +138,11 @@ summary: '' | |
| 123 138 | 
             
            test_files:
         | 
| 124 139 | 
             
            - features/drivers.feature
         | 
| 125 140 | 
             
            - features/finders.feature
         | 
| 141 | 
            +
            - features/select.feature
         | 
| 142 | 
            +
            - features/step_definitions/drivers_steps.rb
         | 
| 126 143 | 
             
            - features/step_definitions/finder_steps.rb
         | 
| 127 144 | 
             
            - features/step_definitions/general_steps.rb
         | 
| 145 | 
            +
            - features/step_definitions/select_steps.rb
         | 
| 128 146 | 
             
            - features/step_definitions/tables_steps.rb
         | 
| 129 147 | 
             
            - features/support/env.rb
         | 
| 130 148 | 
             
            - features/support/hooks.rb
         |