Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/rb/lib/selenium/webdriver/common/interactions/key_actions.rb
1990 views
1
# frozen_string_literal: true
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 key is never released implicitly - either ActionBuilder#key_up(key) or ActionBuilder#release_actions
26
# must be 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
# @overload key_down(key, device: nil)
38
# @param [Symbol, String] key The key to press
39
# @param [Symbol, String] device Optional name of the KeyInput device to press the key on
40
# @overload key_down(element, key, device: nil)
41
# @param [Element] element An optional element to move to first
42
# @param [Symbol, String] key The key to press
43
# @param [Symbol, String] device Optional name of the KeyInput device to press the key on
44
# @return [ActionBuilder] A self reference
45
#
46
47
def key_down(*, device: nil)
48
key_action(*, action: :create_key_down, device: device)
49
end
50
51
#
52
# Performs a key release.
53
# Releasing a non-depressed key will yield undefined behaviour.
54
#
55
# @example Release a key
56
#
57
# driver.action.key_up(:shift).perform
58
#
59
# @example Release a key from an element
60
#
61
# el = driver.find_element(id: "some_id")
62
# driver.action.key_up(el, :alt).perform
63
#
64
# @overload key_up(key, device: nil)
65
# @param [Symbol, String] key The key to press
66
# @param [Symbol, String] device Optional name of the KeyInput device to press the key on
67
# @overload key_up(element, key, device: nil)
68
# @param [Element] element An optional element to move to first
69
# @param [Symbol, String] key The key to release
70
# @param [Symbol, String] device Optional name of the KeyInput device to release the key on
71
# @return [ActionBuilder] A self reference
72
#
73
74
def key_up(*, device: nil)
75
key_action(*, action: :create_key_up, device: device)
76
end
77
78
#
79
# Sends keys to the active element. This differs from calling
80
# Element#send_keys(keys) on the active element in two ways:
81
#
82
# * The modifier keys included in this call are not released.
83
# * There is no attempt to re-focus the element - so send_keys(:tab) for switching elements should work.
84
#
85
# @example Send the text "help" to an element
86
#
87
# el = driver.find_element(id: "some_id")
88
# driver.action.send_keys(el, "help").perform
89
#
90
# @example Send the text "help" to the currently focused element
91
#
92
# driver.action.send_keys("help").perform
93
#
94
# @overload send_keys(keys, device: nil)
95
# @param [Array, Symbol, String] keys The key(s) to press and release
96
# @param [Symbol, String] device Optional name of the KeyInput device to press and release the keys on
97
# @overload send_keys(element, keys, device: nil)
98
# @param [Element] element An optional element to move to first
99
# @param [Array, Symbol, String] keys The key(s) to press and release
100
# @param [Symbol, String] device Optional name of the KeyInput device to press and release the keys on
101
# @return [ActionBuilder] A self reference
102
#
103
104
def send_keys(*args, device: nil)
105
click(args.shift) if args.first.is_a? Element
106
args.map { |x| x.is_a?(String) ? x.chars : x }.flatten.each do |arg|
107
key_down(arg, device: device)
108
key_up(arg, device: device)
109
end
110
self
111
end
112
113
private
114
115
#
116
# @api private
117
#
118
# @overload key_down(key, action: nil, device: nil)
119
# @param [Symbol, String] key The key to press
120
# @param [Symbol] action The name of the key action to perform
121
# @param [Symbol, String] device Optional name of the KeyInput device to press the key on
122
# @overload key_down(element, key, action: nil, device: nil)
123
# @param [Element] element An optional element to move to first
124
# @param [Symbol, String] key The key to press
125
# @param [Symbol] action The name of the key action to perform
126
# @param [Symbol, String] device Optional name of the KeyInput device to press the key on
127
#
128
# @param [Array] args
129
# @option args [Element] element An optional element to move to first
130
# @option args [Symbol, String] key The key to perform the action with
131
# @param [Symbol] action The name of the key action to perform
132
# @param [Symbol, String] device optional name of the KeyInput device to press the key on
133
# @return [ActionBuilder] A self reference
134
#
135
136
def key_action(*args, action: nil, device: nil)
137
key_input = key_input(device)
138
click(args.shift) if args.first.is_a? Element
139
key_input.send(action, args.last)
140
tick(key_input)
141
self
142
end
143
144
def key_input(name = nil)
145
device(name: name, type: Interactions::KEY) || add_key_input('keyboard')
146
end
147
end # KeyActions
148
end # WebDriver
149
end # Selenium
150
151