Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/rb/lib/selenium/webdriver/common/search_context.rb
1865 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 SearchContext
23
# @api private
24
FINDERS = {
25
class: 'class name',
26
class_name: 'class name',
27
css: 'css selector',
28
id: 'id',
29
link: 'link text',
30
link_text: 'link text',
31
name: 'name',
32
partial_link_text: 'partial link text',
33
relative: 'relative',
34
tag_name: 'tag name',
35
xpath: 'xpath'
36
}.freeze
37
38
class << self
39
attr_accessor :extra_finders
40
41
def finders
42
FINDERS.merge(extra_finders || {})
43
end
44
end
45
46
#
47
# Find the first element matching the given arguments
48
#
49
# When using Element#find_element with :xpath, be aware that webdriver
50
# follows standard conventions: a search prefixed with "//" will search
51
# the entire document, not just the children of this current node. Use
52
# ".//" to limit your search to the children of the receiving Element.
53
#
54
# @overload find_element(how, what)
55
# @param [Symbol, String] how The method to find the element by
56
# @param [String] what The locator to use
57
# @overload find_element(opts)
58
# @param [Hash] opts Find options
59
# @option opts [Symbol] :how Key named after the method to find the element by, containing the locator
60
# @return [Element]
61
#
62
# @raise [Error::NoSuchElementError] if the element doesn't exist
63
#
64
65
def find_element(*args)
66
how, what = extract_args(args)
67
68
by = SearchContext.finders[how.to_sym]
69
raise ArgumentError, "cannot find element by #{how.inspect}" unless by
70
71
bridge.find_element_by by, what, ref
72
end
73
74
#
75
# Find all elements matching the given arguments
76
#
77
# @see SearchContext#find_element
78
#
79
80
def find_elements(*args)
81
how, what = extract_args(args)
82
83
by = SearchContext.finders[how.to_sym]
84
raise ArgumentError, "cannot find elements by #{how.inspect}" unless by
85
86
bridge.find_elements_by by, what, ref
87
end
88
89
private
90
91
def extract_args(args)
92
case args.size
93
when 2
94
args
95
when 1
96
arg = args.first
97
98
unless arg.respond_to?(:shift)
99
raise ArgumentError,
100
"expected #{arg.inspect}:#{arg.class} to respond to #shift"
101
end
102
103
# this will be a single-entry hash, so use #shift over #first or #[]
104
arr = arg.dup.shift
105
raise ArgumentError, "expected #{arr.inspect} to have 2 elements" unless arr.size == 2
106
107
arr
108
else
109
raise ArgumentError, "wrong number of arguments (#{args.size} for 2)"
110
end
111
end
112
end # SearchContext
113
end # WebDriver
114
end # Selenium
115
116