selenium-client 1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,32 @@
1
+ module Nautilus
2
+
3
+ class Shell
4
+
5
+ def run(command, options = {})
6
+ sh build_command(command, options)
7
+ end
8
+
9
+ def build_command(command, options = {})
10
+ actual_command = command.kind_of?(Array) ? command.join(" ") : command
11
+ if options[:background]
12
+ if windows?
13
+ actual_command = "start /wait /b " + command
14
+ elsif options[:background]
15
+ actual_command << " &"
16
+ end
17
+ end
18
+ actual_command
19
+ end
20
+
21
+ def windows?
22
+ PLATFORM['win32']
23
+ end
24
+
25
+ def sh(command)
26
+ successful = system(command)
27
+ raise "Error while running >>#{command}<<" unless successful
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -21,13 +21,21 @@
21
21
  require 'net/http'
22
22
  require 'uri'
23
23
  require 'cgi'
24
+ require "digest/md5"
25
+ require "fileutils"
26
+ require File.expand_path(File.dirname(__FILE__) + '/tcp_socket_extension')
27
+ require File.expand_path(File.dirname(__FILE__) + '/nautilus/shell')
24
28
  require File.expand_path(File.dirname(__FILE__) + '/selenium/command_error')
25
29
  require File.expand_path(File.dirname(__FILE__) + '/selenium/protocol_error')
26
30
  require File.expand_path(File.dirname(__FILE__) + '/selenium/client/selenese_client')
27
31
  require File.expand_path(File.dirname(__FILE__) + '/selenium/client/generated_driver')
32
+ require File.expand_path(File.dirname(__FILE__) + '/selenium/client/idiomatic')
28
33
  require File.expand_path(File.dirname(__FILE__) + '/selenium/client/base')
29
34
  require File.expand_path(File.dirname(__FILE__) + '/selenium/client/driver')
30
35
  require File.expand_path(File.dirname(__FILE__) + '/selenium/client/selenium_helper')
36
+ require File.expand_path(File.dirname(__FILE__) + '/selenium/remote_control/remote_control')
37
+ require File.expand_path(File.dirname(__FILE__) + '/selenium/rake/remote_control_start_task')
38
+ require File.expand_path(File.dirname(__FILE__) + '/selenium/rake/remote_control_stop_task')
31
39
 
32
40
  # Backward compatibility
33
41
 
@@ -23,13 +23,14 @@ module Selenium
23
23
  include Selenium::Client::SeleneseClient
24
24
  include Selenium::Client::GeneratedDriver
25
25
 
26
- def initialize(server_host, server_port, browserStartCommand, browserURL, timeout=30000)
26
+ def initialize(server_host, server_port, browser_string, browser_url, timeout_in_seconds=300)
27
27
  @server_host = server_host
28
28
  @server_port = server_port
29
- @browserStartCommand = browserStartCommand
30
- @browserURL = browserURL
31
- @timeout = timeout
29
+ @browser_string = browser_string
30
+ @browser_url = browser_url
31
+ @timeout = timeout_in_seconds
32
32
  @extension_js = ""
33
+ @session_id = nil
33
34
  end
34
35
 
35
36
  def set_extension_js(extension_js)
@@ -37,7 +38,7 @@ module Selenium
37
38
  end
38
39
 
39
40
  def start()
40
- result = get_string("getNewBrowserSession", [@browserStartCommand, @browserURL, @extension_js])
41
+ result = get_string("getNewBrowserSession", [@browser_string, @browser_url, @extension_js])
41
42
  @session_id = result
42
43
  end
43
44
 
@@ -46,6 +47,26 @@ module Selenium
46
47
  @session_id = nil
47
48
  end
48
49
 
50
+ def start_new_browser_session
51
+ start
52
+ end
53
+
54
+ def close_current_browser_session
55
+ stop
56
+ end
57
+
58
+ def session_started?
59
+ not @session_id.nil?
60
+ end
61
+
62
+ def default_timeout_in_seconds
63
+ @timeout
64
+ end
65
+
66
+ def chrome_backend?
67
+ ["*chrome", "*firefox", "*firefox2", "*firefox3"].include?(@browser_string)
68
+ end
69
+
49
70
  end
50
71
 
51
72
  end
@@ -3,6 +3,7 @@ module Selenium
3
3
 
4
4
  class Driver
5
5
  include Selenium::Client::Base
