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