playwright-ruby-client 1.37.1 → 1.38.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.
- checksums.yaml +4 -4
- data/README.md +13 -7
- data/documentation/docs/api/download.md +17 -7
- data/documentation/docs/api/element_handle.md +1 -14
- data/documentation/docs/api/frame.md +1 -6
- data/documentation/docs/api/keyboard.md +4 -0
- data/documentation/docs/api/locator.md +31 -16
- data/documentation/docs/api/locator_assertions.md +684 -0
- data/documentation/docs/api/page.md +1 -6
- data/documentation/docs/api/request.md +17 -0
- data/documentation/docs/include/api_coverage.md +44 -0
- data/lib/playwright/channel.rb +1 -1
- data/lib/playwright/channel_owners/browser_context.rb +15 -0
- data/lib/playwright/channel_owners/page.rb +2 -0
- data/lib/playwright/channel_owners/request.rb +17 -1
- data/lib/playwright/channel_owners/route.rb +5 -1
- data/lib/playwright/errors.rb +15 -2
- data/lib/playwright/events.rb +1 -0
- data/lib/playwright/javascript/value_parser.rb +8 -0
- data/lib/playwright/javascript/value_serializer.rb +11 -5
- data/lib/playwright/locator_assertions_impl.rb +417 -0
- data/lib/playwright/locator_impl.rb +28 -5
- data/lib/playwright/test.rb +68 -0
- data/lib/playwright/utils.rb +4 -0
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright_api/download.rb +12 -3
- data/lib/playwright_api/element_handle.rb +1 -14
- data/lib/playwright_api/frame.rb +1 -6
- data/lib/playwright_api/keyboard.rb +4 -0
- data/lib/playwright_api/locator.rb +31 -16
- data/lib/playwright_api/locator_assertions.rb +538 -0
- data/lib/playwright_api/page.rb +1 -6
- data/lib/playwright_api/request.rb +17 -0
- data/lib/playwright_api/worker.rb +4 -4
- data/sig/playwright.rbs +44 -0
- metadata +7 -3
@@ -54,6 +54,20 @@ def frame
|
|
54
54
|
|
55
55
|
Returns the [Frame](./frame) that initiated this request.
|
56
56
|
|
57
|
+
**Usage**
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
frame_url = request.frame.url
|
61
|
+
```
|
62
|
+
|
63
|
+
**Details**
|
64
|
+
|
65
|
+
Note that in some cases the frame is not available, and this method will throw.
|
66
|
+
- When request originates in the Service Worker. You can use `request.serviceWorker()` to check that.
|
67
|
+
- When navigation request is issued before the corresponding frame is created. You can use [Request#navigation_request?](./request#navigation_request?) to check that.
|
68
|
+
|
69
|
+
Here is an example that handles all the cases:
|
70
|
+
|
57
71
|
## headers
|
58
72
|
|
59
73
|
```
|
@@ -93,6 +107,9 @@ def navigation_request?
|
|
93
107
|
|
94
108
|
Whether this request is driving frame's navigation.
|
95
109
|
|
110
|
+
Some navigation requests are issued before the corresponding frame is created, and therefore
|
111
|
+
do not have [Request#frame](./request#frame) available.
|
112
|
+
|
96
113
|
## method
|
97
114
|
|
98
115
|
```
|
@@ -470,6 +470,7 @@
|
|
470
470
|
* or
|
471
471
|
* page
|
472
472
|
* press
|
473
|
+
* press_sequentially
|
473
474
|
* screenshot
|
474
475
|
* scroll_into_view_if_needed
|
475
476
|
* select_option
|
@@ -526,6 +527,49 @@
|
|
526
527
|
|
527
528
|
* ~~new_context~~
|
528
529
|
|
530
|
+
## LocatorAssertions
|
531
|
+
|
532
|
+
* not_to_be_attached
|
533
|
+
* not_to_be_checked
|
534
|
+
* not_to_be_disabled
|
535
|
+
* not_to_be_editable
|
536
|
+
* not_to_be_empty
|
537
|
+
* not_to_be_enabled
|
538
|
+
* not_to_be_focused
|
539
|
+
* not_to_be_hidden
|
540
|
+
* not_to_be_in_viewport
|
541
|
+
* not_to_be_visible
|
542
|
+
* not_to_contain_text
|
543
|
+
* not_to_have_attribute
|
544
|
+
* not_to_have_class
|
545
|
+
* not_to_have_count
|
546
|
+
* not_to_have_css
|
547
|
+
* not_to_have_id
|
548
|
+
* not_to_have_js_property
|
549
|
+
* not_to_have_text
|
550
|
+
* not_to_have_value
|
551
|
+
* not_to_have_values
|
552
|
+
* to_be_attached
|
553
|
+
* to_be_checked
|
554
|
+
* to_be_disabled
|
555
|
+
* to_be_editable
|
556
|
+
* to_be_empty
|
557
|
+
* to_be_enabled
|
558
|
+
* to_be_focused
|
559
|
+
* to_be_hidden
|
560
|
+
* to_be_in_viewport
|
561
|
+
* to_be_visible
|
562
|
+
* to_contain_text
|
563
|
+
* to_have_attribute
|
564
|
+
* to_have_class
|
565
|
+
* to_have_count
|
566
|
+
* to_have_css
|
567
|
+
* to_have_id
|
568
|
+
* to_have_js_property
|
569
|
+
* to_have_text
|
570
|
+
* to_have_value
|
571
|
+
* to_have_values
|
572
|
+
|
529
573
|
## Android
|
530
574
|
|
531
575
|
* ~~connect~~
|
data/lib/playwright/channel.rb
CHANGED
@@ -46,7 +46,7 @@ module Playwright
|
|
46
46
|
|
47
47
|
private def with_logging(&block)
|
48
48
|
locations = caller_locations
|
49
|
-
first_api_call_location_idx = locations.index { |loc| loc.absolute_path
|
49
|
+
first_api_call_location_idx = locations.index { |loc| loc.absolute_path&.include?('playwright_api') }
|
50
50
|
unless first_api_call_location_idx
|
51
51
|
return block.call(nil)
|
52
52
|
end
|
@@ -38,6 +38,12 @@ module Playwright
|
|
38
38
|
@channel.on('console', ->(params) {
|
39
39
|
on_console_message(ChannelOwners::ConsoleMessage.from(params['message']))
|
40
40
|
})
|
41
|
+
@channel.on('pageError', ->(params) {
|
42
|
+
on_page_error(
|
43
|
+
Error.parse(params['error']['error']),
|
44
|
+
ChannelOwners::Page.from_nullable(params['page']),
|
45
|
+
)
|
46
|
+
})
|
41
47
|
@channel.on('dialog', ->(params) {
|
42
48
|
on_dialog(ChannelOwners::Dialog.from(params['dialog']))
|
43
49
|
})
|
@@ -97,6 +103,8 @@ module Playwright
|
|
97
103
|
end
|
98
104
|
|
99
105
|
private def on_route(route)
|
106
|
+
route.send(:update_context, self)
|
107
|
+
|
100
108
|
# It is not desired to use PlaywrightApi.wrap directly.
|
101
109
|
# However it is a little difficult to define wrapper for `handler` parameter in generate_api.
|
102
110
|
# Just a workaround...
|
@@ -177,6 +185,13 @@ module Playwright
|
|
177
185
|
end
|
178
186
|
end
|
179
187
|
|
188
|
+
private def on_page_error(error, page)
|
189
|
+
emit(Events::BrowserContext::WebError, WebError.new(error, page))
|
190
|
+
if page
|
191
|
+
page.emit(Events::Page::PageError, error)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
180
195
|
private def on_request(request, page)
|
181
196
|
emit(Events::BrowserContext::Request, request)
|
182
197
|
page&.emit(Events::Page::Request, request)
|
@@ -96,6 +96,8 @@ module Playwright
|
|
96
96
|
end
|
97
97
|
|
98
98
|
private def on_route(route)
|
99
|
+
route.send(:update_context, self)
|
100
|
+
|
99
101
|
# It is not desired to use PlaywrightApi.wrap directly.
|
100
102
|
# However it is a little difficult to define wrapper for `handler` parameter in generate_api.
|
101
103
|
# Just a workaround...
|
@@ -86,8 +86,24 @@ module Playwright
|
|
86
86
|
ChannelOwners::Response.from_nullable(resp)
|
87
87
|
end
|
88
88
|
|
89
|
+
class FramePageNotReadyError < StandardError
|
90
|
+
MESSAGE = [
|
91
|
+
'Frame for this navigation request is not available, because the request',
|
92
|
+
'was issued before the frame is created. You can check whether the request',
|
93
|
+
'is a navigation request by calling isNavigationRequest() method.',
|
94
|
+
].join('\n').freeze
|
95
|
+
|
96
|
+
def initialize
|
97
|
+
super(MESSAGE)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
89
101
|
def frame
|
90
|
-
ChannelOwners::Frame.from(@initializer['frame'])
|
102
|
+
ChannelOwners::Frame.from(@initializer['frame']).tap do |result|
|
103
|
+
unless result.page
|
104
|
+
raise FramePageNotReadyError.new
|
105
|
+
end
|
106
|
+
end
|
91
107
|
end
|
92
108
|
|
93
109
|
def navigation_request?
|
@@ -111,7 +111,7 @@ module Playwright
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def fetch(headers: nil, method: nil, postData: nil, url: nil, maxRedirects: nil, timeout: nil)
|
114
|
-
api_request_context =
|
114
|
+
api_request_context = @context.request
|
115
115
|
api_request_context.send(:_inner_fetch,
|
116
116
|
request,
|
117
117
|
url,
|
@@ -172,5 +172,9 @@ module Playwright
|
|
172
172
|
mime_types = MIME::Types.type_for(filepath)
|
173
173
|
mime_types.first.to_s || 'application/octet-stream'
|
174
174
|
end
|
175
|
+
|
176
|
+
private def update_context(context)
|
177
|
+
@context = context
|
178
|
+
end
|
175
179
|
end
|
176
180
|
end
|
data/lib/playwright/errors.rb
CHANGED
@@ -5,13 +5,13 @@ module Playwright
|
|
5
5
|
if error_payload['name'] == 'TimeoutError'
|
6
6
|
TimeoutError.new(
|
7
7
|
message: error_payload['message'],
|
8
|
-
stack: error_payload['stack']
|
8
|
+
stack: error_payload['stack'],
|
9
9
|
)
|
10
10
|
else
|
11
11
|
new(
|
12
12
|
name: error_payload['name'],
|
13
13
|
message: error_payload['message'],
|
14
|
-
stack: error_payload['stack']
|
14
|
+
stack: error_payload['stack'],
|
15
15
|
)
|
16
16
|
end
|
17
17
|
end
|
@@ -25,6 +25,8 @@ module Playwright
|
|
25
25
|
@message = message
|
26
26
|
@stack = stack
|
27
27
|
end
|
28
|
+
|
29
|
+
attr_reader :name, :message, :stack
|
28
30
|
end
|
29
31
|
|
30
32
|
class DriverCrashedError < StandardError
|
@@ -38,4 +40,15 @@ module Playwright
|
|
38
40
|
super(name: 'TimeoutError', message: message, stack: stack)
|
39
41
|
end
|
40
42
|
end
|
43
|
+
|
44
|
+
class WebError
|
45
|
+
def initialize(error, page)
|
46
|
+
@error = error
|
47
|
+
@page = PlaywrightApi.wrap(page)
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_reader :error, :page
|
51
|
+
end
|
52
|
+
|
53
|
+
class AssertionError < StandardError; end
|
41
54
|
end
|
data/lib/playwright/events.rb
CHANGED
@@ -56,6 +56,14 @@ module Playwright
|
|
56
56
|
return hash['bi'].to_i
|
57
57
|
end
|
58
58
|
|
59
|
+
if hash.key?('m')
|
60
|
+
return parse_hash(hash['m']).to_h
|
61
|
+
end
|
62
|
+
|
63
|
+
if hash.key?('se')
|
64
|
+
return Set.new(parse_hash(hash['se']))
|
65
|
+
end
|
66
|
+
|
59
67
|
if hash.key?('r')
|
60
68
|
# @see https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp
|
61
69
|
# @see https://docs.ruby-lang.org/ja/latest/class/Regexp.html
|
@@ -24,7 +24,7 @@ module Playwright
|
|
24
24
|
@handles << value.channel
|
25
25
|
{ h: index }
|
26
26
|
when nil
|
27
|
-
{ v: '
|
27
|
+
{ v: 'null' }
|
28
28
|
when Float::NAN
|
29
29
|
{ v: 'NaN'}
|
30
30
|
when Float::INFINITY
|
@@ -56,11 +56,17 @@ module Playwright
|
|
56
56
|
result = []
|
57
57
|
value.each { |v| result << serialize_value(v) }
|
58
58
|
{ a: result, id: id }
|
59
|
+
when Set
|
60
|
+
{ se: serialize_value(value.to_a) }
|
59
61
|
when Hash
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
if value.any? { |k, v| !k.is_a?(String) && !k.is_a?(Symbol) } # Map
|
63
|
+
{ m: serialize_value(value.to_a) }
|
64
|
+
else
|
65
|
+
id = @visited.log(value)
|
66
|
+
result = []
|
67
|
+
value.each { |key, v| result << { k: key, v: serialize_value(v) } }
|
68
|
+
{ o: result, id: id }
|
69
|
+
end
|
64
70
|
else
|
65
71
|
raise ArgumentError.new("Unexpected value: #{value}")
|
66
72
|
end
|
@@ -0,0 +1,417 @@
|
|
1
|
+
module Playwright
|
2
|
+
# ref: https://github.com/microsoft/playwright-python/blob/main/playwright/_impl/_assertions.py
|
3
|
+
define_api_implementation :LocatorAssertionsImpl do
|
4
|
+
def self._define_negation(method_name)
|
5
|
+
define_method("not_#{method_name}") do |*args, **kwargs|
|
6
|
+
if kwargs.empty? # for Ruby < 2.7
|
7
|
+
_not.public_send(method_name, *args)
|
8
|
+
else
|
9
|
+
_not.public_send(method_name, *args, **kwargs)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(locator, timeout, is_not, message)
|
15
|
+
@locator = locator
|
16
|
+
@timeout = timeout
|
17
|
+
@is_not = is_not
|
18
|
+
@custom_message = message
|
19
|
+
end
|
20
|
+
|
21
|
+
private def expect_impl(expression, expect_options, expected, message)
|
22
|
+
expect_options[:timeout] ||= 5000
|
23
|
+
expect_options[:isNot] = @is_not
|
24
|
+
message.gsub!("expected to", "not expected to") if @is_not
|
25
|
+
expect_options.delete(:useInnerText) if expect_options.key?(:useInnerText) && expect_options[:useInnerText].nil?
|
26
|
+
|
27
|
+
result = @locator.expect(expression, expect_options)
|
28
|
+
|
29
|
+
if result["matches"] == @is_not
|
30
|
+
actual = result["received"]
|
31
|
+
|
32
|
+
log =
|
33
|
+
if result.key?("log")
|
34
|
+
log_contents = result["log"].join("\n").strip
|
35
|
+
|
36
|
+
"\nCall log:\n #{log_contents}"
|
37
|
+
else
|
38
|
+
""
|
39
|
+
end
|
40
|
+
|
41
|
+
out_message =
|
42
|
+
if @custom_message && expected
|
43
|
+
"\nExpected value: '#{expected}'"
|
44
|
+
elsif @custom_message
|
45
|
+
@custom_message
|
46
|
+
elsif message != "" && expected
|
47
|
+
"\n#{message} '#{expected}'"
|
48
|
+
else
|
49
|
+
"\n#{message}"
|
50
|
+
end
|
51
|
+
|
52
|
+
out = "#{out_message}\nActual value #{actual} #{log}"
|
53
|
+
raise AssertionError.new(out)
|
54
|
+
else
|
55
|
+
true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private def _not # "not" is reserved in Ruby
|
60
|
+
LocatorAssertionsImpl.new(
|
61
|
+
@locator,
|
62
|
+
@timeout,
|
63
|
+
!@is_not,
|
64
|
+
@message
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
private def expected_regex(pattern, match_substring, normalize_white_space, ignore_case)
|
69
|
+
regex = JavaScript::Regex.new(pattern)
|
70
|
+
expected = {
|
71
|
+
regexSource: regex.source,
|
72
|
+
regexFlags: regex.flag,
|
73
|
+
matchSubstring: match_substring,
|
74
|
+
normalizeWhiteSpace: normalize_white_space,
|
75
|
+
ignoreCase: ignore_case
|
76
|
+
}
|
77
|
+
expected.delete(:ignoreCase) if ignore_case.nil?
|
78
|
+
|
79
|
+
expected
|
80
|
+
end
|
81
|
+
|
82
|
+
private def to_expected_text_values(items, match_substring = false, normalize_white_space = false, ignore_case = false)
|
83
|
+
return [] unless items.respond_to?(:each)
|
84
|
+
|
85
|
+
items.each.with_object([]) do |item, out|
|
86
|
+
out <<
|
87
|
+
if item.is_a?(String) && ignore_case
|
88
|
+
{
|
89
|
+
string: item,
|
90
|
+
matchSubstring: match_substring,
|
91
|
+
normalizeWhiteSpace: normalize_white_space,
|
92
|
+
ignoreCase: ignore_case,
|
93
|
+
}
|
94
|
+
elsif item.is_a?(String)
|
95
|
+
{
|
96
|
+
string: item,
|
97
|
+
matchSubstring: match_substring,
|
98
|
+
normalizeWhiteSpace: normalize_white_space,
|
99
|
+
}
|
100
|
+
elsif item.is_a?(Regexp)
|
101
|
+
expected_regex(item, match_substring, normalize_white_space, ignore_case)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_contain_text(expected, ignoreCase: nil, timeout: nil, useInnerText: nil)
|
107
|
+
useInnerText = false if useInnerText.nil?
|
108
|
+
|
109
|
+
if expected.respond_to?(:each)
|
110
|
+
expected_text = to_expected_text_values(
|
111
|
+
expected,
|
112
|
+
true,
|
113
|
+
true,
|
114
|
+
ignoreCase,
|
115
|
+
)
|
116
|
+
|
117
|
+
expect_impl(
|
118
|
+
"to.contain.text.array",
|
119
|
+
{
|
120
|
+
expectedText: expected_text,
|
121
|
+
useInnerText: useInnerText,
|
122
|
+
timeout: timeout,
|
123
|
+
},
|
124
|
+
expected,
|
125
|
+
"Locator expected to contain text"
|
126
|
+
)
|
127
|
+
else
|
128
|
+
expected_text = to_expected_text_values(
|
129
|
+
[expected],
|
130
|
+
true,
|
131
|
+
true,
|
132
|
+
ignoreCase
|
133
|
+
)
|
134
|
+
|
135
|
+
expect_impl(
|
136
|
+
"to.have.text",
|
137
|
+
{
|
138
|
+
expectedText: expected_text,
|
139
|
+
useInnerText: useInnerText,
|
140
|
+
timeout: timeout,
|
141
|
+
},
|
142
|
+
expected,
|
143
|
+
"Locator expected to contain text"
|
144
|
+
)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
_define_negation :to_contain_text
|
148
|
+
|
149
|
+
def to_have_attribute(name, value, timeout: nil)
|
150
|
+
expected_text = to_expected_text_values([value])
|
151
|
+
expect_impl(
|
152
|
+
"to.have.attribute.value",
|
153
|
+
{
|
154
|
+
expressionArg: name,
|
155
|
+
expectedText: expected_text,
|
156
|
+
timeout: timeout,
|
157
|
+
},
|
158
|
+
value,
|
159
|
+
"Locator expected to have attribute"
|
160
|
+
)
|
161
|
+
end
|
162
|
+
_define_negation :to_have_attribute
|
163
|
+
|
164
|
+
def to_have_class(expected, timeout: nil)
|
165
|
+
if expected.respond_to?(:each)
|
166
|
+
expected_text = to_expected_text_values(expected)
|
167
|
+
expect_impl(
|
168
|
+
"to.have.class.array",
|
169
|
+
{
|
170
|
+
expectedText: expected_text,
|
171
|
+
timeout: timeout,
|
172
|
+
},
|
173
|
+
expected,
|
174
|
+
"Locator expected to have class"
|
175
|
+
)
|
176
|
+
else
|
177
|
+
expected_text = to_expected_text_values([expected])
|
178
|
+
expect_impl(
|
179
|
+
"to.have.class",
|
180
|
+
{
|
181
|
+
expectedText: expected_text,
|
182
|
+
timeout: timeout,
|
183
|
+
},
|
184
|
+
expected,
|
185
|
+
"Locator expected to have class"
|
186
|
+
)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
_define_negation :to_have_class
|
190
|
+
|
191
|
+
def to_have_count(count, timeout: nil)
|
192
|
+
expect_impl(
|
193
|
+
"to.have.count",
|
194
|
+
{
|
195
|
+
expectedNumber: count,
|
196
|
+
timeout: timeout,
|
197
|
+
},
|
198
|
+
count,
|
199
|
+
"Locator expected to have count"
|
200
|
+
)
|
201
|
+
end
|
202
|
+
_define_negation :to_have_count
|
203
|
+
|
204
|
+
def to_have_css(name, value, timeout: nil)
|
205
|
+
expected_text = to_expected_text_values([value])
|
206
|
+
expect_impl(
|
207
|
+
"to.have.css",
|
208
|
+
{
|
209
|
+
expressionArg: name,
|
210
|
+
expectedText: expected_text,
|
211
|
+
timeout: timeout,
|
212
|
+
},
|
213
|
+
value,
|
214
|
+
"Locator expected to have CSS"
|
215
|
+
)
|
216
|
+
end
|
217
|
+
_define_negation :to_have_css
|
218
|
+
|
219
|
+
def to_have_id(id, timeout: nil)
|
220
|
+
expected_text = to_expected_text_values([id])
|
221
|
+
expect_impl(
|
222
|
+
"to.have.id",
|
223
|
+
{
|
224
|
+
expectedText: expected_text,
|
225
|
+
timeout: timeout,
|
226
|
+
},
|
227
|
+
id,
|
228
|
+
"Locator expected to have ID"
|
229
|
+
)
|
230
|
+
end
|
231
|
+
_define_negation :to_have_id
|
232
|
+
|
233
|
+
def to_have_js_property(name, value, timeout: nil)
|
234
|
+
expect_impl(
|
235
|
+
"to.have.property",
|
236
|
+
{
|
237
|
+
expressionArg: name,
|
238
|
+
expectedValue: value,
|
239
|
+
timeout: timeout,
|
240
|
+
},
|
241
|
+
value,
|
242
|
+
"Locator expected to have JS Property"
|
243
|
+
)
|
244
|
+
end
|
245
|
+
_define_negation :to_have_js_property
|
246
|
+
|
247
|
+
def to_have_value(value, timeout: nil)
|
248
|
+
expected_text = to_expected_text_values([value])
|
249
|
+
|
250
|
+
expect_impl(
|
251
|
+
"to.have.value",
|
252
|
+
{
|
253
|
+
expectedText: expected_text,
|
254
|
+
timeout: timeout,
|
255
|
+
},
|
256
|
+
value,
|
257
|
+
"Locator expected to have Value"
|
258
|
+
)
|
259
|
+
end
|
260
|
+
_define_negation :to_have_value
|
261
|
+
|
262
|
+
def to_have_values(values, timeout: nil)
|
263
|
+
expected_text = to_expected_text_values(values)
|
264
|
+
|
265
|
+
expect_impl(
|
266
|
+
"to.have.values",
|
267
|
+
{
|
268
|
+
expectedText: expected_text,
|
269
|
+
timeout: timeout,
|
270
|
+
},
|
271
|
+
values,
|
272
|
+
"Locator expected to have Values"
|
273
|
+
)
|
274
|
+
end
|
275
|
+
_define_negation :to_have_values
|
276
|
+
|
277
|
+
def to_have_text(expected, ignoreCase: nil, timeout: nil, useInnerText: nil)
|
278
|
+
if expected.respond_to?(:each)
|
279
|
+
expected_text = to_expected_text_values(
|
280
|
+
expected,
|
281
|
+
true,
|
282
|
+
true,
|
283
|
+
ignoreCase,
|
284
|
+
)
|
285
|
+
expect_impl(
|
286
|
+
"to.have.text.array",
|
287
|
+
{
|
288
|
+
expectedText: expected_text,
|
289
|
+
useInnerText: useInnerText,
|
290
|
+
timeout: timeout,
|
291
|
+
},
|
292
|
+
expected,
|
293
|
+
"Locator expected to have text"
|
294
|
+
)
|
295
|
+
else
|
296
|
+
expected_text = to_expected_text_values(
|
297
|
+
[expected],
|
298
|
+
true,
|
299
|
+
true,
|
300
|
+
ignoreCase,
|
301
|
+
)
|
302
|
+
expect_impl(
|
303
|
+
"to.have.text",
|
304
|
+
{
|
305
|
+
expectedText: expected_text,
|
306
|
+
useInnerText: useInnerText,
|
307
|
+
timeout: timeout,
|
308
|
+
},
|
309
|
+
expected,
|
310
|
+
"Locator expected to have text"
|
311
|
+
)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
_define_negation :to_have_text
|
315
|
+
|
316
|
+
def to_be_attached(attached: nil, timeout: nil)
|
317
|
+
expect_impl(
|
318
|
+
(attached || attached.nil?) ? "to.be.attached" : "to.be.detached",
|
319
|
+
{ timeout: timeout },
|
320
|
+
nil,
|
321
|
+
"Locator expected to be attached"
|
322
|
+
)
|
323
|
+
end
|
324
|
+
_define_negation :to_be_attached
|
325
|
+
|
326
|
+
def to_be_checked(checked: nil, timeout: nil)
|
327
|
+
expect_impl(
|
328
|
+
(checked || checked.nil?) ? "to.be.checked" : "to.be.unchecked",
|
329
|
+
{ timeout: timeout },
|
330
|
+
nil,
|
331
|
+
"Locator expected to be checked"
|
332
|
+
)
|
333
|
+
end
|
334
|
+
_define_negation :to_be_checked
|
335
|
+
|
336
|
+
def to_be_disabled(timeout: nil)
|
337
|
+
expect_impl(
|
338
|
+
"to.be.disabled",
|
339
|
+
{ timeout: timeout },
|
340
|
+
nil,
|
341
|
+
"Locator expected to be disabled"
|
342
|
+
)
|
343
|
+
end
|
344
|
+
_define_negation :to_be_disabled
|
345
|
+
|
346
|
+
def to_be_editable(editable: nil, timeout: nil)
|
347
|
+
expect_impl(
|
348
|
+
(editable || editable.nil?) ? "to.be.editable" : "to.be.readonly",
|
349
|
+
{ timeout: timeout },
|
350
|
+
nil,
|
351
|
+
"Locator expected to be editable"
|
352
|
+
)
|
353
|
+
end
|
354
|
+
_define_negation :to_be_editable
|
355
|
+
|
356
|
+
def to_be_empty(timeout: nil)
|
357
|
+
expect_impl(
|
358
|
+
"to.be.empty",
|
359
|
+
{ timeout: timeout },
|
360
|
+
nil,
|
361
|
+
"Locator expected to be empty"
|
362
|
+
)
|
363
|
+
end
|
364
|
+
_define_negation :to_be_empty
|
365
|
+
|
366
|
+
def to_be_enabled(enabled: nil, timeout: nil)
|
367
|
+
expect_impl(
|
368
|
+
(enabled || enabled.nil?) ? "to.be.enabled" : "to.be.disabled",
|
369
|
+
{ timeout: timeout },
|
370
|
+
nil,
|
371
|
+
"Locator expected to be enabled"
|
372
|
+
)
|
373
|
+
end
|
374
|
+
_define_negation :to_be_enabled
|
375
|
+
|
376
|
+
def to_be_hidden(timeout: nil)
|
377
|
+
expect_impl(
|
378
|
+
"to.be.hidden",
|
379
|
+
{ timeout: timeout },
|
380
|
+
nil,
|
381
|
+
"Locator expected to be hidden"
|
382
|
+
)
|
383
|
+
end
|
384
|
+
_define_negation :to_be_hidden
|
385
|
+
|
386
|
+
def to_be_visible(timeout: nil, visible: nil)
|
387
|
+
expect_impl(
|
388
|
+
(visible || visible.nil?) ? "to.be.visible" : "to.be.hidden",
|
389
|
+
{ timeout: timeout },
|
390
|
+
nil,
|
391
|
+
"Locator expected to be visible"
|
392
|
+
)
|
393
|
+
end
|
394
|
+
_define_negation :to_be_visible
|
395
|
+
|
396
|
+
def to_be_focused(timeout: nil)
|
397
|
+
expect_impl(
|
398
|
+
"to.be.focused",
|
399
|
+
{ timeout: timeout },
|
400
|
+
nil,
|
401
|
+
"Locator expected to be focused"
|
402
|
+
)
|
403
|
+
end
|
404
|
+
_define_negation :to_be_focused
|
405
|
+
|
406
|
+
def to_be_in_viewport(ratio: nil, timeout: nil)
|
407
|
+
expect_impl(
|
408
|
+
"to.be.in.viewport",
|
409
|
+
{ timeout: timeout, expectedNumber: ratio },
|
410
|
+
nil,
|
411
|
+
"Locator expected to be in viewport"
|
412
|
+
)
|
413
|
+
end
|
414
|
+
_define_negation :to_be_in_viewport
|
415
|
+
|
416
|
+
end
|
417
|
+
end
|