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
@@ -304,11 +304,7 @@ module Playwright
|
|
304
304
|
end
|
305
305
|
|
306
306
|
def all
|
307
|
-
|
308
|
-
count.times do |i|
|
309
|
-
out << nth(i)
|
310
|
-
end
|
311
|
-
end
|
307
|
+
count.times.map { |i| nth(i) }
|
312
308
|
end
|
313
309
|
|
314
310
|
def count
|
@@ -446,6 +442,10 @@ module Playwright
|
|
446
442
|
@frame.type(@selector, text, strict: true, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout)
|
447
443
|
end
|
448
444
|
|
445
|
+
def press_sequentially(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
446
|
+
type(text, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout)
|
447
|
+
end
|
448
|
+
|
449
449
|
def uncheck(
|
450
450
|
force: nil,
|
451
451
|
noWaitAfter: nil,
|
@@ -484,5 +484,28 @@ module Playwright
|
|
484
484
|
def highlight
|
485
485
|
@frame.highlight(@selector)
|
486
486
|
end
|
487
|
+
|
488
|
+
def expect(expression, options)
|
489
|
+
if options.key?(:expectedValue)
|
490
|
+
options[:expectedValue] = JavaScript::ValueSerializer
|
491
|
+
.new(options[:expectedValue])
|
492
|
+
.serialize
|
493
|
+
end
|
494
|
+
|
495
|
+
result = @frame.channel.send_message_to_server_result(
|
496
|
+
"expect",
|
497
|
+
{
|
498
|
+
selector: @selector,
|
499
|
+
expression: expression,
|
500
|
+
**options,
|
501
|
+
}
|
502
|
+
)
|
503
|
+
|
504
|
+
if result.key?('received')
|
505
|
+
result['received'] = JavaScript::ValueParser.new(result['received']).parse
|
506
|
+
end
|
507
|
+
|
508
|
+
result
|
509
|
+
end
|
487
510
|
end
|
488
511
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Playwright
|
2
|
+
# this module is responsible for running playwright assertions and integrating
|
3
|
+
# with test frameworks.
|
4
|
+
module Test
|
5
|
+
# ref: https://github.com/microsoft/playwright-python/blob/main/playwright/sync_api/__init__.py#L90
|
6
|
+
class Expect
|
7
|
+
def initialize
|
8
|
+
@timeout_settings = TimeoutSettings.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(actual, message = nil)
|
12
|
+
if actual.is_a?(Locator)
|
13
|
+
LocatorAssertions.new(
|
14
|
+
LocatorAssertionsImpl.new(
|
15
|
+
actual,
|
16
|
+
@timeout_settings.timeout,
|
17
|
+
false,
|
18
|
+
message,
|
19
|
+
)
|
20
|
+
)
|
21
|
+
else
|
22
|
+
raise NotImplementedError.new("Only locator assertions are currently implemented")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module Matchers
|
28
|
+
class PlaywrightMatcher
|
29
|
+
def initialize(expectation_method, *args, **kwargs)
|
30
|
+
@method = expectation_method
|
31
|
+
@args = args
|
32
|
+
@kwargs = kwargs
|
33
|
+
end
|
34
|
+
|
35
|
+
def matches?(actual)
|
36
|
+
Expect.new.call(actual).send(@method, *@args, **@kwargs)
|
37
|
+
true
|
38
|
+
rescue AssertionError => e
|
39
|
+
@failure_message = e.full_message
|
40
|
+
false
|
41
|
+
end
|
42
|
+
|
43
|
+
def failure_message
|
44
|
+
@failure_message
|
45
|
+
end
|
46
|
+
|
47
|
+
# we have to invert the message again here because RSpec wants to control
|
48
|
+
# its own negation
|
49
|
+
def failure_message_when_negated
|
50
|
+
@failure_message.gsub("expected to", "not expected to")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
ALL_ASSERTIONS = LocatorAssertions.instance_methods(false)
|
56
|
+
|
57
|
+
ALL_ASSERTIONS
|
58
|
+
.map(&:to_s)
|
59
|
+
.each do |method_name|
|
60
|
+
# to_be_visible => be_visible
|
61
|
+
# not_to_be_visible => not_be_visible
|
62
|
+
root_method_name = method_name.gsub("to_", "")
|
63
|
+
Matchers.define_method(root_method_name) do |*args, **kwargs|
|
64
|
+
Matchers::PlaywrightMatcher.new(method_name, *args, **kwargs)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/playwright/utils.rb
CHANGED
data/lib/playwright/version.rb
CHANGED
@@ -5,14 +5,17 @@ module Playwright
|
|
5
5
|
# All the downloaded files belonging to the browser context are deleted when the
|
6
6
|
# browser context is closed.
|
7
7
|
#
|
8
|
-
# Download event is emitted once the download starts. Download path becomes available once download completes
|
8
|
+
# Download event is emitted once the download starts. Download path becomes available once download completes.
|
9
9
|
#
|
10
10
|
# ```python sync
|
11
|
+
# # Start waiting for the download
|
11
12
|
# with page.expect_download() as download_info:
|
13
|
+
# # Perform the action that initiates download
|
12
14
|
# page.get_by_text("Download file").click()
|
13
15
|
# download = download_info.value
|
14
|
-
#
|
15
|
-
#
|
16
|
+
#
|
17
|
+
# # Wait for the download process to complete and save the downloaded file somewhere
|
18
|
+
# download.save_as("/path/to/save/at/" + download.suggested_filename)
|
16
19
|
# ```
|
17
20
|
class Download < PlaywrightApi
|
18
21
|
|
@@ -54,6 +57,12 @@ module Playwright
|
|
54
57
|
#
|
55
58
|
# Copy the download to a user-specified path. It is safe to call this method while the download
|
56
59
|
# is still in progress. Will wait for the download to finish if necessary.
|
60
|
+
#
|
61
|
+
# **Usage**
|
62
|
+
#
|
63
|
+
# ```python sync
|
64
|
+
# download.save_as("/path/to/save/at/" + download.suggested_filename)
|
65
|
+
# ```
|
57
66
|
def save_as(path)
|
58
67
|
wrap_impl(@impl.save_as(unwrap_impl(path)))
|
59
68
|
end
|
@@ -224,7 +224,7 @@ module Playwright
|
|
224
224
|
#
|
225
225
|
# If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
226
226
|
#
|
227
|
-
# To send fine-grained keyboard events, use [`method:
|
227
|
+
# To send fine-grained keyboard events, use [`method: Locator.pressSequentially`].
|
228
228
|
def fill(value, force: nil, noWaitAfter: nil, timeout: nil)
|
229
229
|
wrap_impl(@impl.fill(unwrap_impl(value), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
230
230
|
end
|
@@ -503,19 +503,6 @@ module Playwright
|
|
503
503
|
# To press a special key, like `Control` or `ArrowDown`, use [`method: ElementHandle.press`].
|
504
504
|
#
|
505
505
|
# **Usage**
|
506
|
-
#
|
507
|
-
# ```python sync
|
508
|
-
# element_handle.type("hello") # types instantly
|
509
|
-
# element_handle.type("world", delay=100) # types slower, like a user
|
510
|
-
# ```
|
511
|
-
#
|
512
|
-
# An example of typing into a text field and then submitting the form:
|
513
|
-
#
|
514
|
-
# ```python sync
|
515
|
-
# element_handle = page.query_selector("input")
|
516
|
-
# element_handle.type("some text")
|
517
|
-
# element_handle.press("Enter")
|
518
|
-
# ```
|
519
506
|
def type(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
520
507
|
wrap_impl(@impl.type(unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
521
508
|
end
|
data/lib/playwright_api/frame.rb
CHANGED
@@ -300,7 +300,7 @@ module Playwright
|
|
300
300
|
#
|
301
301
|
# If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
302
302
|
#
|
303
|
-
# To send fine-grained keyboard events, use [`method:
|
303
|
+
# To send fine-grained keyboard events, use [`method: Locator.pressSequentially`].
|
304
304
|
def fill(
|
305
305
|
selector,
|
306
306
|
value,
|
@@ -867,11 +867,6 @@ module Playwright
|
|
867
867
|
# To press a special key, like `Control` or `ArrowDown`, use [`method: Keyboard.press`].
|
868
868
|
#
|
869
869
|
# **Usage**
|
870
|
-
#
|
871
|
-
# ```python sync
|
872
|
-
# frame.type("#mytextarea", "hello") # types instantly
|
873
|
-
# frame.type("#mytextarea", "world", delay=100) # types slower, like a user
|
874
|
-
# ```
|
875
870
|
def type(
|
876
871
|
selector,
|
877
872
|
text,
|
@@ -81,6 +81,8 @@ module Playwright
|
|
81
81
|
wrap_impl(@impl.insert_text(unwrap_impl(text)))
|
82
82
|
end
|
83
83
|
|
84
|
+
#
|
85
|
+
# **NOTE**: In most cases, you should use [`method: Locator.press`] instead.
|
84
86
|
#
|
85
87
|
# `key` can specify the intended
|
86
88
|
# [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to
|
@@ -119,6 +121,8 @@ module Playwright
|
|
119
121
|
wrap_impl(@impl.press(unwrap_impl(key), delay: unwrap_impl(delay)))
|
120
122
|
end
|
121
123
|
|
124
|
+
#
|
125
|
+
# **NOTE**: In most cases, you should use [`method: Locator.fill`] instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [`method: Locator.pressSequentially`].
|
122
126
|
#
|
123
127
|
# Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
|
124
128
|
#
|
@@ -391,7 +391,7 @@ module Playwright
|
|
391
391
|
#
|
392
392
|
# If the target element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), the control will be filled instead.
|
393
393
|
#
|
394
|
-
# To send fine-grained keyboard events, use [`method: Locator.
|
394
|
+
# To send fine-grained keyboard events, use [`method: Locator.pressSequentially`].
|
395
395
|
def fill(value, force: nil, noWaitAfter: nil, timeout: nil)
|
396
396
|
wrap_impl(@impl.fill(unwrap_impl(value), force: unwrap_impl(force), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
397
397
|
end
|
@@ -869,6 +869,31 @@ module Playwright
|
|
869
869
|
wrap_impl(@impl.press(unwrap_impl(key), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
870
870
|
end
|
871
871
|
|
872
|
+
#
|
873
|
+
# **NOTE**: In most cases, you should use [`method: Locator.fill`] instead. You only need to press keys one by one if there is special keyboard handling on the page.
|
874
|
+
#
|
875
|
+
# Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
|
876
|
+
#
|
877
|
+
# To press a special key, like `Control` or `ArrowDown`, use [`method: Locator.press`].
|
878
|
+
#
|
879
|
+
# **Usage**
|
880
|
+
#
|
881
|
+
# ```python sync
|
882
|
+
# locator.press_sequentially("hello") # types instantly
|
883
|
+
# locator.press_sequentially("world", delay=100) # types slower, like a user
|
884
|
+
# ```
|
885
|
+
#
|
886
|
+
# An example of typing into a text field and then submitting the form:
|
887
|
+
#
|
888
|
+
# ```python sync
|
889
|
+
# locator = page.get_by_label("Password")
|
890
|
+
# locator.press_sequentially("my password")
|
891
|
+
# locator.press("Enter")
|
892
|
+
# ```
|
893
|
+
def press_sequentially(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
894
|
+
wrap_impl(@impl.press_sequentially(unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
895
|
+
end
|
896
|
+
|
872
897
|
#
|
873
898
|
# Take a screenshot of the element matching the locator.
|
874
899
|
#
|
@@ -1066,27 +1091,12 @@ module Playwright
|
|
1066
1091
|
wrap_impl(@impl.text_content(timeout: unwrap_impl(timeout)))
|
1067
1092
|
end
|
1068
1093
|
|
1069
|
-
#
|
1070
|
-
# **NOTE**: In most cases, you should use [`method: Locator.fill`] instead. You only need to type characters if there is special keyboard handling on the page.
|
1071
1094
|
#
|
1072
1095
|
# Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
|
1073
1096
|
#
|
1074
1097
|
# To press a special key, like `Control` or `ArrowDown`, use [`method: Locator.press`].
|
1075
1098
|
#
|
1076
1099
|
# **Usage**
|
1077
|
-
#
|
1078
|
-
# ```python sync
|
1079
|
-
# element.type("hello") # types instantly
|
1080
|
-
# element.type("world", delay=100) # types slower, like a user
|
1081
|
-
# ```
|
1082
|
-
#
|
1083
|
-
# An example of typing into a text field and then submitting the form:
|
1084
|
-
#
|
1085
|
-
# ```python sync
|
1086
|
-
# element = page.get_by_label("Password")
|
1087
|
-
# element.type("my password")
|
1088
|
-
# element.press("Enter")
|
1089
|
-
# ```
|
1090
1100
|
def type(text, delay: nil, noWaitAfter: nil, timeout: nil)
|
1091
1101
|
wrap_impl(@impl.type(unwrap_impl(text), delay: unwrap_impl(delay), noWaitAfter: unwrap_impl(noWaitAfter), timeout: unwrap_impl(timeout)))
|
1092
1102
|
end
|
@@ -1139,6 +1149,11 @@ module Playwright
|
|
1139
1149
|
wrap_impl(@impl.wait_for(state: unwrap_impl(state), timeout: unwrap_impl(timeout)))
|
1140
1150
|
end
|
1141
1151
|
|
1152
|
+
# @nodoc
|
1153
|
+
def expect(expression, options)
|
1154
|
+
wrap_impl(@impl.expect(unwrap_impl(expression), unwrap_impl(options)))
|
1155
|
+
end
|
1156
|
+
|
1142
1157
|
# @nodoc
|
1143
1158
|
def to_s
|
1144
1159
|
wrap_impl(@impl.to_s)
|