selenium-client 1.1

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.
@@ -0,0 +1,95 @@
1
+ module Selenium
2
+ module Client
3
+
4
+ HTTP_HEADERS = { 'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8' }
5
+
6
+ module SeleneseClient
7
+ attr_reader :session_id
8
+
9
+ def do_command(verb, args)
10
+ timeout(@timeout) do
11
+ status, response = http_post(http_request_for(verb, args))
12
+ raise SeleniumCommandError, response unless status == "OK"
13
+ response
14
+ end
15
+ end
16
+
17
+ def get_string(verb, args)
18
+ do_command(verb, args)
19
+ end
20
+
21
+ def get_string_array(verb, args)
22
+ csv = get_string(verb, args)
23
+ token = ""
24
+ tokens = []
25
+ escape = false
26
+ csv.split(//).each do |letter|
27
+ if escape
28
+ token += letter
29
+ escape = false
30
+ next
31
+ end
32
+ case letter
33
+ when '\\'
34
+ escape = true
35
+ when ','
36
+ tokens << token
37
+ token = ""
38
+ else
39
+ token += letter
40
+ end
41
+ end
42
+ tokens << token
43
+ return tokens
44
+ end
45
+
46
+ def get_number(verb, args)
47
+ # Is there something I need to do here?
48
+ return get_string(verb, args)
49
+ end
50
+
51
+ def get_number_array(verb, args)
52
+ # Is there something I need to do here?
53
+ return get_string_array(verb, args)
54
+ end
55
+
56
+ def get_boolean(verb, args)
57
+ parse_boolean_value get_string(verb, args)
58
+ end
59
+
60
+ def get_boolean_array(verb, args)
61
+ get_string_array(verb, args).collect {|value| parse_boolean_value(value)}
62
+ end
63
+
64
+ protected
65
+
66
+ def parse_boolean_value(value)
67
+ if ("true" == value)
68
+ return true
69
+ elsif ("false" == value)
70
+ return false
71
+ end
72
+ raise ProtocolError, "Invalid Selenese boolean value that is neither 'true' nor 'false': got '#{value}'"
73
+ end
74
+
75
+ def http_request_for(verb, args)
76
+ data = "cmd=#{CGI::escape(verb)}"
77
+ args.each_with_index do |arg, index|
78
+ data << "&#{index.succ}=#{CGI::escape(arg.to_s)}"
79
+ end
80
+ data << "&sessionId=#{session_id}" unless session_id.nil?
81
+ data
82
+ end
83
+
84
+ def http_post(data)
85
+ #print "Requesting --->" + command_string + "\n"
86
+ http = Net::HTTP.new(@server_host, @server_port)
87
+ response = http.post('/selenium-server/driver/', data, HTTP_HEADERS)
88
+ #print "RESULT: " + response.body + "\n\n"å
89
+ [ response.body[0..1], response.body[3..-1] ]
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+ end
@@ -0,0 +1,36 @@
1
+ # Defines a mixin module that you can use to write Selenium tests
2
+ # without typing "@selenium." in front of every command. Every
3
+ # call to a missing method will be automatically sent to the @selenium
4
+ # object.
5
+ module Selenium
6
+ module Client
7
+
8
+ module SeleniumHelper
9
+
10
+ # Overrides standard "open" method with @selenium.open
11
+ def open(addr)
12
+ @selenium.open(addr)
13
+ end
14
+
15
+ # Overrides standard "type" method with @selenium.type
16
+ def type(inputLocator, value)
17
+ @selenium.type(inputLocator, value)
18
+ end
19
+
20
+ # Overrides standard "select" method with @selenium.select
21
+ def select(inputLocator, optionLocator)
22
+ @selenium.select(inputLocator, optionLocator)
23
+ end
24
+
25
+ # Passes all calls to missing methods to @selenium
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
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,4 @@
1
+ module Selenium
2
+ class CommandError < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Selenium
2
+ class ProtocolError < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1,187 @@
1
+ require "digest/md5"
2
+ require "base64"
3
+ require "rubygems"
4
+ require "spec"
5
+ require 'spec/runner/formatter/html_formatter'
6
+
7
+ module Selenium
8
+ module RSpec
9
+ class ScreenshotFormatter < Spec::Runner::Formatter::HtmlFormatter
10
+ PLACEHOLDER = "<<placeholder>>"
11
+
12
+ ################### Hooks? ########
13
+
14
+ def start(example_count)
15
+ super
16
+ # ensure there's at least 1 example group header (normally 0 with deep_test)
17
+ # prevents js and html validity errors
18
+ example_group = Object.new
19
+ def example_group.description; ""; end
20
+ add_example_group(example_group)
21
+ end
22
+
23
+ def move_progress
24
+ # we don't have current_example_number, and we don't really care about the progress bar
25
+ end
26
+
27
+ def extra_failure_content(failure)
28
+ super + PLACEHOLDER
29
+ end
30
+
31
+ def example_passed(example)
32
+ include_example_group_description example
33
+ super
34
+ end
35
+
36
+ def example_pending(example_group_description, example, message)
37
+ include_example_group_description example
38
+ super
39
+ end
40
+
41
+ def example_failed(example, counter, failure)
42
+ include_example_group_description example
43
+ old_output = @output
44
+ @output = StringIO.new
45
+ super
46
+ result = @output.string
47
+ result.gsub! PLACEHOLDER, html_capture(example)
48
+ old_output.puts result
49
+ old_output.flush
50
+ ensure
51
+ @output = old_output
52
+ end
53
+
54
+
55
+ ###### Called from After each ####
56
+
57
+ def self.capture_browser_state(selenium_driver, example)
58
+ # Selenium RC seems to 'freeze' every so often when calling getHTMLSource, especially when DeepTest timeout is low, I need to investigate...
59
+ # Set deeptest :timeout_in_seconds => 30 to see it happen
60
+ capture_html_snapshot selenium_driver, example
61
+ capture_screenshot selenium_driver, example
62
+ end
63
+
64
+ def self.capture_html_snapshot(selenium_driver, example)
65
+ html = selenium_driver.get_html_source
66
+ File.open(file_for_html_capture(example), "w") { |f| f.write html }
67
+ end
68
+
69
+ def self.capture_screenshot(selenium_driver, example)
70
+ selenium_driver.window_maximize
71
+ encodedImage = selenium_driver.capture_screenshot_to_string
72
+ pngImage = Base64.decode64(encodedImage)
73
+ File.open(file_for_screenshot_capture(example), "w") { |f| f.write pngImage }
74
+ end
75
+
76
+ ################### Instrumentation ########
77
+
78
+ def html_capture(example)
79
+ dom_id = "example_" + self.class.hash_for_example(example)
80
+ screenshot_url = self.class.relative_file_for_png_capture(example)
81
+ snapshot_url = self.class.relative_file_for_html_capture(example)
82
+ <<-EOS
83
+ <div>[<a id="#{dom_id}_screenshot_link" href="javascript:toggleVisilibility('#{dom_id}_screenshot', 'Screenshot');">Show screenshot</a>]</div>
84
+ <br/>
85
+ <div id="#{dom_id}_screenshot" style="display: none">
86
+ <a href="#{screenshot_url}">
87
+ <img width="80%" src="#{screenshot_url}" />
88
+ </a>
89
+ </div>
90
+ <br/>
91
+
92
+ <div>[<a id="#{dom_id}_snapshot_link" href=\"javascript:toggleVisilibility('#{dom_id}_snapshot', 'Snapshot')\">Show snapshot</a>]</div>
93
+ <br/><br/>
94
+ <div id="#{dom_id}_snapshot" class="dyn-source">
95
+ <a href="#{snapshot_url}">Full screen</a><br/><br/>
96
+ <iframe src="#{snapshot_url}" width="100%" height="600px" ></iframe>
97
+ </div>
98
+ EOS
99
+ end
100
+
101
+
102
+ def self.relative_file_for_html_capture(example)
103
+ "resources/example_#{hash_for_example(example)}.html"
104
+ end
105
+
106
+ def self.relative_file_for_png_capture(example)
107
+ "resources/example_#{hash_for_example(example)}.png"
108
+ end
109
+
110
+ def self.file_for_html_capture(example)
111
+ file_name = capture_root_dir + "/example_#{hash_for_example(example)}.html"
112
+ FileUtils.mkdir_p(capture_root_dir) unless File.directory?(capture_root_dir)
113
+ file_name
114
+ end
115
+
116
+ def self.file_for_screenshot_capture(example)
117
+ file_name = capture_root_dir + "/example_#{hash_for_example(example)}.png"
118
+ FileUtils.mkdir_p(capture_root_dir) unless File.directory?(capture_root_dir)
119
+ file_name
120
+ end
121
+
122
+ def self.hash_for_example(example)
123
+ Digest::MD5.hexdigest example.implementation_backtrace.first
124
+ end
125
+
126
+
127
+ def self.capture_root_dir
128
+ root_dir + "/resources"
129
+ end
130
+
131
+ def self.root_dir
132
+ (ENV['CC_BUILD_ARTIFACTS'] || './tmp/rspec_report')
133
+ end
134
+
135
+
136
+ def include_example_group_description(example)
137
+ def example.description
138
+ self.class.description.to_s + " :: " + super
139
+ end
140
+ end
141
+
142
+
143
+ def report_header
144
+ super + "\n<script type=\"text/javascript\">moveProgressBar('100.0');</script>"
145
+ end
146
+
147
+
148
+
149
+ def global_scripts
150
+ super + <<-EOF
151
+ function toggleVisilibility(id, description) {
152
+ var section;
153
+ var link;
154
+
155
+ section = document.getElementById(id);
156
+ link = document.getElementById(id + "_link");
157
+
158
+ if (section.style.display == "block") {
159
+ section.style.display = "none"
160
+ link.innerHTML = description
161
+ } else {
162
+ section.style.display = "block"
163
+ link.innerHTML = "Hide " + description
164
+ }
165
+ }
166
+ EOF
167
+ end
168
+
169
+ def global_styles
170
+ super + <<-EOF
171
+ div.rspec-report textarea {
172
+ width: 100%;
173
+ }
174
+
175
+ div.rspec-report .dyn-source {
176
+ background: #FFFFEE none repeat scroll 0%;
177
+ border:1px dotted black;
178
+ color: #000000;
179
+ display: none;
180
+ margin: 0.5em 2em;
181
+ padding: 0.5em;
182
+ }
183
+ EOF
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,25 @@
1
+ module Selenium
2
+ module ScreenshotSaver
3
+
4
+ def save_screenshot_to(png_path)
5
+ dir = File.dirname(png_path)
6
+ FileUtils.mkdir_p(dir) unless File.directory?(dir)
7
+ if PLATFORM['darwin']
8
+ sh "screencapture '#{png_path}'"
9
+ elsif image_magick_support?
10
+ sh "import -window root '#{png_path}'"
11
+ end
12
+ end
13
+
14
+ def image_magick_support?
15
+ @image_magick_support ||= `import --version`.grep /"ImageMagick"/
16
+ end
17
+
18
+ def sh(command)
19
+ system command
20
+ STDERR.puts "Warning: Could not capture screenshot with '#{command}'" unless $? == 0
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,3 @@
1
+ Dir["#{File.dirname __FILE__}/unit/**/*_test.rb"].each do |test_case|
2
+ require test_case
3
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: selenium-client
3
+ version: !ruby/object:Gem::Version
4
+ version: "1.1"
5
+ platform: ruby
6
+ authors:
7
+ - OpenQA
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-16 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: selenium-client@rubyforge.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - lib/selenium/client/base.rb
26
+ - lib/selenium/client/driver.rb
27
+ - lib/selenium/client/generated_driver.rb
28
+ - lib/selenium/client/selenese_client.rb
29
+ - lib/selenium/client/selenium_helper.rb
30
+ - lib/selenium/command_error.rb
31
+ - lib/selenium/protocol_error.rb
32
+ - lib/selenium/rspec/screenshot_formatter.rb
33
+ - lib/selenium/screenshot_saver.rb
34
+ - lib/selenium.rb
35
+ - README
36
+ has_rdoc: true
37
+ homepage: http://selenium-client.rubyforge.com
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --title
41
+ - Selenium Client
42
+ - --main
43
+ - README
44
+ - --line-numbers
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project: selenium-client
62
+ rubygems_version: 1.2.0
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: Official Ruby Client for Selenium RC.
66
+ test_files:
67
+ - test/all_unit_tests.rb