selenium-webdriver 3.0.8 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. data/CHANGES +9 -3
  2. data/lib/selenium/webdriver/chrome/bridge.rb +0 -1
  3. data/lib/selenium/webdriver/common.rb +9 -1
  4. data/lib/selenium/webdriver/common/action_builder.rb +1 -3
  5. data/lib/selenium/webdriver/common/driver.rb +17 -0
  6. data/lib/selenium/webdriver/common/interactions/input_device.rb +53 -0
  7. data/lib/selenium/webdriver/common/interactions/interaction.rb +52 -0
  8. data/lib/selenium/webdriver/common/interactions/interactions.rb +43 -0
  9. data/lib/selenium/webdriver/common/interactions/key_actions.rb +112 -0
  10. data/lib/selenium/webdriver/common/interactions/key_input.rb +64 -0
  11. data/lib/selenium/webdriver/common/{driver_extensions/has_input_devices.rb → interactions/none_input.rb} +9 -29
  12. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +355 -0
  13. data/lib/selenium/webdriver/common/interactions/pointer_input.rb +134 -0
  14. data/lib/selenium/webdriver/common/keys.rb +33 -12
  15. data/lib/selenium/webdriver/common/w3c_action_builder.rb +211 -0
  16. data/lib/selenium/webdriver/edge/bridge.rb +1 -4
  17. data/lib/selenium/webdriver/firefox/bridge.rb +1 -2
  18. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  19. data/lib/selenium/webdriver/firefox/w3c_bridge.rb +0 -1
  20. data/lib/selenium/webdriver/ie/bridge.rb +1 -1
  21. data/lib/selenium/webdriver/phantomjs/bridge.rb +1 -4
  22. data/lib/selenium/webdriver/remote/bridge.rb +25 -1
  23. data/lib/selenium/webdriver/remote/w3c_bridge.rb +16 -29
  24. data/lib/selenium/webdriver/remote/w3c_commands.rb +1 -0
  25. data/selenium-webdriver.gemspec +1 -1
  26. metadata +11 -3
data/CHANGES CHANGED
@@ -1,16 +1,22 @@
1
- 3.0.8 (2016-02-08)
1
+ 3.1.0 (2017-02-14)
2
+ ===================
3
+
4
+ Firefox:
5
+ * implement W3C actions endpoint
6
+
7
+ 3.0.8 (2017-02-08)
2
8
  ===================
3
9
 
4
10
  Firefox:
5
11
  * Fix signature of element returned from #active_element
6
12
 
7
- 3.0.7 (2016-02-06)
13
+ 3.0.7 (2017-02-06)
8
14
  ===================
9
15
 
10
16
  Firefox:
11
17
  * Fix signature of element arrays returned from #find_elements (issue 3471)
12
18
 
13
- 3.0.6 (2016-02-05)
19
+ 3.0.6 (2017-02-05)
14
20
  ===================
15
21
 
16
22
  Firefox:
@@ -49,7 +49,6 @@ module Selenium
49
49
  def driver_extensions
50
50
  [
51
51
  DriverExtensions::TakesScreenshot,
52
- DriverExtensions::HasInputDevices,
53
52
  DriverExtensions::HasWebStorage
54
53
  ]
55
54
  end
@@ -42,13 +42,15 @@ require 'selenium/webdriver/common/options'
42
42
  require 'selenium/webdriver/common/w3c_options'
43
43
  require 'selenium/webdriver/common/search_context'
44
44
  require 'selenium/webdriver/common/action_builder'
45
+ require 'selenium/webdriver/common/interactions/key_actions'
46
+ require 'selenium/webdriver/common/interactions/pointer_actions'
47
+ require 'selenium/webdriver/common/w3c_action_builder'
45
48
  require 'selenium/webdriver/common/touch_action_builder'
46
49
  require 'selenium/webdriver/common/html5/shared_web_storage'
47
50
  require 'selenium/webdriver/common/html5/local_storage'
48
51
  require 'selenium/webdriver/common/html5/session_storage'
49
52
  require 'selenium/webdriver/common/driver_extensions/takes_screenshot'
50
53
  require 'selenium/webdriver/common/driver_extensions/rotatable'
51
- require 'selenium/webdriver/common/driver_extensions/has_input_devices'
52
54
  require 'selenium/webdriver/common/driver_extensions/has_web_storage'
53
55
  require 'selenium/webdriver/common/driver_extensions/has_location'
54
56
  require 'selenium/webdriver/common/driver_extensions/has_session_id'
@@ -56,6 +58,12 @@ require 'selenium/webdriver/common/driver_extensions/has_touch_screen'
56
58
  require 'selenium/webdriver/common/driver_extensions/has_remote_status'
57
59
  require 'selenium/webdriver/common/driver_extensions/has_network_connection'
58
60
  require 'selenium/webdriver/common/driver_extensions/uploads_files'
