bbc-selenium-webdriver 1.17.0

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.
Files changed (168) hide show
  1. data/CHANGES +473 -0
  2. data/README +31 -0
  3. data/lib/selenium-client.rb +2 -0
  4. data/lib/selenium-webdriver.rb +1 -0
  5. data/lib/selenium/client.rb +37 -0
  6. data/lib/selenium/client/base.rb +118 -0
  7. data/lib/selenium/client/driver.rb +10 -0
  8. data/lib/selenium/client/errors.rb +9 -0
  9. data/lib/selenium/client/extensions.rb +118 -0
  10. data/lib/selenium/client/idiomatic.rb +488 -0
  11. data/lib/selenium/client/javascript_expression_builder.rb +116 -0
  12. data/lib/selenium/client/javascript_frameworks/jquery.rb +13 -0
  13. data/lib/selenium/client/javascript_frameworks/prototype.rb +13 -0
  14. data/lib/selenium/client/legacy_driver.rb +1720 -0
  15. data/lib/selenium/client/protocol.rb +104 -0
  16. data/lib/selenium/client/selenium_helper.rb +34 -0
  17. data/lib/selenium/rake/server_task.rb +157 -0
  18. data/lib/selenium/server.rb +223 -0
  19. data/lib/selenium/webdriver.rb +64 -0
  20. data/lib/selenium/webdriver/android.rb +9 -0
  21. data/lib/selenium/webdriver/android/bridge.rb +51 -0
  22. data/lib/selenium/webdriver/chrome.rb +26 -0
  23. data/lib/selenium/webdriver/chrome/bridge.rb +106 -0
  24. data/lib/selenium/webdriver/chrome/profile.rb +83 -0
  25. data/lib/selenium/webdriver/chrome/service.rb +74 -0
  26. data/lib/selenium/webdriver/common.rb +30 -0
  27. data/lib/selenium/webdriver/common/action_builder.rb +352 -0
  28. data/lib/selenium/webdriver/common/alert.rb +26 -0
  29. data/lib/selenium/webdriver/common/bridge_helper.rb +67 -0
  30. data/lib/selenium/webdriver/common/core_ext/base64.rb +9 -0
  31. data/lib/selenium/webdriver/common/core_ext/dir.rb +42 -0
  32. data/lib/selenium/webdriver/common/core_ext/string.rb +5 -0
  33. data/lib/selenium/webdriver/common/driver.rb +301 -0
  34. data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +39 -0
  35. data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +44 -0
  36. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +43 -0
  37. data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +46 -0
  38. data/lib/selenium/webdriver/common/element.rb +262 -0
  39. data/lib/selenium/webdriver/common/error.rb +212 -0
  40. data/lib/selenium/webdriver/common/file_reaper.rb +47 -0
  41. data/lib/selenium/webdriver/common/keyboard.rb +52 -0
  42. data/lib/selenium/webdriver/common/keys.rb +109 -0
  43. data/lib/selenium/webdriver/common/mouse.rb +65 -0
  44. data/lib/selenium/webdriver/common/navigation.rb +43 -0
  45. data/lib/selenium/webdriver/common/options.rb +128 -0
  46. data/lib/selenium/webdriver/common/platform.rb +166 -0
  47. data/lib/selenium/webdriver/common/port_prober.rb +25 -0
  48. data/lib/selenium/webdriver/common/profile_helper.rb +67 -0
  49. data/lib/selenium/webdriver/common/proxy.rb +120 -0
  50. data/lib/selenium/webdriver/common/search_context.rb +92 -0
  51. data/lib/selenium/webdriver/common/socket_poller.rb +100 -0
  52. data/lib/selenium/webdriver/common/target_locator.rb +81 -0
  53. data/lib/selenium/webdriver/common/timeouts.rb +29 -0
  54. data/lib/selenium/webdriver/common/wait.rb +60 -0
  55. data/lib/selenium/webdriver/common/window.rb +96 -0
  56. data/lib/selenium/webdriver/common/zipper.rb +82 -0
  57. data/lib/selenium/webdriver/firefox.rb +37 -0
  58. data/lib/selenium/webdriver/firefox/binary.rb +161 -0
  59. data/lib/selenium/webdriver/firefox/bridge.rb +58 -0
  60. data/lib/selenium/webdriver/firefox/extension.rb +52 -0
  61. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  62. data/lib/selenium/webdriver/firefox/launcher.rb +104 -0
  63. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  64. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  65. data/lib/selenium/webdriver/firefox/profile.rb +315 -0
  66. data/lib/selenium/webdriver/firefox/profiles_ini.rb +62 -0
  67. data/lib/selenium/webdriver/firefox/socket_lock.rb +61 -0
  68. data/lib/selenium/webdriver/firefox/util.rb +29 -0
  69. data/lib/selenium/webdriver/ie.rb +19 -0
  70. data/lib/selenium/webdriver/ie/bridge.rb +60 -0
  71. data/lib/selenium/webdriver/ie/native/win32/IEDriver.dll +0 -0
  72. data/lib/selenium/webdriver/ie/native/x64/IEDriver.dll +0 -0
  73. data/lib/selenium/webdriver/ie/server.rb +64 -0
  74. data/lib/selenium/webdriver/iphone.rb +9 -0
  75. data/lib/selenium/webdriver/iphone/bridge.rb +50 -0
  76. data/lib/selenium/webdriver/opera.rb +24 -0
  77. data/lib/selenium/webdriver/opera/bridge.rb +113 -0
  78. data/lib/selenium/webdriver/opera/service.rb +49 -0
  79. data/lib/selenium/webdriver/remote.rb +21 -0
  80. data/lib/selenium/webdriver/remote/bridge.rb +473 -0
  81. data/lib/selenium/webdriver/remote/capabilities.rb +241 -0
  82. data/lib/selenium/webdriver/remote/commands.rb +181 -0
  83. data/lib/selenium/webdriver/remote/http/common.rb +74 -0
  84. data/lib/selenium/webdriver/remote/http/curb.rb +79 -0
  85. data/lib/selenium/webdriver/remote/http/default.rb +102 -0
  86. data/lib/selenium/webdriver/remote/http/persistent.rb +38 -0
  87. data/lib/selenium/webdriver/remote/response.rb +99 -0
  88. data/lib/selenium/webdriver/remote/server_error.rb +17 -0
  89. data/lib/selenium/webdriver/support.rb +4 -0
  90. data/lib/selenium/webdriver/support/abstract_event_listener.rb +28 -0
  91. data/lib/selenium/webdriver/support/block_event_listener.rb +17 -0
  92. data/lib/selenium/webdriver/support/event_firing_bridge.rb +112 -0
  93. data/lib/selenium/webdriver/support/select.rb +293 -0
  94. data/spec/integration/selenium/client/api/backward_compatible_api_spec.rb +22 -0
  95. data/spec/integration/selenium/client/api/browser_xpath_library_spec.rb +17 -0
  96. data/spec/integration/selenium/client/api/click_spec.rb +39 -0
  97. data/spec/integration/selenium/client/api/cookie_spec.rb +39 -0
  98. data/spec/integration/selenium/client/api/element_spec.rb +14 -0
  99. data/spec/integration/selenium/client/api/highlight_located_element_spec.rb +19 -0
  100. data/spec/integration/selenium/client/api/retrieve_last_remote_control_logs_spec.rb +33 -0
  101. data/spec/integration/selenium/client/api/screenshot_spec.rb +29 -0
  102. data/spec/integration/selenium/client/api/select_window_spec.rb +46 -0
  103. data/spec/integration/selenium/client/api/start_stop_spec.rb +9 -0
  104. data/spec/integration/selenium/client/api/wait_for_ajax_spec.rb +27 -0
  105. data/spec/integration/selenium/client/api/wait_for_element_spec.rb +56 -0
  106. data/spec/integration/selenium/client/api/wait_for_field_value_spec.rb +52 -0
  107. data/spec/integration/selenium/client/api/wait_for_text_spec.rb +98 -0
  108. data/spec/integration/selenium/client/sample-app/public/jquery-1.3.2.js +4376 -0
  109. data/spec/integration/selenium/client/sample-app/public/jquery.html +55 -0
  110. data/spec/integration/selenium/client/sample-app/public/prototype-1.6.0.3.js +4320 -0
  111. data/spec/integration/selenium/client/sample-app/public/prototype.html +59 -0
  112. data/spec/integration/selenium/client/sample-app/sample_app.rb +32 -0
  113. data/spec/integration/selenium/client/spec_helper.rb +125 -0
  114. data/spec/integration/selenium/webdriver/chrome/driver_spec.rb +28 -0
  115. data/spec/integration/selenium/webdriver/chrome/profile_spec.rb +42 -0
  116. data/spec/integration/selenium/webdriver/driver_spec.rb +253 -0
  117. data/spec/integration/selenium/webdriver/element_spec.rb +185 -0
  118. data/spec/integration/selenium/webdriver/error_spec.rb +30 -0
  119. data/spec/integration/selenium/webdriver/firefox/driver_spec.rb +21 -0
  120. data/spec/integration/selenium/webdriver/firefox/profile_spec.rb +141 -0
  121. data/spec/integration/selenium/webdriver/keyboard_spec.rb +57 -0
  122. data/spec/integration/selenium/webdriver/mouse_spec.rb +55 -0
  123. data/spec/integration/selenium/webdriver/navigation_spec.rb +44 -0
  124. data/spec/integration/selenium/webdriver/opera/driver_spec.rb +47 -0
  125. data/spec/integration/selenium/webdriver/options_spec.rb +49 -0
  126. data/spec/integration/selenium/webdriver/remote/element_spec.rb +24 -0
  127. data/spec/integration/selenium/webdriver/spec_helper.rb +44 -0
  128. data/spec/integration/selenium/webdriver/spec_support.rb +13 -0
  129. data/spec/integration/selenium/webdriver/spec_support/guards.rb +86 -0
  130. data/spec/integration/selenium/webdriver/spec_support/helpers.rb +46 -0
  131. data/spec/integration/selenium/webdriver/spec_support/jruby_test_environment.rb +29 -0
  132. data/spec/integration/selenium/webdriver/spec_support/rack_server.rb +123 -0
  133. data/spec/integration/selenium/webdriver/spec_support/test_environment.rb +199 -0
  134. data/spec/integration/selenium/webdriver/target_locator_spec.rb +170 -0
  135. data/spec/integration/selenium/webdriver/timeout_spec.rb +56 -0
  136. data/spec/integration/selenium/webdriver/window_spec.rb +56 -0
  137. data/spec/integration/selenium/webdriver/zipper_spec.rb +66 -0
  138. data/spec/unit/selenium/client/base_spec.rb +239 -0
  139. data/spec/unit/selenium/client/extensions_spec.rb +174 -0
  140. data/spec/unit/selenium/client/idiomatic_spec.rb +500 -0
  141. data/spec/unit/selenium/client/javascript_expression_builder_spec.rb +79 -0
  142. data/spec/unit/selenium/client/javascript_frameworks/jquery_spec.rb +10 -0
  143. data/spec/unit/selenium/client/javascript_frameworks/prototype_spec.rb +10 -0
  144. data/spec/unit/selenium/client/protocol_spec.rb +124 -0
  145. data/spec/unit/selenium/client/selenium_helper_spec.rb +56 -0
  146. data/spec/unit/selenium/client/spec_helper.rb +24 -0
  147. data/spec/unit/selenium/rake/task_spec.rb +79 -0
  148. data/spec/unit/selenium/server_spec.rb +131 -0
  149. data/spec/unit/selenium/webdriver/action_builder_spec.rb +90 -0
  150. data/spec/unit/selenium/webdriver/android/bridge_spec.rb +31 -0
  151. data/spec/unit/selenium/webdriver/chrome/bridge_spec.rb +94 -0
  152. data/spec/unit/selenium/webdriver/chrome/profile_spec.rb +57 -0
  153. data/spec/unit/selenium/webdriver/chrome/service_spec.rb +44 -0
  154. data/spec/unit/selenium/webdriver/error_spec.rb +41 -0
  155. data/spec/unit/selenium/webdriver/firefox/bridge_spec.rb +17 -0
  156. data/spec/unit/selenium/webdriver/iphone/bridge_spec.rb +30 -0
  157. data/spec/unit/selenium/webdriver/proxy_spec.rb +87 -0
  158. data/spec/unit/selenium/webdriver/remote/bridge_spec.rb +16 -0
  159. data/spec/unit/selenium/webdriver/remote/capabilities_spec.rb +111 -0
  160. data/spec/unit/selenium/webdriver/remote/http/common_spec.rb +24 -0
  161. data/spec/unit/selenium/webdriver/remote/http/default_spec.rb +46 -0
  162. data/spec/unit/selenium/webdriver/search_context_spec.rb +61 -0
  163. data/spec/unit/selenium/webdriver/socket_poller_spec.rb +68 -0
  164. data/spec/unit/selenium/webdriver/spec_helper.rb +6 -0
  165. data/spec/unit/selenium/webdriver/support/event_firing_spec.rb +111 -0
  166. data/spec/unit/selenium/webdriver/support/select_spec.rb +290 -0
  167. data/spec/unit/selenium/webdriver/wait_spec.rb +40 -0
  168. metadata +215 -0