6
+ include Selenium::Client::Idiomatic
6
7
  end
7
8
 
8
9
  end
@@ -0,0 +1,179 @@
1
+ #
2
+ # Provide a more idiomatic API than the generated Ruby driver.
3
+ #
4
+ # Work on progress...
5
+ #
6
+ module Selenium
7
+ module Client
8
+
9
+ module Idiomatic
10
+
11
+ # Return the text content of an HTML element (rendered text shown to
12
+ # the user). Works for any HTML element that contains text.
13
+ #
14
+ #
15
+ # This command uses either the textContent (Mozilla-like browsers)
16
+ # or the innerText (IE-like browsers) of the element, which is the
17
+ # rendered text shown to the user.
18
+ #
19
+ # 'locator' is an Selenium element locator
20
+ def text_content(locator)
21
+ get_string "getText", [locator,]
22
+ end
23
+
24
+ # Return the title of the current HTML page.
25
+ def title
26
+ get_string "getTitle"
27
+ end
28
+
29
+ # Returns the absolute URL of the current page.
30
+ def location
31
+ get_string "getLocation"
32
+ end
33
+
34
+ # Waits for a new page to load.
35
+ #
36
+ # Selenium constantly keeps track of new pages loading, and sets a
37
+ # "newPageLoaded" flag when it first notices a page load. Running
38
+ # any other Selenium command after turns the flag to false. Hence,
39
+ # if you want to wait for a page to load, you must wait immediately
40
+ # after a Selenium command that caused a page-load.
41
+ #
42
+ # 'timeout_in_seconds' is a timeout in seconds, after which this
43
+ # command will return with an error
44
+ def wait_for_page(timeout_in_seconds=nil)
45
+ actual_timeout = timeout_in_seconds || default_timeout_in_seconds
46
+ do_command "waitForPageToLoad", [actual_timeout * 1000,]
47
+ end
48
+
49
+ # Gets the entire text of the page.
50
+ def body_text
51
+ get_string "getBodyText"
52
+ end
53
+
54
+ # Clicks on a link, button, checkbox or radio button. If the click action
55
+ # causes a new page to load (like a link usually does), call
56
+ # waitForPageToLoad.
57
+ #
58
+ # 'locator' is an element locator
59
+ def click(locator, options={})
60
+ do_command("click", [locator,])
61
+ if options[:wait_for] == :page
62
+ wait_for_page options[:timeout_in_seconds]
63
+ end
64
+ end
65
+
66
+ # Verifies that the specified text pattern appears somewhere on the rendered page shown to the user.
67
+ #
68
+ # 'pattern' is a pattern to match with the text of the page
69
+ def text_present?(pattern)
70
+ get_boolean "isTextPresent", [pattern,]
71
+ end
72
+
73
+ # Verifies that the specified element is somewhere on the page.
74
+ #
75
+ # 'locator' is an element locator
76
+ def element_present?(locator)
77
+ get_boolean "isElementPresent", [locator,]
78
+ end
79
+
80
+ # Gets the (whitespace-trimmed) value of an input field
81
+ # (or anything else with a value parameter).
82
+ # For checkbox/radio elements, the value will be "on" or "off"
83
+ # depending on whether the element is checked or not.
84
+ #
85
+ # 'locator' is an element locator
86
+ def value(locator)
87
+ get_string "getValue", [locator,]
88
+ end
89
+
90
+ # Whether an alert occurred
91
+ def alert?
92
+ get_boolean "isAlertPresent"
93
+ end
94
+
95
+ # Retrieves the message of a JavaScript alert generated during the previous action,
96
+ # or fail if there were no alerts.
97
+ #
98
+ # Getting an alert has the same effect as manually clicking OK. If an
99
+ # alert is generated but you do not consume it with getAlert, the next Selenium action
100
+ # will fail.
101
+ # Under Selenium, JavaScript alerts will NOT pop up a visible alert
102
+ # dialog.
103
+ # Selenium does NOT support JavaScript alerts that are generated in a
104
+ # page's onload() event handler. In this case a visible dialog WILL be
105
+ # generated and Selenium will hang until someone manually clicks OK.
106
+ #
107
+ def alert
108
+ get_string "getAlert"
109
+ end
110
+
111
+ # Whether a confirmation has been auto-acknoledged (i.e. confirm() been called)
112
+ def confirmation?
113
+ get_boolean "isConfirmationPresent"
114
+ end
115
+
116
+ # Retrieves the message of a JavaScript confirmation dialog generated during
117
+ # the previous action.
118
+ #
119
+ # By default, the confirm function will return true, having the same effect
120
+ # as manually clicking OK. This can be changed by prior execution of the
121
+ # chooseCancelOnNextConfirmation command.
122
+ #
123
+ # If an confirmation is generated but you do not consume it with getConfirmation,
124
+ # the next Selenium action will fail.
125
+ #
126
+ # NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible
127
+ # dialog.
128
+ #
129
+ # NOTE: Selenium does NOT support JavaScript confirmations that are
130
+ # generated in a page's onload() event handler. In this case a visible
131
+ # dialog WILL be generated and Selenium will hang until you manually click
132
+ # OK.
133
+ def confirmation
134
+ get_string "getConfirmation"
135
+ end
136
+
137
+ # Whether a prompt occurred
138
+ def prompt?
139
+ get_boolean "isPromptPresent"
140
+ end
141
+
142
+ # Retrieves the message of a JavaScript question prompt dialog generated during
143
+ # the previous action.
144
+ #
145
+ # Successful handling of the prompt requires prior execution of the
146
+ # answerOnNextPrompt command. If a prompt is generated but you
147
+ # do not get/verify it, the next Selenium action will fail.
148
+ #
149
+ # NOTE: under Selenium, JavaScript prompts will NOT pop up a visible
150
+ # dialog.
151
+ #
152
+ # NOTE: Selenium does NOT support JavaScript prompts that are generated in a
153
+ # page's onload() event handler. In this case a visible dialog WILL be
154
+ # generated and Selenium will hang until someone manually clicks OK.
155
+ def prompt
156
+ get_string "getPrompt"
157
+ end
158
+
159
+ # Returns the result of evaluating the specified JavaScript snippet whithin the browser.
160
+ # The snippet may have multiple lines, but only the result of the last line will be returned.
161
+ #
162
+ # Note that, by default, the snippet will run in the context of the "selenium"
163
+ # object itself, so <tt>this</tt> will refer to the Selenium object. Use <tt>window</tt> to
164
+ # refer to the window of your application, e.g. <tt>window.document.getElementById('foo')</tt>
165
+ # If you need to use
166
+ # a locator to refer to a single element in your application page, you can
167
+ # use <tt>this.browserbot.findElement("id=foo")</tt> where "id=foo" is your locator.
168
+ #
169
+ # 'script' is the JavaScript snippet to run
170
+ def js_eval(script)
171
+ get_string "getEval", [script,]
172
+ end
173
+
174
+
175
+ # set speed
176
+ end
177
+
178
+ end
179
+ end
@@ -7,14 +7,14 @@ module Selenium
7
7
  attr_reader :session_id