61
+ require 'selenium/webdriver/common/interactions/interactions'
62
+ require 'selenium/webdriver/common/interactions/input_device'
63
+ require 'selenium/webdriver/common/interactions/interaction'
64
+ require 'selenium/webdriver/common/interactions/none_input'
65
+ require 'selenium/webdriver/common/interactions/key_input'
66
+ require 'selenium/webdriver/common/interactions/pointer_input'
59
67
  require 'selenium/webdriver/common/keys'
60
68
  require 'selenium/webdriver/common/bridge_helper'
61
69
  require 'selenium/webdriver/common/profile_helper'
@@ -23,9 +23,7 @@ module Selenium
23
23
  # The ActionBuilder provides the user a way to set up and perform
24
24
  # complex user interactions.
25
25
  #
26
- # This class should not be instantiated directly, but is created by
27
- # Selenium::WebDriver::DriverExtensions::HasInputDevices#action, which
28
- # is available on Driver instances that support the user interaction API.
26
+ # This class should not be instantiated directly, but is created by Driver#action
29
27
  #
30
28
  # @example
31
29
  #
@@ -124,6 +124,23 @@ module Selenium
124
124
  bridge.options
125
125
  end
126
126
 
127
+ #
128
+ # @return [ActionBuilder, W3CActionBuilder]
129
+ # @see ActionBuilder, W3CActionBuilder
130
+ #
131
+
132
+ def action
133
+ bridge.action
134
+ end
135
+
136
+ def mouse
137
+ bridge.mouse
138
+ end
139
+
140
+ def keyboard
141
+ bridge.keyboard
142
+ end
143
+
127
144
  #
128
145
  # Opens the specified URL in the browser.
