watir_robot 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ v0.1.0. Initial gem package for Watir Robot. Includes healthy base of Robot Framework keywords for driving the browser, taking a screenshot and using the mouse natively.
data/KEYWORDS.rdoc ADDED
@@ -0,0 +1,83 @@
1
+ = Currently Available Keywords
2
+
3
+ The following list of functions map to Robot Framework keywords. The keyword is derived from removing the hash symbol and underscores, and capitalizing the first letter of each word in the function name.
4
+
5
+ This documentation has been copied from YARD's output.
6
+
7
+ == Methods included from TextField
8
+ #input_password, #input_text, #textfield_should_contain, #textfield_text_should_be
9
+
10
+ == Methods included from Table
11
+ #get_table_cell, #table_cell_should_contain, #table_column_should_contain, #table_header_should_contain, #table_row_should_contain, #table_should_contain
12
+
13
+ == Methods included from Select
14
+ #clear_items_from_select_list, #select_all_items_from_list, #select_item_from_list
15
+
16
+ == Methods included from Radio
17
+ #radio_button_should_be_selected, #radio_button_should_not_be_selected, #select_radio_button
18
+
19
+ == Methods included from List
20
+ #get_list_items
21
+
22
+ == Methods included from Link
23
+ #click_link
24
+
25
+ == Methods included from Image
26
+ #click_image
27
+
28
+ == Methods included from CheckBox
29
+ #checkbox_should_be_selected, #checkbox_should_not_be_selected, #select_checkbox, #unselect_checkbox
30
+
31
+ == Methods included from Button
32
+ #click_button
33
+
34
+ == Methods included from Element
35
+ #click_element, #element_should_be_visible, #element_should_not_be_visible, #element_text_should_be, #element_text_should_contain, #focus, #get_element_attribute, #get_element_text
36
+
37
+ == Methods included from Page
38
+ #execute_javascript, #get_all_elements, #get_page_source, #get_page_status, #get_page_text, #get_title, #log_page_source, #page_should_contain, #page_should_contain_button, #page_should_contain_checkbox, #page_should_contain_element, #page_should_contain_image, #page_should_contain_link, #page_should_contain_list, #page_should_contain_radio_button, #page_should_contain_textfield, #page_should_not_contain, #page_should_not_contain_button, #page_should_not_contain_checkbox, #page_should_not_contain_element, #page_should_not_contain_image, #page_should_not_contain_link, #page_should_not_contain_list, #page_should_not_contain_radio_button, #page_should_not_contain_textfield, #title_should_be, #title_should_contain
39
+
40
+ == Methods included from Native
41
+ #capture_screenshot, #click_left_mouse_button, #click_right_mouse_button, #drag_and_drop, #move_mouse_to_position, #press_left_mouse_button, #press_right_mouse_button, #release_left_mouse_button, #release_right_mouse_button
42
+
43
+ == Methods included from Browser
44
+ #close_browser, #delete_all_cookies, #delete_cookie, #get_all_cookies, #get_cookie, #get_url, #go_back, #go_forward, #go_to, #maximize_browser_window, #open_browser, #refresh, #start_browser, #url_should_be, #url_should_contain
45
+
46
+ = Possible Future Keywords
47
+ * Alert Should Be Present (maybe)
48
+ * Choose Cancel On Next Confirmation (requires optional require: 'watir-webdriver/extensions/alerts')
49
+ * Close All Browsers (currently only support single browser)
50
+ * Close Window (WebDriver switches windows, you needn't close them, they'll close when Browser is killed)
51
+ * Confirm Action (optional require, see choose cancel above)
52
+ * Current Frame Should Contain
53
+ * Drag And Drop
54
+ * Frame Should Contain
55
+ * Get Alert Message
56
+ * Get All Links (return id, text;;)
57
+ * Get Horizontal Position (via JS)
58
+ * Get Matching Xpath Count = Get Number of Matches
59
+ * Get Vertical Position (via JS)
60
+ * Get Window Identifiers
61
+ * Get Window Names
62
+ * Get Window Titles
63
+ * List Selection Should Be
64
+ * List Should Have No Selections
65
+ * Mouse Down On Image
66
+ * Mouse Down On Link
67
+ * Mouse Out
68
+ * Mouse Over
69
+ * Open Context Menu (?)
70
+ * Press Key
71
+ * Press Key Native
72
+ * Register Keyword To Run On Failure
73
+ * Select Frame
74
+ * Select Window
75
+ * Simulate
76
+ * Switch Browser
77
+ * Table Footer Should Contain
78
+ * Unselect Frame
79
+ * Wait For Condition
80
+ * Wait Until Page Contains
81
+ * Wait Until Page Contains Element
82
+ * Wait Until Page Loaded
83
+ * Xpath Should Match X Times
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2010, Daniel L. Gregoire
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of Watir Robot, Semperos nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL DANIEL L. GREGOIRE BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Manifest ADDED
@@ -0,0 +1,28 @@
1
+ CHANGELOG
2
+ KEYWORDS.rdoc
3
+ LICENSE
4
+ Manifest
5
+ README.rdoc
6
+ Rakefile
7
+ lib/watir_robot.rb
8
+ lib/watir_robot/exception.rb
9
+ lib/watir_robot/keywords/browser.rb
10
+ lib/watir_robot/keywords/button.rb
11
+ lib/watir_robot/keywords/checkbox.rb
12
+ lib/watir_robot/keywords/element.rb
13
+ lib/watir_robot/keywords/file_field.rb
14
+ lib/watir_robot/keywords/form.rb
15
+ lib/watir_robot/keywords/image.rb
16
+ lib/watir_robot/keywords/link.rb
17
+ lib/watir_robot/keywords/list.rb
18
+ lib/watir_robot/keywords/native.rb
19
+ lib/watir_robot/keywords/page.rb
20
+ lib/watir_robot/keywords/radio.rb
21
+ lib/watir_robot/keywords/select.rb
22
+ lib/watir_robot/keywords/table.rb
23
+ lib/watir_robot/keywords/text_field.rb
24
+ lib/watir_robot/parser.rb
25
+ scripts/example_tests/resource.txt
26
+ scripts/example_tests/test.txt
27
+ scripts/run_server.rb
28
+ watir_robot.gemspec
data/README.rdoc ADDED
@@ -0,0 +1,116 @@
1
+ = Watir Robot Library
2
+
3
+ Watir Robot is a testing library for Robot Framework which provides keywords for automated web testing, using the Watir-WebDriver library to drive the browser. Because Watir-WebDriver is written in Ruby, this project interoperates with Robot Framework via its Remote Library interface.
4
+
5
+ See {this project's wiki}[https://github.com/semperos/watir-robot/wiki] for tutorials and further documentation. See the Watir Robot Users and Watir Robot Devel Google groups to join in the discussion or ask questions of the community.
6
+
7
+ == Overview
8
+
9
+ Although Robot Framework is designed to work with Python and Java testing libraries natively, it also provides a Remote Library interface which allows testing libraries written in any language to be used with Robot Framework. These testing libraries provide the first, low-level "layer" of keywords, from which can be built more complex test suites. Watir Robot provides keywords specific to automated functional web testing, using the Watir library for driving the browser. The goal of this project is to provide a base of keywords similar to the existing SeleniumLibrary available for Robot Framework.
10
+
11
+ This project is designed to be used in tandem with the +robot_remote_server+ gem hosted on Rubygems.org, with source code {on Github}[http://github.com/semperos/robot-remote-server]. In order to supply Robot Framework with keywords from Watir Robot, it is necessary to install that gem and run the included server application, feeding it an instance of the WatirRobot class.
12
+
13
+ == Terminology
14
+
15
+ * <b>Robot Framework:</b> A generic keyword-driven test automation framework. Map keywords to functions, then build a higher-level DSL by building keywords from keywords.
16
+ * <b>Robot Framework's Remote Library:</b> One of the standard libraries provided by Robot Framework, this is the interface which allows you to write a Remote Server in any language, providing the bridge between the Python/Java world of Robot Framework and your own testing library.
17
+ * <b>Remote Server:</b> Not part of Robot Framework, you can write a remote server to create a bridge between your testing library and Robot Framework by following the conventions of its Remote Library. A Python and Ruby implementation are provided as examples in Robot Framework's source code. A Ruby gem called +robot_remote_server+ is available on Rubygems.org and {here on Github}[http://github.com/semperos/robot-remote-server]
18
+ * <b>Remote Testing Library:</b> Robot Framework runs on keywords; the testing library is that first layer of keywords that maps keywords to functions. These can be written in any language, as long as you write/use a Remote Server written in the same language. This project is a Testing Library which uses Ruby and Watir to provide that keyword base.
19
+
20
+ These represent the full stack; on top of this stack, you write actual Robot Framework test cases. These can be written in a number of formats (text, HTML, etc.) and can be edited using the {RIDE (Robot IDE)}[http://code.google.com/p/robotframework-ride].
21
+
22
+ == Installation
23
+
24
+ === Ruby Compatibility
25
+
26
+ You must be running <b>JRuby >=1.5.3</b> to use this library.
27
+
28
+ *Note:* If you want to generate the YARD documentation for this project yourself, you should use MRI Ruby >=1.9.1 to do so, but JRuby for running the actual code.
29
+
30
+ === Dependencies
31
+
32
+ * +robot_remote_server+, which provides the Ruby interface to Robot Framework' Remote Library
33
+ * +yard+, as a _runtime_ dependency, because the YARD Registry is used to feed Robot Framework and RIDE metadata about defined keywords.
34
+
35
+ == Usage
36
+
37
+ === Context and Overview
38
+
39
+ This projects relies on the following stack (see Robot Framework's {Remote Library documentation}[http://code.google.com/p/robotframework/wiki/RemoteLibrary]):
40
+
41
+ * Robot Framework
42
+ * Remote Library
43
+
44
+ ...which we talk to with this stack:
45
+
46
+ * Remote Server
47
+ * Test Library (this project)
48
+ * Application being tested
49
+
50
+ Robot Framework relies on keywords to execute tests. The framework itself defines some keywords for setting up test suite dependencies, converting values to different types, setting up conditional workflows, and defining test assertions (see full lists in the Robot Framework {Built-In Library documentation}[http://code.google.com/p/robotframework/wiki/BuiltInLibrary]). Watir Robot, as a Test Library, defines its own set of keywords specific to the domain of automated web testing, including interacting with web pages and manipulating web browsers.
51
+
52
+ So, you're going to write regular Robot Framework tests, leveraging the Watir Robot library for extra keywords. The one catch is that Watir is written in Ruby, and Robot Framework only supports test libraries in Python and Java by default. However, Robot Framework has a Remote Library which allows us to interface with the main framework by running a local Remote Server instance that can communicate with the main framework (via XML-RPC). By writing a Remote Server in the language of our Test Library, we can define keywords in any programming language and use them within Robot Framework.
53
+
54
+ A Remote Server has already been implemented in Ruby by the Robot Framework development team, and I've packaged it as a gem on Rubygems.org. So make sure you have the <tt>robot_remote_server</tt> gem installed in addition to the +watir_robot+ gem (+watir_robot+ defines +robot_remote_server+ as a dependency, but in case you've pulled this down and installed it manually, you must have both parts).
55
+
56
+ Once you've installed +robot_remote_server+, you'll need to start an instance of the server and "register" the Watir Robot library with it. Without a running server, there's no way for Watir Robot to tell Robot Framework what keywords it defines.
57
+
58
+ === Practical Usage
59
+
60
+ To tell Robot Framework what keywords Watir Robot defines, we need to start the +robot_remote_server+ and pass in the main class that defines Watir Robot's keywords. You can accomplish this in two ways.
61
+
62
+ ==== Start Remote Server and Run Tests
63
+
64
+ Run the file <tt>scripts/run_server.rb</tt> to start an instance of the remote server. This file feeds the remote server the <tt>WatirRobot::KeywordLibrary</tt> class. You can copy the code in that file and supply your own class name to provide your own keyword library class.
65
+
66
+ Once you've started the server, Robot Framework is aware of Watir Robot's keywords, and you can start building Robot Framework tests with Watir-based keywords!
67
+
68
+ For instructions on writing and running Robot Framework tests, see these resources:
69
+
70
+ * {Quick Start}[http://code.google.com/p/robotframework/wiki/QuickStartGuide]
71
+ * {User Guide}[http://code.google.com/p/robotframework/wiki/UserGuide]
72
+ * RIDE[http://code.google.com/p/robotframework-ride], an integrated development environment for writing Robot Framework tests
73
+
74
+ === Keywords
75
+
76
+ This library primarily ships with Watir-based keywords for manipulating the browser. However, if used with JRuby, there are certain "native" keywords available for handling the mouse and keyboard.
77
+
78
+ This native functionality may eventually ship in a separate gem, but for now the <tt>lib/keywords/native.rb</tt> file contains the <tt>Native</tt> module. Require this module in <tt>watir_robot.rb</tt> and do <tt>include Native</tt> in the +WatirRobot+ class to leverage these keywords. They are currently disabled by default, since they necessitate the use of JRuby and Java dependencies.
79
+
80
+ === Documentation
81
+
82
+ One of the facilities provided by the Remote Library/server system is the collection of documentation and method signatures for remote keywords. Due to the fact that Ruby completely ignores comments in source files, we have to use separate documentation tools to parse and store this information.
83
+
84
+ The YARD tool is a perfect fit for this situation due to its modular nature. YARD separates the concerns of parsing, storing and displaying documentation, allowing us to use any part independently of the others. Watir Robot leverages the storage component, specifically the "yardoc file" produced after a run of the +yardoc+ command, which contains metadata on every method defined in this code base.
85
+
86
+ ==== Generate Documentation
87
+
88
+ If you need to re-generate the documentation locally, follow these instructions.
89
+
90
+ <b>Note:</b> MRI Ruby >=1.9.1 or later should be used to generate this project's documentation with YARD.
91
+
92
+ Make sure the +yard+ gem is installed for the version of Ruby you're using:
93
+
94
+ gem install yard
95
+
96
+ Then run the +yardoc+ command from this project's root. You should see output describing how many files were created and what percentage of your codebase is commented. You should also see a new folder called +.yardoc+ in your project's root; this is your "yardoc file."
97
+
98
+ By default, the +run_server.rb+ file which comes packaged with this project expects to find the yardoc file in the project's root folder. If you've adjusted the location of the yardoc file or adjusted the +run_server.rb+ file, you should ensure that it's pointing to the correct path.
99
+
100
+ = Why Watir? Which Watir?
101
+
102
+ First and most importantly, I feel that the Watir API is the cleanest and most intuitive among the open soure browser-driving frameworks available. Secondly, because it drives browsers using "native" drivers (not JavaScript manipulation), it is able to perform tasks that other tools are not.
103
+
104
+ I am currently using the Watir-WebDriver version of Watir to drive the browser, for the following reasons:
105
+
106
+ * It will become Watir 2.0
107
+ * It leverages the WebDriver library
108
+ * It supports more browsers than standard Watir (by virtue of WebDriver)
109
+ * It has one dependency, Selenium-WebDriver, whereas standard Watir requires a separate driver gem per browser
110
+ * It's receiving more active development than standard Watir at this time
111
+
112
+ If folks have strong opinions about the use of Watir vs Watir-WebDriver vs Tool Of Your Choice, please join the discussion {on the wiki page}[https://github.com/semperos/watir-robot/wiki/Watir-Discussion]
113
+
114
+ = To-Do's
115
+
116
+ * Implement keywords that interact with/collect values from multiple elements
data/Rakefile ADDED
@@ -0,0 +1,50 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'yard'
4
+ require 'fileutils'
5
+ require 'echoe'
6
+
7
+ PROJECT_DIR = File.expand_path(File.dirname(__FILE__))
8
+
9
+ Echoe.new('watir_robot') do |p|
10
+ p.description = "Watir Robot - Remote keyword library for Robot Framework"
11
+ p.url = "http://github.com/semperos/watir-robot"
12
+ p.author = "Daniel Gregoire"
13
+ p.ignore_pattern = ["tmp/*", "script/*"]
14
+ p.runtime_dependencies = ['robot_remote_server >=2.5.5.2', 'watir-webdriver >=0.1.8']
15
+ p.need_tar_gz = false
16
+ end
17
+
18
+ YARD::Rake::YardocTask.new do |t|
19
+ # t.files = ['lib/**/*.rb', OTHER_PATHS]
20
+ t.options = ['-b', 'yardoc']
21
+ end
22
+
23
+
24
+ namespace :clean do
25
+ desc "Remove Robot Framework test-run output"
26
+ task :rf do
27
+ FileUtils.rm Dir.glob(File.join('**', 'example_tests', '*.html'))
28
+ FileUtils.rm Dir.glob(File.join('**', 'example_tests', '*.xml'))
29
+ FileUtils.rm Dir.glob(File.join('**', '*.png'))
30
+ end
31
+
32
+ desc "Remove YARD documentation"
33
+ task :doc do
34
+ doc_dir = File.join(PROJECT_DIR, "doc")
35
+ FileUtils.rm_rf(doc_dir) if File.exists?(doc_dir)
36
+ end
37
+
38
+ desc "Remote YARD registry cache"
39
+ task :yardoc do
40
+ yardoc_dir = File.join(PROJECT_DIR, "yardoc")
41
+ FileUtils.rm_rf(yardoc_dir) if File.exists?(yardoc_dir)
42
+ end
43
+
44
+ desc "Cleanup all generated files"
45
+ task :all do
46
+ Rake::Task['clean:rf'].invoke
47
+ Rake::Task['clean:doc'].invoke
48
+ Rake::Task['clean:yardoc'].invoke
49
+ end
50
+ end
@@ -0,0 +1,56 @@
1
+ require 'watir-webdriver'
2
+
3
+ require 'watir_robot/parser'
4
+ require 'watir_robot/exception'
5
+
6
+ require 'watir_robot/keywords/browser'
7
+ require 'watir_robot/keywords/element'
8
+ require 'watir_robot/keywords/button'
9
+ require 'watir_robot/keywords/checkbox'
10
+ require 'watir_robot/keywords/file_field'
11
+ require 'watir_robot/keywords/form'
12
+ require 'watir_robot/keywords/image'
13
+ require 'watir_robot/keywords/link'
14
+ require 'watir_robot/keywords/list'
15
+ require 'watir_robot/keywords/native'
16
+ require 'watir_robot/keywords/page'
17
+ require 'watir_robot/keywords/radio'
18
+ require 'watir_robot/keywords/select'
19
+ require 'watir_robot/keywords/table'
20
+ require 'watir_robot/keywords/text_field'
21
+
22
+ #
23
+ # The overarching module which contains all keyword definitions and utilities
24
+ #
25
+ module WatirRobot
26
+
27
+ #
28
+ # The class which defines Robot Framework keywords.
29
+ #
30
+ # Feed an instance of this class to an instance of +RobotRemoteServer+
31
+ # provided by the +robot_remote_server+ gem to make these keywords
32
+ # available to your Robot Framework tests and to RIDE.
33
+ #
34
+ class KeywordLibrary
35
+ include WatirRobot::Exception
36
+ include WatirRobot::Parser
37
+
38
+ include WatirRobot::Browser
39
+ include WatirRobot::Button
40
+ include WatirRobot::CheckBox
41
+ include WatirRobot::Element
42
+ include WatirRobot::FileField
43
+ include WatirRobot::Form
44
+ include WatirRobot::Image
45
+ include WatirRobot::Link
46
+ include WatirRobot::List
47
+ include WatirRobot::Native
48
+ include WatirRobot::Page
49
+ include WatirRobot::Radio
50
+ include WatirRobot::Select
51
+ include WatirRobot::Table
52
+ include WatirRobot::TextField
53
+ end
54
+
55
+ end
56
+
@@ -0,0 +1,76 @@
1
+ module WatirRobot
2
+
3
+ #
4
+ # Custom exceptions for Watir Robot test cases
5
+ #
6
+ module Exception
7
+
8
+ #
9
+ # Exception when an object cannot be found on the given page
10
+ #
11
+ class ObjectDoesNotExist < RuntimeError; end
12
+ #
13
+ # Exception when an HTML element cannot be found on the given page
14
+ #
15
+ class ElementDoesNotExist < ObjectDoesNotExist; end
16
+
17
+ #
18
+ # Exception when an object does not match expected parameters
19
+ #
20
+ class ObjectMatchError < RuntimeError; end
21
+ #
22
+ # Exception when an element does not match expected parameters
23
+ #
24
+ class ElementMatchError < ObjectMatchError; end
25
+
26
+ #
27
+ # Exception when the page does not match expected parameters
28
+ #
29
+ class PageMatchError < ObjectMatchError; end
30
+
31
+ #
32
+ # Exception when the page title does not match expected string value
33
+ #
34
+ class TitleMatchError < ObjectMatchError; end
35
+
36
+ #
37
+ # Exception when the URL does not match the expected string value
38
+ #
39
+ class UrlMatchError < ObjectMatchError; end
40
+
41
+ #
42
+ # Exception when trying to match a Window is unsuccessful
43
+ #
44
+ class WindowMatchError < ObjectMatchError; end
45
+
46
+ #
47
+ # Exception when an object is visible or invisible and should be the opposite
48
+ #
49
+ class ObjectVisibilityError < RuntimeError; end
50
+ #
51
+ # Exception when an HTML element is visible or invisible and should be the opposite
52
+ #
53
+ class ElementVisibilityError < ObjectVisibilityError; end
54
+
55
+ #
56
+ # Exception when object is "selected" or "unselected" when it should be the opposite
57
+ #
58
+ class ObjectSelectionError < RuntimeError; end
59
+ #
60
+ # Exception when a checkbox is selected or unselected when it should be the opposite
61
+ #
62
+ class CheckboxSelectionError < RuntimeError; end
63
+
64
+ #
65
+ # Exception when a radio button is selected or unselected when it should be the opposite
66
+ #
67
+ class RadioSelectionError < RuntimeError; end
68
+
69
+ #
70
+ # Exception when a select list has items selected or unselected which should be the opposite
71
+ #
72
+ class SelectListSelectionError < RuntimeError; end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,317 @@
1
+ module WatirRobot
2
+
3
+ #
4
+ # Functionality at the browser level, including browser history and cookie handling
5
+ #
6
+ module Browser
7
+
8
+ ### Actions ###
9
+
10
+ #
11
+ # Start browser
12
+ #
13
+ # @param [String] browser the name of the browser to use, must match a name recognized by WebDriver
14
+ # @return [Object] the browser object with which to drive the browser
15
+ #
16
+ def open_browser(browser = 'firefox')
17
+ @browser = Watir::Browser.new browser.to_sym
18
+ @driver = @browser.driver
19
+ @window_id = 0
20
+ return @browser
21
+ end
22
+
23
+ #
24
+ # Open browser and go to specific URL
25
+ #
26
+ # @param [String] url the URL to navigate to
27
+ # @param [String] browser the name of the browser to use, must match a name recognized by WebDriver
28
+ # @return [Object] the browser object with which to drive the browser
29
+ #
30
+ def start_browser(url, browser = 'firefox')
31
+ self.open_browser browser
32
+ @browser.goto url
33
+ return @browser
34
+ end
35
+
36
+ #
37
+ # Get current URL
38
+ #
39
+ # @return [String] URL of the current page
40
+ #
41
+ def get_url
42
+ @browser.url
43
+ end
44
+
45
+ #
46
+ # Go to specific URL in already-opened browser
47
+ #
48
+ # @param [String] url the URL to navigate to
49
+ #
50
+ def go_to(url)
51
+ @browser.goto(url)
52
+ end
53
+
54
+ #
55
+ # Go back in browsing history
56
+ #
57
+ def go_back
58
+ @browser.back
59
+ end
60
+
61
+ #
62
+ # Go forward in browsing history
63
+ #
64
+ def go_forward
65
+ @browser.forward
66
+ end
67
+
68
+ #
69
+ # Refresh the current page
70
+ #
71
+ def refresh
72
+ @browser.refresh
73
+ end
74
+
75
+ #
76
+ # Get all cookies defined in the current session
77
+ #
78
+ # @return [Array<Hash>] list of cookies
79
+ #
80
+ def get_all_cookies
81
+ @driver.manage.all_cookies
82
+ end
83
+
84
+ #
85
+ # Get a cookie by name
86
+ #
87
+ # @param [String] name name of the cookie
88
+ # @return [Hash, nil] the cookie or nil, if it doesn't exist
89
+ #
90
+ def get_cookie(name)
91
+ @driver.manage.cookie_named(name)
92
+ end
93
+
94
+ #
95
+ # Delete all browser cookies
96
+ #
97
+ def delete_all_cookies
98
+ @browser.clear_cookies
99
+ end
100
+
101
+ #
102
+ # Delete individual cookie, identified by name
103
+ #
104
+ # @param [String] name name of the cookie
105
+ #
106
+ def delete_cookie(name)
107
+ @driver.manage.delete_cookie(name)
108
+ end
109
+
110
+ #
111
+ # Close current browser
112
+ #
113
+ def close_browser
114
+ @browser.close
115
+ end
116
+
117
+ #
118
+ # Maximize browser window (uses JavaScript)
119
+ #
120
+ def maximize_browser_window
121
+ @browser.execute_script(
122
+ "if (window.screen) {
123
+ window.moveTo(0, 0);
124
+ window.resizeTo(window.screen.availWidth, window.screen.availHeight);
125
+ };")
126
+ end
127
+
128
+ #
129
+ # Switch to "other" window; assumes there are only 2 open
130
+ #
131
+ def switch_to_other_window
132
+ @window_id = (@window_id - 1).abs
133
+ if @window_id != 0 and @window_id !=1
134
+ puts @window_id
135
+ raise(Exception::WindowMatchError, "You cannot use this keyword when more than 2 windows are open; you must use 'Switch To Window', 'Switch to Next Window', or 'Switch to Previous Window'")
136
+ end
137
+
138
+ @browser.windows[@window_id].use
139
+ end
140
+
141
+ #
142
+ # Switch to a specified opened window
143
+ #
144
+ # @param [String] loc attribute/value pairs that match an HTML element
145
+ #
146
+ def switch_to_window(loc)
147
+ if loc[0..3] == 'url=' or loc[0..5] == 'title='
148
+ @browser.window(parse_location(loc)).use
149
+ else
150
+ # assume loc is an integer
151
+ # since Robot Framework sends all args as text, the above check for
152
+ # "url=" and "title=" is the best we can do to ensure argument correctness
153
+ loc = loc.to_i
154
+ # the number of the window
155
+ # user-facing numbers are 1-based, internal we use 0-based because @browser.windows
156
+ # is a Ruby array, so minus 1
157
+ @window_id = loc - 1
158
+ if @window_id == -1
159
+ # either the user has been too smart for his/her own good and thinks the windows are 0-based,
160
+ # or they've entered text that doesn't match 'url=' or 'title=', in which case
161
+ # the above loc.to_i will make loc equal 0
162
+ raise(ArgumentError, "You must provide the url or title of the window in the format 'url=' or 'title=', or you must provide the number of the window, starting with 1 for the first window opened.")
163
+ end
164
+ # this will throw its own error if the index is out of range
165
+ @browser.windows[loc].use
166
+ end
167
+ end
168
+
169
+ #
170
+ # Switch to "next" window, the order depending on order of original opening.
171
+ #
172
+ # If the "last" window is active and you ask for the next, you will be taken
173
+ # back to the first window (i.e. it wraps around)
174
+ #
175
+ def switch_to_next_window
176
+ @window_id += 1
177
+ if @window_id >= @browser.windows.count
178
+ # wrap back to the first
179
+ @window_id = 0
180
+ end
181
+
182
+ @browser.windows[@window_id].use
183
+ end
184
+
185
+ #
186
+ # Switch to "previous" window, the order depending on order of original opening.
187
+ #
188
+ # If the "first" window is active and you ask for the previous, you will be taken
189
+ # around to the last window (i.e. it wraps around)
190
+ #
191
+ def switch_to_previous_window
192
+ @window_id -= 1
193
+ if @window_id < 0
194
+ # wrap back to the last
195
+ @window_id = @browser.windows.count - 1
196
+ end
197
+
198
+ @browser.windows[@window_id].use
199
+ end
200
+
201
+ #
202
+ # Close "other" window; assumes there are only 2 open
203
+ #
204
+ def close_other_window
205
+ @window_id = (@window_id - 1).abs
206
+ if @window_id != 0 and @window_id !=1
207
+ raise(Exception::WindowMatchError, "You cannot use this keyword when more than 2 windows are open; you must use 'Switch To Window', 'Switch to Next Window', or 'Switch to Previous Window'")
208
+ end
209
+
210
+ @browser.windows[@window_id].close
211
+ end
212
+
213
+ #
214
+ # Close a single browser window
215
+ #
216
+ # If you have multiple windows open and you close a non-active window, the window is simply closed.
217
+ # If you have multiple windows open and you close the active window, by default,
218
+ # the "previous" window will become the active one before closing the specified window
219
+ # (to avoid browser crashes). You can optionally specify which window should be used
220
+ # upon closing the active one.
221
+ # If you have only one window open and you issue this command, it is the same as calling
222
+ # "Close Browser", and the entire browser instance will be closed.
223
+ #
224
+ # @param [String] close_loc the identifier for the window you wish to close, either title, url, or integer
225
+ #
226
+ def close_window(close_loc = :current, active_loc = nil)
227
+ if @browser.windows.count == 1
228
+ # doesn't matter what they enter, bc closing the only window of a browser
229
+ # instance causes the browser to crash
230
+ @browser.close
231
+ end
232
+
233
+
234
+ if close_loc == :current
235
+ # if the current window is being closed, we have to move to another before closing it
236
+ if active_loc.nil?
237
+ # if new active window is unspecified, make the previous window the new active one
238
+ self.switch_to_previous_window
239
+ else
240
+ self.switch_to_window(active_loc)
241
+ end
242
+ else
243
+ # a specific window to be closed has been specified (though it may still be the active one)
244
+ if close_loc[0..3] == 'url=' or close_loc[0..5] == 'title='
245
+ if @browser.window(parse_location(close_loc)).current?
246
+ # if the current window is being closed, we have to move to another before closing it
247
+ if active_loc.nil?
248
+ # if new active window is unspecified, make the previous window the new active one
249
+ self.switch_to_previous_window
250
+ else
251
+ self.switch_to_window(active_loc)
252
+ end
253
+ end
254
+ @browser.window(parse_location(close_loc)).close
255
+ else
256
+ # assume close_loc is an integer
257
+ # since Robot Framework sends all args as text, the above check for
258
+ # "url=" and "title=" is the best we can do to ensure argument correctness
259
+ close_loc = close_loc.to_i
260
+ # the number of the window
261
+ # user-facing numbers are 1-based, internal we use 0-based because @browser.windows
262
+ # is a Ruby array, so minus 1
263
+ window_id = close_loc - 1
264
+ if window_id == -1
265
+ # either the user has been too smart for his/her own good and thinks the windows are 0-based,
266
+ # or they've entered text that doesn't match 'url=' or 'title=', in which case
267
+ # the above loc.to_i will make loc equal 0
268
+ raise(ArgumentError, "You must provide the url or title of the window in the format 'url=' or 'title=', or you must provide the number of the window, starting with 1 for the first window opened.")
269
+ end
270
+
271
+ if @browser.windows[window_id].current?
272
+ # if the current window is being closed, we have to move to another before closing it
273
+ if active_loc.nil?
274
+ # if new active window is unspecified, make the previous window the new active one
275
+ self.switch_to_previous_window
276
+ else
277
+ self.switch_to_window(active_loc)
278
+ end
279
+ end
280
+ # this will throw its own error if the index is out of range
281
+ @browser.windows[window_id].close
282
+ end
283
+ end
284
+ end
285
+
286
+ #
287
+ # Return the number of open windows
288
+ #
289
+ def get_window_count
290
+ return @browser.windows.count
291
+ end
292
+
293
+ ### Conditions ###
294
+
295
+ #
296
+ # Verify that the current URL matches a given string
297
+ #
298
+ # @param [String] url the URL to match against
299
+ #
300
+ def url_should_be(url)
301
+ raise(Exception::UrlMatchError, "The URL #{@browser.url} is not correct; it should be #{url}") unless
302
+ @browser.url == url
303
+ end
304
+
305
+ #
306
+ # Verify that URL contains certain text
307
+ #
308
+ # @param [String] text the text which should appear in the URL
309
+ #
310
+ def url_should_contain(text)
311
+ raise(Exception::UrlMatchError, "The URL #{@browser.url} is not correct; it should contain #{text}") unless
312
+ @browser.url.include?(text)
313
+ end
314
+
315
+ end
316
+
317
+ end