8
8
 
9
9
  def do_command(verb, args)
10
- timeout(@timeout) do
10
+ timeout(default_timeout_in_seconds) do
11
11
  status, response = http_post(http_request_for(verb, args))
12
12
  raise SeleniumCommandError, response unless status == "OK"
13
13
  response
14
14
  end
15
15
  end
16
16
 
17
- def get_string(verb, args)
17
+ def get_string(verb, args=[])
18
18
  do_command(verb, args)
19
19
  end
20
20
 
@@ -53,7 +53,7 @@ module Selenium
53
53
  return get_string_array(verb, args)
54
54
  end
55
55
 
56
- def get_boolean(verb, args)
56
+ def get_boolean(verb, args=[])
57
57
  parse_boolean_value get_string(verb, args)
58
58
  end
59
59
 
@@ -82,10 +82,10 @@ module Selenium
82
82
  end
83
83
 
84
84
  def http_post(data)
85
- #print "Requesting --->" + command_string + "\n"
85
+ # puts "Requesting ---> #{data.inspect}"
86
86
  http = Net::HTTP.new(@server_host, @server_port)
87
87
  response = http.post('/selenium-server/driver/', data, HTTP_HEADERS)
88
- #print "RESULT: " + response.body + "\n\n"å
88
+ # puts "RESULT: #{response.inspect}\n"
89
89
  [ response.body[0..1], response.body[3..-1] ]
90
90
  end
91
91
 
@@ -24,11 +24,11 @@ module Selenium
24
24
 
