selenium_plus 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +54 -15
- data/features/drivers.feature +11 -0
- data/features/step_definitions/general_steps.rb +10 -0
- data/features/step_definitions/tables_steps.rb +19 -0
- data/features/support/env.rb +13 -0
- data/features/support/hooks.rb +20 -0
- data/features/tables.feature +53 -0
- data/lib/selenium_plus/driver.rb +28 -19
- data/lib/selenium_plus/{exception.rb → exceptions.rb} +0 -0
- data/lib/selenium_plus/page_obj/container.rb +4 -6
- data/lib/selenium_plus/page_obj/page.rb +8 -5
- data/lib/selenium_plus/page_obj/section.rb +2 -3
- data/lib/selenium_plus/selenium/element.rb +15 -0
- data/lib/selenium_plus/selenium/table.rb +62 -2
- data/lib/selenium_plus/version.rb +2 -2
- data/lib/selenium_plus.rb +22 -20
- data/test_site/html/home.html +50 -0
- data/test_site/html/login.html +25 -0
- data/test_site/pages/home_page.rb +12 -0
- data/test_site/pages/login_page.rb +15 -0
- data/test_site/sections/info_section.rb +9 -0
- data/test_site/test_project.rb +12 -0
- data/test_site/test_site.rb +19 -0
- metadata +40 -39
- checksums.yaml +0 -15
- data/lib/selenium_plus/page_obj/site.rb +0 -9
- data/test_project/features/search.feature +0 -0
- data/test_project/features/step_definitions/search_steps.rb +0 -0
- data/test_project/test_project.rb +0 -26
- data/test_project/test_site/html/home.html +0 -46
- data/test_project/test_site/pages/home_page.rb +0 -18
- data/test_project/test_site/sections/info_section.rb +0 -13
- data/test_project/test_site/test_site.rb +0 -13
data/README.md
CHANGED
@@ -1,29 +1,68 @@
|
|
1
1
|
# SeleniumPlus
|
2
2
|
|
3
|
-
|
3
|
+
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.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
7
|
+
$ gem install selenium_plus
|
8
8
|
|
9
|
-
|
9
|
+
## Key benefits
|
10
10
|
|
11
|
-
|
11
|
+
- Quickly build Page Objects
|
12
|
+
- Includes new element class e.g. Table
|
12
13
|
|
13
|
-
|
14
|
+
## Usage
|
14
15
|
|
15
|
-
|
16
|
+
Using page object model and page factory
|
16
17
|
|
17
|
-
|
18
|
+
```ruby
|
18
19
|
|
19
|
-
|
20
|
+
# define page
|
21
|
+
class LoginPage < SeleniumPlus::Page
|
22
|
+
element(:username_input, :id, 'username')
|
23
|
+
element(:password_input, :id, 'password')
|
24
|
+
element(:submit_btn, :css, 'input[name=commit]')
|
25
|
+
|
26
|
+
def login
|
27
|
+
username_input.type('Spark')
|
28
|
+
password_input.type('12345')
|
29
|
+
submit_btn.click
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# define your site
|
34
|
+
require 'pages/home_page'
|
35
|
+
|
36
|
+
class TestSite
|
37
|
+
|
38
|
+
def home_page
|
39
|
+
Test::HomePage.new
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
SeleniumPlus.register_driver :chrome_driver do
|
45
|
+
SeleniumPlus::Driver.new(:browser => :chrome)
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
SeleniumPlus.using_driver(:chrome_driver)
|
50
|
+
|
51
|
+
# start some test
|
52
|
+
@Test = TestSite.new
|
53
|
+
@Test.home_page.goto('/test_site/html/home.html')
|
54
|
+
@Test.home_page.show_first_table
|
55
|
+
@Test.home_page.info_section.h_table.rows_text.should == h_table.rows
|
56
|
+
|
57
|
+
```
|
20
58
|
|
21
|
-
|
59
|
+
Without using page object model
|
22
60
|
|
23
|
-
|
61
|
+
```ruby
|
62
|
+
# Use default firefox driver, skipping driver registration
|
63
|
+
driver = SeleniumPlus.using_driver(:chrome_driver)
|
64
|
+
driver.goto('http://www.google.com.hk')
|
65
|
+
driver.find(:id,'lst-ib').type('Mozy')
|
66
|
+
driver.find(:css,'input[name=btnK]').click
|
24
67
|
|
25
|
-
|
26
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
68
|
+
```
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: Verify drivers
|
2
|
+
|
3
|
+
@firefox
|
4
|
+
Scenario: Verify using @firefox tag calls firefox driver
|
5
|
+
When I login to home page
|
6
|
+
Then Current browser should be firefox
|
7
|
+
|
8
|
+
@chrome
|
9
|
+
Scenario: navigate using @chrome tag calls chrome driver
|
10
|
+
When I login to home page
|
11
|
+
Then Current browser should be chrome
|
@@ -0,0 +1,10 @@
|
|
1
|
+
|
2
|
+
When /^I login to home page$/ do
|
3
|
+
@site = TestSite.new
|
4
|
+
@site.login_page.goto('file:///'+File.dirname(__FILE__)+'../../../test_site/html/login.html')
|
5
|
+
@site.login_page.login
|
6
|
+
end
|
7
|
+
|
8
|
+
When /^Current browser should be (firefox|chrome)$/ do |browser|
|
9
|
+
SeleniumPlus.driver.native.browser.should == browser.to_sym
|
10
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
When /^I show first table$/ do
|
2
|
+
@site.home_page.show_first_table
|
3
|
+
end
|
4
|
+
Then /^Horizontal table text should be:$/ do |h_table|
|
5
|
+
@site.home_page.info_section.h_table.headers_text.should == h_table.headers
|
6
|
+
@site.home_page.info_section.h_table.rows_text.should == h_table.rows
|
7
|
+
end
|
8
|
+
|
9
|
+
Then /^Horizontal table hashes should be:$/ do |h_table|
|
10
|
+
actual = @site.home_page.info_section.h_table.hashes
|
11
|
+
expected = h_table.hashes
|
12
|
+
expected.each_index{ |index| expected[index].keys.each{ |key| actual[index][key].should == expected[index][key]} }
|
13
|
+
end
|
14
|
+
|
15
|
+
Then /^Vertical table text should be:$/ do |h_table|
|
16
|
+
@site.home_page.info_section.v_table.headers_text.should == h_table.headers
|
17
|
+
@site.home_page.info_section.v_table.rows_text.should == h_table.rows
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../../test_site')
|
2
|
+
|
3
|
+
require 'test_site'
|
4
|
+
|
5
|
+
SeleniumPlus.register_driver :firefox_driver do
|
6
|
+
SeleniumPlus::Driver.new(:browser => :firefox)
|
7
|
+
end
|
8
|
+
|
9
|
+
SeleniumPlus.register_driver :chrome_driver do
|
10
|
+
SeleniumPlus::Driver.new(:browser => :chrome)
|
11
|
+
end
|
12
|
+
|
13
|
+
SeleniumPlus.using_driver(:firefox_driver)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Before do |scenario|
|
2
|
+
# Do things before each scenario.
|
3
|
+
end
|
4
|
+
|
5
|
+
After do |scenario|
|
6
|
+
SeleniumPlus.driver.reset!
|
7
|
+
end
|
8
|
+
|
9
|
+
AfterStep do
|
10
|
+
# Do things after each step.
|
11
|
+
end
|
12
|
+
|
13
|
+
# Setup driver using tags
|
14
|
+
Before('@chrome') do
|
15
|
+
SeleniumPlus.using_driver(:chrome_driver)
|
16
|
+
end
|
17
|
+
|
18
|
+
Before('@firefox') do
|
19
|
+
SeleniumPlus.using_driver(:firefox_driver)
|
20
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Feature: Verify HTML Tables
|
2
|
+
|
3
|
+
# Actual Html table:
|
4
|
+
# | ID: | Name: | Company: |
|
5
|
+
# | 1 | Smith | VMware |
|
6
|
+
# | 2 | James | EMC |
|
7
|
+
#
|
8
|
+
Scenario: Verify HTML Table with horizontal header
|
9
|
+
When I login to home page
|
10
|
+
And I show first table
|
11
|
+
Then Horizontal table text should be:
|
12
|
+
| ID: | Name: | Company: |
|
13
|
+
| 1 | Smith | VMware |
|
14
|
+
| 2 | James | EMC |
|
15
|
+
|
16
|
+
# Actual Html table:
|
17
|
+
# | ID: | 1 | 2 |
|
18
|
+
# | Name: | Alex | Google |
|
19
|
+
# | Company: | Eric | Microsoft |
|
20
|
+
#
|
21
|
+
Scenario: Verify HTML Table with vertical header
|
22
|
+
When I login to home page
|
23
|
+
Then Vertical table text should be:
|
24
|
+
| ID: | Name: | Company: |
|
25
|
+
| 1 | Alex | Google |
|
26
|
+
| 2 | Eric | Microsoft |
|
27
|
+
|
28
|
+
# Actual Html table:
|
29
|
+
# | ID: | Name: | Company: |
|
30
|
+
# | 1 | Smith | VMware |
|
31
|
+
# | 2 | James | EMC |
|
32
|
+
#
|
33
|
+
Scenario: Verify HTML Table using hashes
|
34
|
+
When I login to home page
|
35
|
+
And I show first table
|
36
|
+
Then Horizontal table hashes should be:
|
37
|
+
| ID: | Name: |
|
38
|
+
| 1 | Smith |
|
39
|
+
| 2 | James |
|
40
|
+
And Horizontal table hashes should be:
|
41
|
+
| ID: | Company: |
|
42
|
+
| 1 | VMware |
|
43
|
+
| 2 | EMC |
|
44
|
+
And Horizontal table hashes should be:
|
45
|
+
| Name: | Company: |
|
46
|
+
| Smith | VMware |
|
47
|
+
| James | EMC |
|
48
|
+
And Horizontal table hashes should be:
|
49
|
+
| ID: | Name: | Company: |
|
50
|
+
| 1 | Smith | VMware |
|
51
|
+
And Horizontal table hashes should be:
|
52
|
+
| Name: | Company: |
|
53
|
+
| Smith | VMware |
|
data/lib/selenium_plus/driver.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
module SeleniumPlus
|
2
|
+
|
2
3
|
class Driver
|
3
4
|
|
4
5
|
DEFAULT_OPTIONS = { :browser => :firefox }
|
5
6
|
|
6
|
-
attr_reader :
|
7
|
+
attr_reader :native, :options
|
7
8
|
|
8
9
|
def initialize(options={})
|
9
|
-
@
|
10
|
+
@native = nil
|
10
11
|
@exit_status = nil
|
11
12
|
@options = DEFAULT_OPTIONS.merge(options)
|
12
13
|
end
|
13
14
|
|
14
|
-
def
|
15
|
-
unless @
|
16
|
-
@
|
15
|
+
def native
|
16
|
+
unless @native
|
17
|
+
@native = Selenium::WebDriver.for(options[:browser])
|
18
|
+
@native.manage.timeouts.implicit_wait = SeleniumPlus.default_wait_time
|
17
19
|
main = Process.pid
|
18
20
|
at_exit do
|
19
21
|
# Store the exit status of the test run since it goes away after calling the at_exit proc...
|
@@ -22,50 +24,57 @@ module SeleniumPlus
|
|
22
24
|
exit @exit_status if @exit_status # Force exit with stored status
|
23
25
|
end
|
24
26
|
end
|
25
|
-
@
|
27
|
+
@native
|
26
28
|
end
|
27
29
|
|
28
30
|
def visit(url)
|
29
|
-
|
31
|
+
native.get(url)
|
30
32
|
end
|
31
33
|
|
32
34
|
def find(*args)
|
33
|
-
|
35
|
+
native.find_element(*args)
|
36
|
+
#highlight_element(el) if enable_highlight_element
|
37
|
+
#el
|
34
38
|
end
|
35
39
|
|
36
40
|
def all(*args)
|
37
|
-
|
41
|
+
native.find_elements(*args)
|
38
42
|
end
|
39
43
|
|
40
|
-
def
|
41
|
-
|
44
|
+
def active_element
|
45
|
+
native.switch_to.active_element
|
42
46
|
end
|
43
47
|
|
44
|
-
def
|
45
|
-
|
48
|
+
def highlight_element(element)
|
49
|
+
native.execute_script("arguments[0].setAttribute('style', 'border: 2px solid red;')", element)
|
50
|
+
end
|
51
|
+
|
52
|
+
def execute_script(script)
|
53
|
+
native.execute_script(script)
|
46
54
|
end
|
47
55
|
|
48
|
-
def
|
49
|
-
|
56
|
+
def evaluate_script(script)
|
57
|
+
native.execute_script("return #{script}")
|
50
58
|
end
|
51
59
|
|
52
60
|
def reset!
|
53
61
|
# Use instance variable directly so we avoid starting the browser just to reset the session
|
54
|
-
if @
|
55
|
-
begin @
|
62
|
+
if @native
|
63
|
+
begin @native.manage.delete_all_cookies
|
56
64
|
rescue Selenium::WebDriver::Error::UnhandledError
|
57
65
|
# delete_all_cookies fails when we've previously gone
|
58
66
|
# to about:blank, so we rescue this error and do nothing
|
59
67
|
# instead.
|
60
68
|
end
|
61
|
-
@
|
69
|
+
@native.navigate.to('about:blank')
|
62
70
|
end
|
63
71
|
end
|
64
72
|
|
65
73
|
def quit
|
66
|
-
@
|
74
|
+
@native.quit
|
67
75
|
rescue Errno::ECONNREFUSED
|
68
76
|
# Browser must have already gone
|
69
77
|
end
|
78
|
+
|
70
79
|
end
|
71
80
|
end
|
File without changes
|
@@ -15,10 +15,9 @@ module SeleniumPlus
|
|
15
15
|
# @return [Selenium::WebDriver::Element]
|
16
16
|
def element(name, *find_args)
|
17
17
|
define_method(name) do
|
18
|
-
|
18
|
+
find(*find_args)
|
19
19
|
end
|
20
20
|
add_existence_checker(name, *find_args)
|
21
|
-
private name
|
22
21
|
end
|
23
22
|
|
24
23
|
# Define a new method with the name of the symbol and return elements
|
@@ -34,9 +33,8 @@ module SeleniumPlus
|
|
34
33
|
# @return [Array<Selenium::WebDriver::Element>]
|
35
34
|
def elements(name, *find_args)
|
36
35
|
define_method(name) do
|
37
|
-
|
36
|
+
all(*find_args)
|
38
37
|
end
|
39
|
-
private name
|
40
38
|
end
|
41
39
|
|
42
40
|
# Define partial section of the page
|
@@ -52,7 +50,7 @@ module SeleniumPlus
|
|
52
50
|
# @return [SeleniumPlus::Section]
|
53
51
|
def section(name, section_class, *find_args)
|
54
52
|
define_method(name) do
|
55
|
-
section_class.new(
|
53
|
+
section_class.new(find(*find_args))
|
56
54
|
end
|
57
55
|
end
|
58
56
|
|
@@ -75,7 +73,7 @@ module SeleniumPlus
|
|
75
73
|
# @return [Boolean]
|
76
74
|
def add_existence_checker(name, *find_args)
|
77
75
|
define_method("has_#{name.to_s}?") do
|
78
|
-
|
76
|
+
all(*find_args).size > 0
|
79
77
|
end
|
80
78
|
end
|
81
79
|
end
|
@@ -2,14 +2,17 @@ module SeleniumPlus
|
|
2
2
|
class Page
|
3
3
|
extend Container
|
4
4
|
|
5
|
-
|
5
|
+
def goto(url)
|
6
|
+
SeleniumPlus.driver.visit(url)
|
7
|
+
end
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
private
|
10
|
+
def find(*args)
|
11
|
+
SeleniumPlus.driver.find(*args)
|
9
12
|
end
|
10
13
|
|
11
|
-
def
|
12
|
-
driver.
|
14
|
+
def all(*args)
|
15
|
+
SeleniumPlus.driver.all(*args)
|
13
16
|
end
|
14
17
|
end
|
15
18
|
end
|
@@ -17,6 +17,14 @@ class Selenium::WebDriver::Element
|
|
17
17
|
nil
|
18
18
|
end
|
19
19
|
|
20
|
+
def visible?
|
21
|
+
self.disaplyed?
|
22
|
+
end
|
23
|
+
|
24
|
+
def focused?
|
25
|
+
self == SeleniumPlus.driver.active_element
|
26
|
+
end
|
27
|
+
|
20
28
|
# Set the value of the element to the given value.
|
21
29
|
#
|
22
30
|
# Examples:
|
@@ -69,4 +77,11 @@ class Selenium::WebDriver::Element
|
|
69
77
|
self.set(old + text)
|
70
78
|
end
|
71
79
|
|
80
|
+
def find(*args)
|
81
|
+
self.find_element(*args)
|
82
|
+
end
|
83
|
+
|
84
|
+
def all(*args)
|
85
|
+
self.find_elements(*args)
|
86
|
+
end
|
72
87
|
end
|
@@ -1,10 +1,70 @@
|
|
1
1
|
module SeleniumPlus
|
2
2
|
module Elements
|
3
3
|
module Table
|
4
|
+
# Raw elements of table
|
5
|
+
#
|
6
|
+
# @return [Array[Array<Selenium::WebDriver::Element>]]
|
4
7
|
def raw
|
5
|
-
|
8
|
+
self.all(:css, 'tr').map{ |row| row.all(:css, 'th,td')}
|
9
|
+
end
|
10
|
+
|
11
|
+
# Raw text of table
|
12
|
+
#
|
13
|
+
# @return [Array[Array<String>]]
|
14
|
+
def raw_text
|
15
|
+
raw.map{ |row| row.map{ |cell| cell.text.strip } }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Elements of table header
|
19
|
+
#
|
20
|
+
# @return [Array<Selenium::WebDriver::Element>]
|
21
|
+
def headers
|
22
|
+
th_size = raw.first.select{ |cell| cell.tag_name == 'th'}.size
|
23
|
+
case
|
24
|
+
when th_size == 1 # vertical header
|
25
|
+
raw.map { |cell| cell[0] }
|
26
|
+
when th_size > 1 # horizontal header
|
27
|
+
raw.first
|
28
|
+
else
|
29
|
+
nil # no th elements detected
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Elements of table rows
|
34
|
+
#
|
35
|
+
# @return [Array[Array<Selenium::WebDriver::Element>]]
|
36
|
+
def rows
|
37
|
+
th_size = raw.first.select{ |cell| cell.tag_name == 'th'}.size
|
38
|
+
case
|
39
|
+
when th_size == 1 # vertical header
|
40
|
+
raw.map{ |row| row[1..-1] }.transpose
|
41
|
+
when th_size > 1 # horizontal header
|
42
|
+
raw[1..-1]
|
43
|
+
else
|
44
|
+
nil # no th elements detected
|
45
|
+
end
|
6
46
|
end
|
7
|
-
end
|
8
47
|
|
48
|
+
# Text of table header
|
49
|
+
#
|
50
|
+
# @return [Array<String>]
|
51
|
+
def headers_text
|
52
|
+
headers.map { |cell| cell.text.strip }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Text of table rows
|
56
|
+
#
|
57
|
+
# @return [Array[Array<String>]]
|
58
|
+
def rows_text
|
59
|
+
rows.map { |row| row.map { |cell| cell.text.strip } }
|
60
|
+
end
|
61
|
+
|
62
|
+
# Array of Hash where the keys of each Hash are the headers in the table
|
63
|
+
#
|
64
|
+
# @return [Array<Hash>]
|
65
|
+
def hashes
|
66
|
+
rows_text.map{ |row| Hash[*headers_text.zip(row).flatten] }
|
67
|
+
end
|
68
|
+
end
|
9
69
|
end
|
10
70
|
end
|
@@ -1,3 +1,3 @@
|
|
1
1
|
module SeleniumPlus
|
2
|
-
VERSION = '0.0.
|
3
|
-
end
|
2
|
+
VERSION = '0.0.3'
|
3
|
+
end
|
data/lib/selenium_plus.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
require 'logger'
|
1
3
|
require 'selenium-webdriver'
|
2
4
|
require 'selenium_plus/version'
|
3
|
-
require 'selenium_plus/
|
5
|
+
require 'selenium_plus/exceptions'
|
4
6
|
require 'selenium_plus/driver'
|
5
7
|
require 'selenium_plus/page_obj/container'
|
6
|
-
require 'selenium_plus/page_obj/site'
|
7
8
|
require 'selenium_plus/page_obj/page'
|
8
9
|
require 'selenium_plus/page_obj/section'
|
9
10
|
require 'selenium_plus/selenium/table'
|
@@ -12,7 +13,8 @@ require 'selenium_plus/selenium/element'
|
|
12
13
|
module SeleniumPlus
|
13
14
|
|
14
15
|
class << self
|
15
|
-
|
16
|
+
|
17
|
+
attr_accessor :driver, :default_driver, :current_driver, :default_wait_time, :enable_highlight_element
|
16
18
|
|
17
19
|
# Configure SeleniumPlus
|
18
20
|
#
|
@@ -23,7 +25,7 @@ module SeleniumPlus
|
|
23
25
|
# end
|
24
26
|
#
|
25
27
|
# [default_wait_time = Integer]
|
26
|
-
# [
|
28
|
+
# [enable_highlight_element = Boolean]
|
27
29
|
#
|
28
30
|
def configure
|
29
31
|
yield self
|
@@ -44,41 +46,41 @@ module SeleniumPlus
|
|
44
46
|
drivers[name] = block
|
45
47
|
end
|
46
48
|
|
49
|
+
# All register drivers
|
50
|
+
#
|
51
|
+
# @return [Array]
|
47
52
|
def drivers
|
48
53
|
@drivers ||= {}
|
49
54
|
end
|
50
55
|
|
51
|
-
#
|
56
|
+
# The name of default driver
|
57
|
+
#
|
58
|
+
# @return [Symbol]
|
52
59
|
def default_driver
|
53
60
|
@default_driver || :firefox_driver
|
54
61
|
end
|
55
62
|
|
56
|
-
#
|
63
|
+
# The name of the driver currently in use
|
64
|
+
#
|
65
|
+
# @return [Symbol]
|
57
66
|
def current_driver
|
58
67
|
@current_driver || default_driver
|
59
68
|
end
|
60
69
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
#
|
66
|
-
# @return [SeleniumPlus::Driver] A SeleniumPlus driver instance
|
67
|
-
def using_driver
|
68
|
-
@driver ||= begin
|
69
|
-
unless drivers.has_key?(@current_driver)
|
70
|
-
other_drivers = drivers.keys.map { |key| key.inspect }
|
71
|
-
raise SeleniumPlus::Exceptions::DriverNotFoundError, "Driver #{@current_driver} was not found. Available types: #{other_drivers.join(', ')}"
|
72
|
-
end
|
73
|
-
drivers[@current_driver].call
|
70
|
+
def using_driver(driver)
|
71
|
+
unless drivers.has_key?(driver)
|
72
|
+
other_drivers = drivers.keys.map { |key| key.inspect }
|
73
|
+
raise SeleniumPlus::Exceptions::DriverNotFoundError, "Driver #{driver} was not found. Available types: #{other_drivers.join(', ')}"
|
74
74
|
end
|
75
|
+
@driver = drivers[driver].call
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
80
|
+
|
79
81
|
SeleniumPlus.configure do |config|
|
80
82
|
config.default_wait_time =10
|
81
|
-
config.
|
83
|
+
config.enable_highlight_element = true
|
82
84
|
end
|
83
85
|
|
84
86
|
SeleniumPlus.register_driver :firefox_driver do
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title></title>
|
5
|
+
<script type="text/javascript">
|
6
|
+
function showFirstTable(id) {
|
7
|
+
document.getElementById(id).style.display = 'block';
|
8
|
+
}
|
9
|
+
</script>
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<input type='submit' name='Show First Table' value='Show' onclick="showFirstTable('first')"/>
|
13
|
+
<div id='info'>
|
14
|
+
<table id="first" class='horizontal_headers' style="display: none">
|
15
|
+
<tr>
|
16
|
+
<th>ID:</th>
|
17
|
+
<th>Name:</th>
|
18
|
+
<th>Company:</th>
|
19
|
+
</tr>
|
20
|
+
<tr>
|
21
|
+
<td>1</td>
|
22
|
+
<td>Smith</td>
|
23
|
+
<td>VMware</td>
|
24
|
+
</tr>
|
25
|
+
<tr>
|
26
|
+
<td>2</td>
|
27
|
+
<td>James</td>
|
28
|
+
<td>EMC</td>
|
29
|
+
</tr>
|
30
|
+
</table>
|
31
|
+
<table class='vertical_headers'>
|
32
|
+
<tr>
|
33
|
+
<th>ID:</th>
|
34
|
+
<td>1</td>
|
35
|
+
<td>2</td>
|
36
|
+
</tr>
|
37
|
+
<tr>
|
38
|
+
<th>Name:</th>
|
39
|
+
<td>Alex</td>
|
40
|
+
<td>Eric</td>
|
41
|
+
</tr>
|
42
|
+
<tr>
|
43
|
+
<th>Company:</th>
|
44
|
+
<td>Google</td>
|
45
|
+
<td>Microsoft</td>
|
46
|
+
</tr>
|
47
|
+
</table>
|
48
|
+
</div>
|
49
|
+
</body>
|
50
|
+
</html>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Login Page</title>
|
5
|
+
<script type="text/javascript" language="JavaScript">
|
6
|
+
function visitHome()
|
7
|
+
{
|
8
|
+
window.location = 'home.html'
|
9
|
+
}
|
10
|
+
</script>
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<div>
|
14
|
+
<label for="username">Username:</label>
|
15
|
+
<input id="username" type="text" tabindex="1" size="25" name="username" />
|
16
|
+
</div>
|
17
|
+
<div>
|
18
|
+
<label for="password">Password:</label>
|
19
|
+
<input id="password" type="password" value="" tabindex="2" size="25" name="password" />
|
20
|
+
</div>
|
21
|
+
<div>
|
22
|
+
<input type="submit" value="login" name="commit" onclick="visitHome()" />
|
23
|
+
</div>
|
24
|
+
</body>
|
25
|
+
</html>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Test
|
2
|
+
class LoginPage < SeleniumPlus::Page
|
3
|
+
|
4
|
+
element(:username_input, :id, 'username')
|
5
|
+
element(:password_input, :id, 'password')
|
6
|
+
element(:submit_btn, :css, 'input[name=commit]')
|
7
|
+
|
8
|
+
def login
|
9
|
+
username_input.type('Spark')
|
10
|
+
password_input.type('12345')
|
11
|
+
submit_btn.click
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
require '../lib/selenium_plus'
|
3
|
+
#
|
4
|
+
SeleniumPlus.register_driver :firefox_driver do
|
5
|
+
SeleniumPlus::Driver.new(:browser => :firefox)
|
6
|
+
end
|
7
|
+
|
8
|
+
driver = SeleniumPlus.using_driver(:firefox_driver)
|
9
|
+
|
10
|
+
driver.visit('http://www.google.com.hk')
|
11
|
+
driver.find(:id, 'lst-ib')
|
12
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'selenium_plus'
|
4
|
+
require 'sections/info_section'
|
5
|
+
require 'pages/login_page'
|
6
|
+
require 'pages/home_page'
|
7
|
+
|
8
|
+
|
9
|
+
class TestSite
|
10
|
+
|
11
|
+
def login_page
|
12
|
+
Test::LoginPage.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def home_page
|
16
|
+
Test::HomePage.new
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
metadata
CHANGED
@@ -1,71 +1,60 @@
|
|
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.3
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- SparkYao
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-
|
12
|
+
date: 2013-03-05 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rake
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70285072777900 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: '0'
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
|
-
version_requirements:
|
23
|
-
requirements:
|
24
|
-
- - ! '>='
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
24
|
+
version_requirements: *70285072777900
|
27
25
|
- !ruby/object:Gem::Dependency
|
28
26
|
name: selenium-webdriver
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
27
|
+
requirement: &70285072776760 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
30
29
|
requirements:
|
31
30
|
- - ! '>='
|
32
31
|
- !ruby/object:Gem::Version
|
33
32
|
version: 2.25.0
|
34
33
|
type: :runtime
|
35
34
|
prerelease: false
|
36
|
-
version_requirements:
|
37
|
-
requirements:
|
38
|
-
- - ! '>='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 2.25.0
|
35
|
+
version_requirements: *70285072776760
|
41
36
|
- !ruby/object:Gem::Dependency
|
42
37
|
name: rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirement: &70285072775160 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
44
40
|
requirements:
|
45
41
|
- - ! '>='
|
46
42
|
- !ruby/object:Gem::Version
|
47
43
|
version: 2.1.0
|
48
44
|
type: :runtime
|
49
45
|
prerelease: false
|
50
|
-
version_requirements:
|
51
|
-
requirements:
|
52
|
-
- - ! '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 2.1.0
|
46
|
+
version_requirements: *70285072775160
|
55
47
|
- !ruby/object:Gem::Dependency
|
56
48
|
name: cucumber
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirement: &70285072774360 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
58
51
|
requirements:
|
59
52
|
- - ! '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 1.2.1
|
62
55
|
type: :development
|
63
56
|
prerelease: false
|
64
|
-
version_requirements:
|
65
|
-
requirements:
|
66
|
-
- - ! '>='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 1.2.1
|
57
|
+
version_requirements: *70285072774360
|
69
58
|
description: ''
|
70
59
|
email:
|
71
60
|
- shipuyao@gmail.com
|
@@ -78,45 +67,57 @@ files:
|
|
78
67
|
- LICENSE.txt
|
79
68
|
- README.md
|
80
69
|
- Rakefile
|
70
|
+
- features/drivers.feature
|
71
|
+
- features/step_definitions/general_steps.rb
|
72
|
+
- features/step_definitions/tables_steps.rb
|
73
|
+
- features/support/env.rb
|
74
|
+
- features/support/hooks.rb
|
75
|
+
- features/tables.feature
|
81
76
|
- lib/selenium_plus.rb
|
82
77
|
- lib/selenium_plus/driver.rb
|
83
|
-
- lib/selenium_plus/
|
78
|
+
- lib/selenium_plus/exceptions.rb
|
84
79
|
- lib/selenium_plus/page_obj/container.rb
|
85
80
|
- lib/selenium_plus/page_obj/page.rb
|
86
81
|
- lib/selenium_plus/page_obj/section.rb
|
87
|
-
- lib/selenium_plus/page_obj/site.rb
|
88
82
|
- lib/selenium_plus/selenium/element.rb
|
89
83
|
- lib/selenium_plus/selenium/table.rb
|
90
84
|
- lib/selenium_plus/version.rb
|
91
85
|
- selenium_plus.gemspec
|
92
|
-
-
|
93
|
-
-
|
94
|
-
-
|
95
|
-
-
|
96
|
-
-
|
97
|
-
-
|
98
|
-
-
|
86
|
+
- test_site/html/home.html
|
87
|
+
- test_site/html/login.html
|
88
|
+
- test_site/pages/home_page.rb
|
89
|
+
- test_site/pages/login_page.rb
|
90
|
+
- test_site/sections/info_section.rb
|
91
|
+
- test_site/test_project.rb
|
92
|
+
- test_site/test_site.rb
|
99
93
|
homepage: ''
|
100
94
|
licenses: []
|
101
|
-
metadata: {}
|
102
95
|
post_install_message:
|
103
96
|
rdoc_options: []
|
104
97
|
require_paths:
|
105
98
|
- lib
|
106
99
|
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
107
101
|
requirements:
|
108
102
|
- - ! '>='
|
109
103
|
- !ruby/object:Gem::Version
|
110
104
|
version: '0'
|
111
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
112
107
|
requirements:
|
113
108
|
- - ! '>='
|
114
109
|
- !ruby/object:Gem::Version
|
115
110
|
version: '0'
|
116
111
|
requirements: []
|
117
112
|
rubyforge_project:
|
118
|
-
rubygems_version:
|
113
|
+
rubygems_version: 1.8.7
|
119
114
|
signing_key:
|
120
|
-
specification_version:
|
115
|
+
specification_version: 3
|
121
116
|
summary: ''
|
122
|
-
test_files:
|
117
|
+
test_files:
|
118
|
+
- features/drivers.feature
|
119
|
+
- features/step_definitions/general_steps.rb
|
120
|
+
- features/step_definitions/tables_steps.rb
|
121
|
+
- features/support/env.rb
|
122
|
+
- features/support/hooks.rb
|
123
|
+
- features/tables.feature
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
MmEyMDM1ZjgxNDg3ZmU4M2VlNTllZTIyMDk2NWFhZWEzYWM1YjhjZg==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MmMzNjc3MjVlMjY4MDI2N2FkNDRiMGQ2Nzg2MTM4YTJkNmEzM2U2Ng==
|
7
|
-
!binary "U0hBNTEy":
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MmMwNDA3OWZjNzRmN2ZlODI0NTUyMDUzYmI1NmJjNTg4MWIwMzUxOGE3MDI4
|
10
|
-
OTdkZTA3MjE3YjJlMTNjNDg4ZmU5YTdiYjU4YjAwMWQzNDA2YmQ3ZGFmYTA3
|
11
|
-
OWVkZGE3YjU0ZmRkYzY1ZjM4ZDM5YmNkY2EyZDhjOGMzNGU4MDg=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YjQxNWQ1OTk3NDk4MzgyMTYxOTI4NDZhZmE2NWZmOGRhNjk3ZTViMzI5MjUz
|
14
|
-
ZDRmZWE4M2ZmNWVhNDc5ZjI1OWY0YzE2YzE1OWFiNTZhYWU2OTI3OTcyNzMx
|
15
|
-
YWE4ODIxYjE0ODAyZTAzMDg0Mzc1OGExZjk3N2EzOGFhZWU5OGE=
|
File without changes
|
File without changes
|
@@ -1,26 +0,0 @@
|
|
1
|
-
$:.unshift(File.dirname(__FILE__))
|
2
|
-
require '../lib/selenium_plus'
|
3
|
-
require 'rspec'
|
4
|
-
require 'test_site/test_site'
|
5
|
-
|
6
|
-
|
7
|
-
SeleniumPlus.register_driver :firefox_driver do
|
8
|
-
SeleniumPlus::Driver.new(:browser => :chrome)
|
9
|
-
end
|
10
|
-
|
11
|
-
SeleniumPlus.register_driver :chrome_driver do
|
12
|
-
SeleniumPlus::Driver.new(:browser => :chrome)
|
13
|
-
end
|
14
|
-
|
15
|
-
SeleniumPlus.current_driver = :chrome_driver
|
16
|
-
|
17
|
-
#driver = SeleniumPlus.using_driver
|
18
|
-
#driver.visit('http://www.google.com.hk')
|
19
|
-
#driver.find(:id,'lst-ib').type('Mozy')
|
20
|
-
#driver.find(:css,'input[name=btnK]').click
|
21
|
-
#sleep 5
|
22
|
-
|
23
|
-
@Test = TestSite.new
|
24
|
-
@Test.home_page.visit('file:///Users/shipuy/Github/selenium_plus/test_project/test_site/html/home.html')
|
25
|
-
@Test.home_page.show
|
26
|
-
puts @Test.home_page.info_section.has_names_table?
|
@@ -1,46 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<title></title>
|
5
|
-
<script type="text/javascript">
|
6
|
-
function load() {
|
7
|
-
|
8
|
-
}
|
9
|
-
window.onload = load;
|
10
|
-
</script>
|
11
|
-
</head>
|
12
|
-
<body>
|
13
|
-
<input type='text' id='keywords' value=''/>
|
14
|
-
<input type='submit' name='Submit' value='Show'/>
|
15
|
-
<div id='info'>
|
16
|
-
<table class='view'>
|
17
|
-
<tr>
|
18
|
-
<th>ID</th>
|
19
|
-
<th>Name</th>
|
20
|
-
</tr>
|
21
|
-
<tr>
|
22
|
-
<td>1</td>
|
23
|
-
<td>Alex</td>
|
24
|
-
</tr>
|
25
|
-
<tr>
|
26
|
-
<td>2</td>
|
27
|
-
<td>James</td>
|
28
|
-
</tr>
|
29
|
-
</table>
|
30
|
-
<table class='view'>
|
31
|
-
<tr>
|
32
|
-
<th>ID</th>
|
33
|
-
<th>Company</th>
|
34
|
-
</tr>
|
35
|
-
<tr>
|
36
|
-
<td>1</td>
|
37
|
-
<td>EMC</td>
|
38
|
-
</tr>
|
39
|
-
<tr>
|
40
|
-
<td>2</td>
|
41
|
-
<td>VMware</td>
|
42
|
-
</tr>
|
43
|
-
</table>
|
44
|
-
</div>
|
45
|
-
</body>
|
46
|
-
</html>
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Test
|
2
|
-
# This class provides actions for google search page
|
3
|
-
class HomePage < SeleniumPlus::Page
|
4
|
-
|
5
|
-
section(:info_section, InfoSection, :id, 'info')
|
6
|
-
|
7
|
-
# Private elements
|
8
|
-
#
|
9
|
-
element(:search_input, :id, 'keywords')
|
10
|
-
element(:submit_btn, :css, 'input[name=Submit]')
|
11
|
-
|
12
|
-
def show
|
13
|
-
search_input.type('hello world')
|
14
|
-
submit_btn.click
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Test
|
2
|
-
# This class provides actions for add new admin section
|
3
|
-
class InfoSection < SeleniumPlus::Section
|
4
|
-
|
5
|
-
# Private elements
|
6
|
-
#
|
7
|
-
element(:names_table, :css, 'table.view:first-child')
|
8
|
-
|
9
|
-
def names_table_rows
|
10
|
-
names_table
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|