@@ -0,0 +1,100 @@
1
+ require 'selenium/webdriver/common/platform'
2
+ require 'socket'
3
+
4
+ module Selenium
5
+ module WebDriver
6
+ class SocketPoller
7
+
8
+ def initialize(host, port, timeout = 0, interval = 0.25)
9
+ @host = host
10
+ @port = Integer(port)
11
+ @timeout = Float(timeout)
12
+ @interval = interval
13
+ end
14
+
15
+ #
16
+ # Returns true if the server is listening within the given timeout,
17
+ # false otherwise.
18
+ #
19
+ # @return [Boolean]
20
+ #
21
+
22
+ def connected?
23
+ with_timeout { listening? }
24
+ end
25
+
26
+ #
27
+ # Returns true if the server has stopped listening within the given timeout,
28
+ # false otherwise.
29
+ #
30
+ # @return [Boolean]
31
+ #
32
+
33
+ def closed?
34
+ with_timeout { not listening? }
35
+ end
36
+
37
+ private
38
+
39
+ CONNECT_TIMEOUT = 5
40
+
41
+ NOT_CONNECTED_ERRORS = [Errno::ECONNREFUSED, Errno::ENOTCONN, SocketError]
42
+ NOT_CONNECTED_ERRORS << Errno::EPERM if Platform.cygwin?
43
+
44
+ CONNECTED_ERRORS = [Errno::EISCONN]
45
+ CONNECTED_ERRORS << Errno::EINVAL if Platform.windows?
46
+
47
+ if Platform.jruby?
48
+ # we use a plain TCPSocket here since JRuby has issues select()ing on a connecting socket
49
+ # see http://jira.codehaus.org/browse/JRUBY-5165
50
+ def listening?
51
+ TCPSocket.new(@host, @port).close
52
+ true
53
+ rescue *NOT_CONNECTED_ERRORS
54
+ false
55
+ end
56
+ else
57
+ def listening?
58
+ addr = Socket.getaddrinfo(@host, @port, Socket::AF_INET, Socket::SOCK_STREAM)
59
+ sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
60
+ sockaddr = Socket.pack_sockaddr_in(@port, addr[0][3])
61
+
62
+ begin
63
+ sock.connect_nonblock sockaddr
64
+ rescue Errno::EINPROGRESS
65
+ if IO.select(nil, [sock], nil, CONNECT_TIMEOUT)
66
+ retry
67
+ else
68
+ raise Errno::ECONNREFUSED
69
+ end
70
+ rescue *CONNECTED_ERRORS
71
+ # yay!
72
+ end
73
+
74
+ sock.close
75
+ true
76
+ rescue *NOT_CONNECTED_ERRORS
77
+ sock.close if sock
78
+ $stderr.puts [@host, @port].inspect if $DEBUG
79
+ false
80
+ end
81
+ end
82
+
83
+ def with_timeout(&blk)
84
+ max_time = Time.now + @timeout
85
+
86
+ (
87
+ return true if yield
88
+ wait
89
+ ) until Time.now > max_time
90
+
91
+ false
92
+ end
93
+
94
+ def wait
95
+ sleep @interval
96
+ end
97
+
98
+ end # SocketPoller
99
+ end # WebDriver
100
+ end # Selenium
@@ -0,0 +1,81 @@
1
+ module Selenium
2
+ module WebDriver
3
+ class TargetLocator
4
+
5
+ #
6
+ # @api private
7
+ #
8
+
9
+ def initialize(bridge)
10
+ @bridge = bridge
11
+ end
12
+
13
+ #
14
+ # switch to the frame with the given id
15
+ #
16
+
17
+ def frame(id)
18
+ @bridge.switchToFrame id
19
+ end
20
+
21
+ #
22
+ # switch to the given window handle
23
+ #
24
+ # If given a block, this method will switch back to the original window after
25
+ # block execution.
26
+ #
27
+ # @param id
28
+ # A window handle, obtained through Driver#window_handles
29
+ #
30
+
31
+ def window(id)
32
+ if block_given?
33
+ original = @bridge.getCurrentWindowHandle
34
+ @bridge.switchToWindow id
35
+
36
+ begin
37
+ returned = yield
38
+ ensure
39
+ current_handles = @bridge.getWindowHandles
40
+
41
+ if current_handles.size == 1
42
+ original = current_handles.shift
43
+ end
44
+
45
+ @bridge.switchToWindow original
46
+ returned
47
+ end
48
+ else
49
+ @bridge.switchToWindow id
50
+ end
51
+ end
52
+
53
+ #
54
+ # get the active element
55
+ #
56
+ # @return [WebDriver::Element]
57
+ #
58
+
59
+ def active_element
60
+ @bridge.switchToActiveElement
61
+ end
62
+
63
+ #
64
+ # selects either the first frame on the page, or the main document when a page contains iframes.
65
+ #
66
+
67
+ def default_content
68
+ @bridge.switchToDefaultContent
69
+ end
70
+
71
+ #
72
+ # switches to the currently active modal dialog for this particular driver instance
73
+ #
74
+
75
+ def alert
76
+ Alert.new(@bridge)
77
+ end
78
+
79
+ end # TargetLocator
80
+ end # WebDriver
81
+ end # Selenium
@@ -0,0 +1,29 @@
1
+ module Selenium
2
+ module WebDriver
3
+ class Timeouts
4
+
5
+ def initialize(bridge)
6
+ @bridge = bridge
7
+ end
8
+
9
+ #
10
+ # Set the amount of time the driver should wait when searching for elements.
11
+ #
12
+
13
+ def implicit_wait=(seconds)
14
+ @bridge.setImplicitWaitTimeout Integer(seconds * 1000)
15
+ end
16
+
17
+ #
18
+ # Sets the amount of time to wait for an asynchronous script to finish
19
+ # execution before throwing an error. If the timeout is negative, then the
20
+ # script will be allowed to run indefinitely.
21
+ #
22
+
23
+ def script_timeout=(seconds)
24
+ @bridge.setScriptTimeout Integer(seconds * 1000)
25
+ end
26
+
27
+ end # Timeouts
28
+ end # WebDriver
29
+ end # Selenium
@@ -0,0 +1,60 @@
1
+ module Selenium
2
+ module WebDriver
3
+ class Wait
4
+
5
+ DEFAULT_TIMEOUT = 5
6
+ DEFAULT_INTERVAL = 0.5
7
+
8
+ #
9
+ # Create a new Wait instance
10
+ #
11
+ # @param [Hash] opts Options for this instance
12
+ # @option opts [Numeric] :timeout (5) Seconds to wait before timing out.
13
+ # @option opts [Numeric] :interval (0.5) Seconds to sleep between polls.
14
+ # @option opts [String] :message Exception mesage if timed out.
15
+
16
+ def initialize(opts = {})
17
+ @timeout = opts.fetch(:timeout, DEFAULT_TIMEOUT)
18
+ @interval = opts.fetch(:interval, DEFAULT_INTERVAL)
19
+ @message = opts[:message]
20
+ end
21
+
22
+
23
+ #
24
+ # Wait until the given block returns a true value.
25
+ #
26
+ # @raise [Error::TimeOutError]
27
+ # @return [Object] the result of the block
28
+ #
29
+
30
+ def until(&blk)
31
+ end_time = Time.now + @timeout
32
+ last_error = nil
33
+
34
+ until Time.now > end_time
35
+ begin
36
+ result = yield
37
+ return result if result
38
+ rescue Error::NoSuchElementError => last_error
39
+ # swallowed
40
+ end
41
+
42
+ sleep @interval
43
+ end
44
+
45
+
46
+ if @message
47
+ msg = @message.dup
48
+ else
49
+ msg = "timed out after #{@timeout} seconds"
50
+ end
51
+
52
+ msg << " (#{last_error.message})}" if last_error
53
+
54
+ raise Error::TimeOutError, msg
55
+ end
56
+
57
+ end # Wait
58
+ end # WebDriver
59
+ end # Selenium
60
+
@@ -0,0 +1,96 @@
1
+ module Selenium
2
+ module WebDriver
3
+
4
+ #
5
+ # @api beta This API may be changed or removed in a future release.
6
+ #
7
+
8
+ class Window
9
+
10
+ #
11
+ # @api private
12
+ #
13
+
14
+ def initialize(bridge)
15
+ @bridge = bridge
16
+ end
17
+
18
+ #
19
+ # Resize the current window to the given dimension.
20
+ #
21
+ # @param [Selenium::WebDriver::Dimension, #width and #height] dimension The new size.
22
+ #
23
+
24
+ def size=(dimension)
25
+ unless dimension.respond_to?(:width) && dimension.respond_to?(:height)
26
+ raise ArgumentError, "expected #{dimension.inspect}:#{dimension.class}" +
27
+ " to respond to #width and #height"
28
+ end
29
+
30
+ @bridge.setWindowSize dimension.width, dimension.height
31
+ end
32
+
33
+ #
34
+ # Get the size of the current window.
35
+ #
36
+ # @return [Selenium::WebDriver::Dimension] The size.
37
+ #
38
+
39
+ def size
40
+ @bridge.getWindowSize
41
+ end
42
+
43
+ #
44
+ # Move the current window to the given position.
45
+ #
46
+ # @param [Selenium::WebDriver::Point, #x and #y] point The new position.
47
+ #
48
+
49
+ def position=(point)
50
+ unless point.respond_to?(:x) && point.respond_to?(:y)
51
+ raise ArgumentError, "expected #{point.inspect}:#{point.class}" +
52
+ " to respond to #x and #y"
53
+ end
54
+
55
+ @bridge.setWindowPosition point.x, point.y
56
+ end
57
+
58
+ #
59
+ # Get the position of the current window.
60
+ #
61
+ # @return [Selenium::WebDriver::Point] The position.
62
+ #
63
+
64
+ def position
65
+ @bridge.getWindowPosition
66
+ end
67
+
68
+ #
69
+ # Equivalent to #size=, but accepts width and height arguments.
70
+ #
71
+ # @example Maximize the window.
72
+ #
73
+ # max_width, max_height = driver.execute_script("return [window.screen.availWidth, window.screen.availHeight];")
74
+ # driver.manage.window.resize_to(max_width, max_height)
75
+ #
76
+
77
+ def resize_to(width, height)
78
+ @bridge.setWindowSize Integer(width), Integer(height)
79
+ end
80
+
81
+ #
82
+ # Equivalent to #position=, but accepts x and y arguments.
83
+ #
84
+ # @example
85
+ #
86
+ # driver.manage.window.move_to(300, 400)
87
+ #
88
+
89
+ def move_to(x, y)
90
+ @bridge.setWindowPosition Integer(x), Integer(y)
91
+ end
92
+
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,82 @@
1
+ require 'zip/zip'
2
+ require 'tempfile'
3
+ require 'find'
4
+
5
+ module Selenium
6
+ module WebDriver
7
+ #
8
+ # @api private
9
+ #
10
+
11
+ module Zipper
12
+
13
+ EXTENSIONS = %w[.zip .xpi]
14
+
15
+ class << self
16
+
17
+ def unzip(path)
18
+ destination = Dir.mktmpdir("unzip")
19
+ FileReaper << destination
20
+
21
+ Zip::ZipFile.open(path) do |zip|
22
+ zip.each do |entry|
23
+ to = File.join(destination, entry.name)
24
+ dirname = File.dirname(to)
25
+
26
+ FileUtils.mkdir_p dirname unless File.exist? dirname
27
+ zip.extract(entry, to)
28
+ end
29
+ end
30
+
31
+ destination
32
+ end
33
+
34
+ def zip(path)
35
+ with_tmp_zip do |zip|
36
+ ::Find.find(path) do |file|
37
+ unless File.directory?(file)
38
+ add_zip_entry zip, file, file.sub("#{path}/", '')
39
+ end
40
+ end
41
+
42
+ zip.commit
43
+ File.open(zip.name, "rb") { |io| Base64.strict_encode64 io.read }
44
+ end
45
+ end
46
+
47
+ def zip_file(path)
48
+ with_tmp_zip do |zip|
49
+ add_zip_entry zip, path, File.basename(path)
50
+
51
+ zip.commit
52
+ File.open(zip.name, "rb") { |io| Base64.strict_encode64 io.read }
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def with_tmp_zip(&blk)
59
+ # can't use Tempfile here since it doesn't support File::BINARY mode on 1.8
60
+ # can't use Dir.mktmpdir(&blk) because of http://jira.codehaus.org/browse/JRUBY-4082
61
+ tmp_dir = Dir.mktmpdir
62
+ zip_path = File.join(tmp_dir, "webdriver-zip")
63
+
64
+ begin
65
+ Zip::ZipFile.open(zip_path, Zip::ZipFile::CREATE, &blk)
66
+ ensure
67
+ FileUtils.rm_rf tmp_dir
68
+ FileUtils.rm_rf zip_path
69
+ end
70
+ end
71
+
72
+ def add_zip_entry(zip, file, entry_name)
73
+ entry = Zip::ZipEntry.new(zip.name, entry_name)
74
+ entry.follow_symlinks = true
75
+
76
+ zip.add entry, file
77
+ end
78
+
79
+ end
80
+ end # Zipper
81
+ end # WebDriver
82
+ end # Selenium