25
25
  # Passes all calls to missing methods to @selenium
26
26
  def method_missing(method_name, *args)
27
- if args.empty?
28
- @selenium.send(method_name)
29
- else
30
- @selenium.send(method_name, *args)
31
- end
27
+ if args.empty?
28
+ @selenium.send(method_name)
29
+ else
30
+ @selenium.send(method_name, *args)
31
+ end
32
32
  end
33
33
  end
34
34
 
@@ -0,0 +1,43 @@
1
+ module Selenium
2
+ module Rake
3
+
4
+ class RemoteControlStartTask
5
+ attr_accessor :port, :timeout_in_seconds, :background,
6
+ :wait_until_up_and_running, :additional_args
7
+ attr_reader :jar_file
8
+
9
+ def initialize(name = :'selenium:rc:start')
10
+ @name = name
11
+ @port = 4444
12
+ @timeout_in_seconds = 5
13
+ @jar_file = "vendor/selenium/selenium-server-1.0-standalone.jar"
14
+ @additional_args = []
15
+ @background = false
16
+ @wait_until_up_and_running = false
17
+ yield self if block_given?
18
+ define
19
+ end
20
+
21
+ def jar_file=(new_jar_file)
22
+ @jar_file = File.expand_path(new_jar_file)
23
+ end
24
+
25
+ def define
26
+ desc "Launch Selenium Remote Control"
27
+ task @name do
28
+ puts "Starting Selenium Remote Control at 0.0.0.0:#{@port}..."
29
+ remote_control = Selenium::RemoteControl::RemoteControl.new("0.0.0.0", @port, @timeout_in_seconds)
30
+ remote_control.jar_file = @jar_file
31
+ remote_control.additional_args = @additional_args
32
+ remote_control.start :background => @background
33
+ if @background && @wait_until_up_and_running
34
+ puts "Waiting for Remote Control to be up and running..."
35
+ TCPSocket.wait_for_service :host => @host, :port => @port
36
+ end
37
+ puts "Selenium Remote Control at 0.0.0.0:#{@port} ready"
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ module Selenium
2
+ module Rake
3
+
4
+ class RemoteControlStopTask
5
+ attr_accessor :host, :port, :timeout_in_seconds
6
+
7
+ def initialize(name = :'selenium:rc:stop')
8
+ @host = "localhost"
9
+ @name = name
10
+ @port = 4444
11
+ @timeout_in_seconds = 5
12
+ yield self if block_given?
13
+ define
14
+ end
15
+
16
+ def define
17
+ desc "Stop Selenium Remote Control running"
18
+ task @name do
19
+ puts "Stopping Selenium Remote Control running at #{@host}:#{@port}..."
20
+ remote_control = Selenium::RemoteControl::RemoteControl.new(@host, @port, @timeout_in_seconds)
21
+ remote_control.stop
22
+ puts "Stopped Selenium Remote Control running at #{@host}:#{@port}"
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,6 @@
1
+ require "net/http"
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../nautilus/shell')
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../tcp_socket_extension')
4
+ require File.expand_path(File.dirname(__FILE__) + '/../remote_control/remote_control')
5
+ require File.expand_path(File.dirname(__FILE__) + '/remote_control_start_task')
6
+ require File.expand_path(File.dirname(__FILE__) + '/remote_control_stop_task')
@@ -0,0 +1,30 @@
1
+ module Selenium
2
+ module RemoteControl
3
+
4
+ class RemoteControl
5
+ attr_reader :host, :port, :timeout_in_seconds
6
+ attr_accessor :additional_args, :jar_file
7
+
8
+ def initialize(host, port, timeout_in_seconds = 2 * 60)
9
+ @host, @port, @timeout_in_seconds = host, port, timeout_in_seconds
10
+ @additional_args = []
11
+ @shell = Nautilus::Shell.new
12
+ end
13
+
14
+ def start(options = {})
15
+ command = "java -jar \"#{jar_file}\""
16
+ command << " -port #{@port}"
17
+ command << " -timeout #{@timeout_in_seconds}"
18
+ command << " #{additional_args.join(' ')}" unless additional_args.empty?
19
+
20
+ @shell.run command, {:background => options[:background]}
21
+ end
22
+
23
+ def stop
24
+ Net::HTTP.get(@host, '/selenium-server/driver/?cmd=shutDown', @port)
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end