129
146
  #
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ require 'securerandom'
21
+
22
+ module Selenium
23
+ module WebDriver
24
+ module Interactions
25
+ class InputDevice
26
+ attr_reader :name, :actions
27
+
28
+ def initialize(name = nil)
29
+ @name = name || SecureRandom.uuid
30
+ @actions = []
31
+ end
32
+
33
+ def add_action(action)
34
+ raise TypeError, "#{action.inspect} is not a valid action" unless action.class < Interaction
35
+ @actions << action
36
+ end
37
+
38
+ def clear_actions
39
+ @actions.clear
40
+ end
41
+
42
+ def create_pause(duration = nil)
43
+ add_action(Pause.new(self, duration))
44
+ end
45
+
46
+ def no_actions? # Determine if only pauses are present
47
+ actions = @actions.reject { |action| action.type == Interaction::PAUSE }
48
+ actions.empty?
49
+ end
50
+ end # InputDevice
51
+ end # Interactions
52
+ end # WebDriver
53
+ end # Selenium
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module Interactions
23
+ class Interaction
24
+ PAUSE = :pause
25
+
26
+ attr_reader :source
27
+
28
+ def initialize(source)
29
+ raise TypeError, "#{source.type} is not a valid input type" unless Interactions::SOURCE_TYPES.include? source.type
30
+ @source = source
31
+ end
32
+ end
33
+
34
+ class Pause < Interaction
35
+ def initialize(source, duration = nil)
36
+ super(source)
37
+ @duration = duration
38
+ end
39
+
40
+ def type
41
+ PAUSE
42
+ end
43
+
44
+ def encode
45
+ output = {type: type}
46
+ output[:duration] = @duration * 1000 if @duration
47
+ output
48
+ end
49
+ end # Interaction
50
+ end # Interactions
51
+ end # WebDriver
52
+ end # Selenium
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module Interactions
23
+ KEY = :key
24
+ POINTER = :pointer
25
+ NONE = :none
26
+ SOURCE_TYPES = [KEY, POINTER, NONE].freeze
27
+
28
+ class << self
29
+ def key(name)
30
+ KeyInput.new(name)
31
+ end
32
+
33
+ def pointer(kind, **kwargs)
34
+ PointerInput.new(kind, **kwargs)
35
+ end
36
+
37
+ def none(name = nil)
38
+ NoneInput.new(name)
39
+ end
40
+ end
41
+ end # Interactions
42
+ end # WebDriver
43
+ end # Selenium
@@ -0,0 +1,112 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module KeyActions
23
+ #
24
+ # Performs a key press. Does not release the key - subsequent interactions may assume it's kept pressed.
25
+ # Note that the modifier key is never released implicitly - either #key_up(key) or #release_actions must be
26
+ # called to release the key.
27
+ #
28
+ # @example Press a key
29
+ #
30
+ # driver.action.key_down(:control).perform
31
+ #
32
+ # @example Press a key on an element
33
+ #
34
+ # el = driver.find_element(id: "some_id")
35
+ # driver.action.key_down(el, :shift).perform
36
+ #
37
+ # @param [Selenium::WebDriver::Element] element An optional element
38
+ # @param [:shift, :alt, :control, :command, :meta, 'a'] key The key to press.
39
+ # @param [Symbol || String] device optional name of the KeyInput device to press the key on
40
+ # @return [W3CActionBuilder] A self reference.
41
+ #
42
+
43
+ def key_down(*args, device: nil)
44
+ key_action(*args, action: :create_key_down, device: device)
45
+ end
46
+
47
+ #
48
+ # Performs a modifier key release.
49
+ # Releasing a non-depressed modifier key will yield undefined behaviour.
50
+ #
51
+ # @example Release a key
52
+ #
53
+ # driver.action.key_up(:shift).perform
54
+ #
55
+ # @example Release a key from an element
56
+ #
57
+ # el = driver.find_element(id: "some_id")
58
+ # driver.action.key_up(el, :alt).perform
59
+ #
60
+ # @param [Selenium::WebDriver::Element] element An optional element
61
+ # @param [:shift, :alt, :control, :command, :meta, 'a'] key The modifier key to release.
62
+ # @param [Symbol || String] device optional name of the KeyInput device to release the key on
63
+ # @return [W3CActionBuilder] A self reference.
64
+ #
65
+
66
+ def key_up(*args, device: nil)
67
+ key_action(*args, action: :create_key_up, device: device)
68
+ end
69
+
70
+ #
71
+ # Sends keys to the active element. This differs from calling
72
+ # Element#send_keys(keys) on the active element in two ways:
73
+ #
74
+ # * The modifier keys included in this call are not released.
75
+ # * There is no attempt to re-focus the element - so send_keys(:tab) for switching elements should work.
76
+ #
77
+ # @example Send the text "help" to an element
78
+ #
79
+ # el = driver.find_element(id: "some_id")
80
+ # driver.action.send_keys(el, "help").perform
81
+ #
82
+ # @example Send the text "help" to the currently focused element
83
+ #
84
+ # driver.action.send_keys("help").perform
85
+ #
86
+ # @param [Selenium::WebDriver::Element] element An optional element
87
+ # @param [String] keys The keys to be sent.
88
+ # @param [Symbol || String] device optional name of the KeyInput device to send keys with
89
+ # @return [W3CActionBuilder] A self reference.
90
+ #
91
+
92
+ def send_keys(*args, device: nil)
93
+ click(args.shift) if args.first.is_a? Element
94
+ args.map { |x| x.is_a?(String) ? x.chars : x }.flatten.each do |arg|
95
+ key_down(arg, device: device)
96
+ key_up(arg, device: device)
97
+ end
98
+ self
99
+ end
100
+
101
+ private
102
+
103
+ def key_action(*args, action: nil, device: nil)
104
+ key_input = get_device(device) || key_inputs.first
105
+ click(args.shift) if args.first.is_a? Element
106
+ key_input.send(action, args.last)
107
+ tick(key_input)
108
+ self
109
+ end
110
+ end # KeyActions
111
+ end # WebDriver
112
+ end # Selenium
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module Interactions
23
+ class KeyInput < InputDevice
24
+ SUBTYPES = {down: :keyDown, up: :keyUp, pause: :pause}.freeze
25
+
26
+ def type
27
+ Interactions::KEY
28
+ end
29
+
30
+ def encode
31
+ return nil if no_actions?
32
+ {type: type, id: name, actions: @actions.map(&:encode)}
33
+ end
34
+
35
+ def create_key_down(key)
36
+ add_action(TypingInteraction.new(self, :down, key))
37
+ end
38
+
39
+ def create_key_up(key)
40
+ add_action(TypingInteraction.new(self, :up, key))
41
+ end
42
+
43
+ class TypingInteraction < Interaction
44
+ attr_reader :type
45
+
46
+ def initialize(source, type, key)
47
+ super(source)
48
+ @type = assert_type(type)
49
+ @key = Keys.encode_key(key)
50
+ end
51
+
52
+ def assert_type(type)
53
+ raise TypeError, "#{type.inspect} is not a valid key subtype" unless KeyInput::SUBTYPES.key? type
54
+ KeyInput::SUBTYPES[type]
55
+ end
56
+
57
+ def encode
58
+ {type: @type, value: @key}
59
+ end
60
+ end # TypingInteraction
61
+ end # KeyInput
62
+ end # Interactions
63
+ end # WebDriver
64
+ end # Selenium
@@ -19,37 +19,17 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- #
23
- # @api private
24
- #
25
-
26
- module DriverExtensions
27
- module HasInputDevices
28
- #
29
- # @return [ActionBuilder]
30
- # @api public
31
- #
32
-
33
- def action
34
- ActionBuilder.new mouse, keyboard
35
- end
36
-
37
- #
38
- # @api private
39
- #
40
-
41
- def mouse
42
- Mouse.new @bridge
22
+ module Interactions
23
+ class NoneInput < InputDevice
24
+ def type
25
+ Interactions::NONE
43
26
  end
44
27
 
45
- #
46
- # @api private
47
- #
48
-
49
- def keyboard
50
- Keyboard.new @bridge
28
+ def encode
29
+ return nil if no_actions?
30
+ {type: type, id: name, actions: @actions.map(&:encode)}
51
31
  end
52
- end # HasInputDevices
53
- end # DriverExtensions
32
+ end # NoneInput
33
+ end # Interactions
54
34
  end # WebDriver
55
35
  end # Selenium