playwright-ruby-client 1.37.1 → 1.38.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00d50bbadac84d3bfa4881ee450991e7e0999c9ca5daab2343bceb885d90522b
4
- data.tar.gz: 16bfdd05cc45587c02a89a9e9098c32a518c3e6b81e254524393e71b47483391
3
+ metadata.gz: 421d718c0a7b5e649fe2632e9f193ef66722149f63a52ba0c1baa63252a0b99d
4
+ data.tar.gz: 0fb410e0d38bff1cd589afa3499ac3938c1897220be2a7c9ebcf7bddfa4c157c
5
5
  SHA512:
6
- metadata.gz: 4e936a99c032fb86e7865cc8880c6679a23b2d621624a98b31d528a7c9d9886851b02b6cb9bab43937bf85b85a2d27ee2cbb0d15d25a11f2962066991531eac0
7
- data.tar.gz: 5e3c6c5bf4af0df7129d6c5ed1ebd6b29928ed68b10b698eb3385ac414c3a04a7ec4a96b964feffa6a65e2f96a7821c3dea8e5b841d186312a66ec1ad53ad825
6
+ metadata.gz: da207f741063627b79efb045adff0af67c935926f30cc5086da9fcf2ccf80555c2f449dc57b2cd953d939c0117ed4f6050c93c8ad35a3d9e654b0141d75e1c53
7
+ data.tar.gz: eac5d5f995949b5e6e925016e2f0ab3ad4dd6c92766e8204023fa84f1a2b50d157659f9bdbb1fcac6500fae64752632b3ed3dfcd6fb042c07706f3ce30c00b48
data/README.md CHANGED
@@ -51,18 +51,24 @@ Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwrigh
51
51
  page = browser.new_page
52
52
  page.goto('https://github.com/')
53
53
 
54
- form = page.query_selector("form.js-site-search-form")
55
- search_input = form.query_selector("input.header-search-input")
56
- search_input.click
54
+ page.get_by_placeholder("Search or jump to...").click
55
+ page.locator('input[name="query-builder-test"]').click
56
+
57
+ expect(page.keyboard).to be_a(::Playwright::Keyboard)
58
+
57
59
  page.keyboard.type("playwright")
58
60
  page.expect_navigation {
59
61
  page.keyboard.press("Enter")
60
62
  }
61
63
 
62
- list = page.query_selector("ul.repo-list")
63
- items = list.query_selector_all("div.f4")
64
- items.each do |item|
65
- title = item.eval_on_selector("a", "a => a.innerText")
64
+ list = page.get_by_test_id('results-list').locator('.search-title')
65
+
66
+ # wait for item to appear
67
+ list.first.wait_for
68
+
69
+ # list them
70
+ list.locator('.search-title').all.each do |item|
71
+ title = item.text_content
66
72
  puts("==> #{title}")
67
73
  end
68
74
  end
@@ -10,15 +10,18 @@ sidebar_position: 10
10
10
  All the downloaded files belonging to the browser context are deleted when the
11
11
  browser context is closed.
12
12
 
13
- Download event is emitted once the download starts. Download path becomes available once download completes:
13
+ Download event is emitted once the download starts. Download path becomes available once download completes.
14
14
 
15
- ```ruby
16
- download = page.expect_download do
17
- page.get_by_text("Download file").click
18
- end
15
+ ```python sync title=example_c247767083cf193df26a39a61a3a8bc19d63ed5c24db91b88c50b7d37975005d.py
16
+ # Start waiting for the download
17
+ with page.expect_download() as download_info:
18
+ # Perform the action that initiates download
19
+ page.get_by_text("Download file").click()
20
+ download = download_info.value
21
+
22
+ # Wait for the download process to complete and save the downloaded file somewhere
23
+ download.save_as("/path/to/save/at/" + download.suggested_filename)
19
24
 
20
- # wait for download to complete
21
- path = download.path
22
25
  ```
23
26
 
24
27
  ## cancel
@@ -81,6 +84,13 @@ def save_as(path)
81
84
  Copy the download to a user-specified path. It is safe to call this method while the download
82
85
  is still in progress. Will wait for the download to finish if necessary.
83
86
 
87
+ **Usage**
88
+
89
+ ```python sync title=example_66ffd4ef7286957e4294d84b8f660ff852c87af27a56b3e4dd9f84562b5ece02.py
90
+ download.save_as("/path/to/save/at/" + download.suggested_filename)
91
+
92
+ ```
93
+
84
94
  ## suggested_filename
85
95
 
86
96
  ```
@@ -259,7 +259,7 @@ This method waits for [actionability](https://playwright.dev/python/docs/actiona
259
259
 
260
260
  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.
261
261
 
262
- To send fine-grained keyboard events, use [ElementHandle#type](./element_handle#type).
262
+ To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
263
263
 
264
264
  ## focus
265
265
 
@@ -614,19 +614,6 @@ To press a special key, like `Control` or `ArrowDown`, use [ElementHandle#press]
614
614
 
615
615
  **Usage**
616
616
 
617
- ```ruby
618
- element_handle.type("hello") # types instantly
619
- element_handle.type("world", delay: 100) # types slower, like a user
620
- ```
621
-
622
- An example of typing into a text field and then submitting the form:
623
-
624
- ```ruby
625
- element_handle = page.query_selector("input")
626
- element_handle.type("some text")
627
- element_handle.press("Enter")
628
- ```
629
-
630
617
  ## uncheck
631
618
 
632
619
  ```
@@ -349,7 +349,7 @@ This method waits for an element matching `selector`, waits for [actionability](
349
349
 
350
350
  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.
351
351
 
352
- To send fine-grained keyboard events, use [Frame#type](./frame#type).
352
+ To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
353
353
 
354
354
  ## focus
355
355
 
@@ -1041,11 +1041,6 @@ To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./ke
1041
1041
 
1042
1042
  **Usage**
1043
1043
 
1044
- ```ruby
1045
- frame.type("#mytextarea", "hello") # types instantly
1046
- frame.type("#mytextarea", "world", delay: 100) # types slower, like a user
1047
- ```
1048
-
1049
1044
  ## uncheck
1050
1045
 
1051
1046
  ```
@@ -97,6 +97,8 @@ def press(key, delay: nil)
97
97
  ```
98
98
 
99
99
 
100
+ **NOTE**: In most cases, you should use [Locator#press](./locator#press) instead.
101
+
100
102
  `key` can specify the intended
101
103
  [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to
102
104
  generate the text for. A superset of the `key` values can be found
@@ -136,6 +138,8 @@ def type(text, delay: nil)
136
138
  ```
137
139
 
138
140
 
141
+ **NOTE**: In most cases, you should use [Locator#fill](./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 [Locator#press_sequentially](./locator#press_sequentially).
142
+
139
143
  Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
140
144
 
141
145
  To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./keyboard#press).
@@ -458,7 +458,7 @@ This method waits for [actionability](https://playwright.dev/python/docs/actiona
458
458
 
459
459
  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.
460
460
 
461
- To send fine-grained keyboard events, use [Locator#type](./locator#type).
461
+ To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
462
462
 
463
463
  ## filter
464
464
 
@@ -1032,6 +1032,36 @@ respective texts.
1032
1032
  Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported as well. When specified with the
1033
1033
  modifier, modifier is pressed and being held while the subsequent key is being pressed.
1034
1034
 
1035
+ ## press_sequentially
1036
+
1037
+ ```
1038
+ def press_sequentially(text, delay: nil, noWaitAfter: nil, timeout: nil)
1039
+ ```
1040
+
1041
+
1042
+ **NOTE**: In most cases, you should use [Locator#fill](./locator#fill) instead. You only need to press keys one by one if there is special keyboard handling on the page.
1043
+
1044
+ Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
1045
+
1046
+ To press a special key, like `Control` or `ArrowDown`, use [Locator#press](./locator#press).
1047
+
1048
+ **Usage**
1049
+
1050
+ ```python sync title=example_1b7781d5527574a18d4b9812e3461203d2acc9ba7e09cbfd0ffbc4154e3f5971.py
1051
+ locator.press_sequentially("hello") # types instantly
1052
+ locator.press_sequentially("world", delay=100) # types slower, like a user
1053
+
1054
+ ```
1055
+
1056
+ An example of typing into a text field and then submitting the form:
1057
+
1058
+ ```python sync title=example_cc0a6b9aa95b97e5c17c4b114da10a29c7f6f793e99aee1ea2703636af6e24f9.py
1059
+ locator = page.get_by_label("Password")
1060
+ locator.press_sequentially("my password")
1061
+ locator.press("Enter")
1062
+
1063
+ ```
1064
+
1035
1065
  ## screenshot
1036
1066
 
1037
1067
  ```
@@ -1254,27 +1284,12 @@ def type(text, delay: nil, noWaitAfter: nil, timeout: nil)
1254
1284
  ```
1255
1285
 
1256
1286
 
1257
- **NOTE**: In most cases, you should use [Locator#fill](./locator#fill) instead. You only need to type characters if there is special keyboard handling on the page.
1258
-
1259
1287
  Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
1260
1288
 
1261
1289
  To press a special key, like `Control` or `ArrowDown`, use [Locator#press](./locator#press).
1262
1290
 
1263
1291
  **Usage**
1264
1292
 
1265
- ```ruby
1266
- element.type("hello") # types instantly
1267
- element.type("world", delay: 100) # types slower, like a user
1268
- ```
1269
-
1270
- An example of typing into a text field and then submitting the form:
1271
-
1272
- ```ruby
1273
- element = page.get_by_label("Password")
1274
- element.type("my password")
1275
- element.press("Enter")
1276
- ```
1277
-
1278
1293
  ## uncheck
1279
1294
 
1280
1295
  ```
@@ -554,7 +554,7 @@ This method waits for an element matching `selector`, waits for [actionability](
554
554
 
555
555
  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.
556
556
 
557
- To send fine-grained keyboard events, use [Page#type](./page#type).
557
+ To send fine-grained keyboard events, use [Locator#press_sequentially](./locator#press_sequentially).
558
558
 
559
559
  ## focus
560
560
 
@@ -1519,11 +1519,6 @@ To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./ke
1519
1519
 
1520
1520
  **Usage**
1521
1521
 
1522
- ```ruby
1523
- page.type("#mytextarea", "hello") # types instantly
1524
- page.type("#mytextarea", "world", delay: 100) # types slower, like a user
1525
- ```
1526
-
1527
1522
  ## uncheck
1528
1523
 
1529
1524
  ```
@@ -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
@@ -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 = request.frame.page.context.request
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
@@ -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'].split("\n"),
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'].split("\n"),
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,13 @@ 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
41
52
  end
@@ -29,6 +29,7 @@ end
29
29
  Console: 'console',
30
30
  Dialog: 'dialog',
31
31
  Page: 'page',
32
+ WebError: 'weberror',
32
33
  ServiceWorker: 'serviceworker',
33
34
  Request: 'request',
34
35
  Response: 'response',
@@ -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
@@ -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
- id = @visited.log(value)
61
- result = []
62
- value.each { |key, v| result << { k: key, v: serialize_value(v) } }
63
- { o: result, id: id }
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
@@ -446,6 +446,10 @@ module Playwright
446
446
  @frame.type(@selector, text, strict: true, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout)
447
447
  end
448
448
 
449
+ def press_sequentially(text, delay: nil, noWaitAfter: nil, timeout: nil)
450
+ type(text, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout)
451
+ end
452
+
449
453
  def uncheck(
450
454
  force: nil,
451
455
  noWaitAfter: nil,
@@ -61,6 +61,10 @@ module Playwright
61
61
  end
62
62
  end
63
63
 
64
+ if params[:acceptDownloads] || params[:acceptDownloads] == false
65
+ params[:acceptDownloads] = params[:acceptDownloads] ? 'accept' : 'deny'
66
+ end
67
+
64
68
  params
65
69
  end
66
70
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playwright
4
- VERSION = '1.37.1'
5
- COMPATIBLE_PLAYWRIGHT_VERSION = '1.37.0'
4
+ VERSION = '1.38.0'
5
+ COMPATIBLE_PLAYWRIGHT_VERSION = '1.38.0'
6
6
  end
@@ -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
- # # wait for download to complete
15
- # path = download.path()
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: ElementHandle.type`].
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
@@ -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: Frame.type`].
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.type`].
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
@@ -532,7 +532,7 @@ module Playwright
532
532
  #
533
533
  # 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.
534
534
  #
535
- # To send fine-grained keyboard events, use [`method: Page.type`].
535
+ # To send fine-grained keyboard events, use [`method: Locator.pressSequentially`].
536
536
  def fill(
537
537
  selector,
538
538
  value,
@@ -1340,11 +1340,6 @@ module Playwright
1340
1340
  # To press a special key, like `Control` or `ArrowDown`, use [`method: Keyboard.press`].
1341
1341
  #
1342
1342
  # **Usage**
1343
- #
1344
- # ```python sync
1345
- # page.type("#mytextarea", "hello") # types instantly
1346
- # page.type("#mytextarea", "world", delay=100) # types slower, like a user
1347
- # ```
1348
1343
  def type(
1349
1344
  selector,
1350
1345
  text,
@@ -37,6 +37,20 @@ module Playwright
37
37
 
38
38
  #
39
39
  # Returns the `Frame` that initiated this request.
40
+ #
41
+ # **Usage**
42
+ #
43
+ # ```py
44
+ # frame_url = request.frame.url
45
+ # ```
46
+ #
47
+ # **Details**
48
+ #
49
+ # Note that in some cases the frame is not available, and this method will throw.
50
+ # - When request originates in the Service Worker. You can use `request.serviceWorker()` to check that.
51
+ # - When navigation request is issued before the corresponding frame is created. You can use [`method: Request.isNavigationRequest`] to check that.
52
+ #
53
+ # Here is an example that handles all the cases:
40
54
  def frame
41
55
  wrap_impl(@impl.frame)
42
56
  end
@@ -64,6 +78,9 @@ module Playwright
64
78
 
65
79
  #
66
80
  # Whether this request is driving frame's navigation.
81
+ #
82
+ # Some navigation requests are issued before the corresponding frame is created, and therefore
83
+ # do not have [`method: Request.frame`] available.
67
84
  def navigation_request?
68
85
  wrap_impl(@impl.navigation_request?)
69
86
  end
@@ -47,13 +47,13 @@ module Playwright
47
47
  end
48
48
 
49
49
  # @nodoc
50
- def page=(req)
51
- wrap_impl(@impl.page=(unwrap_impl(req)))
50
+ def context=(req)
51
+ wrap_impl(@impl.context=(unwrap_impl(req)))
52
52
  end
53
53
 
54
54
  # @nodoc
55
- def context=(req)
56
- wrap_impl(@impl.context=(unwrap_impl(req)))
55
+ def page=(req)
56
+ wrap_impl(@impl.page=(unwrap_impl(req)))
57
57
  end
58
58
 
59
59
  # -- inherited from EventEmitter --
data/sig/playwright.rbs CHANGED
@@ -483,6 +483,7 @@ module Playwright
483
483
  def or: (Locator locator) -> Locator
484
484
  def page: -> Page
485
485
  def press: (String key, ?delay: Float, ?noWaitAfter: bool, ?timeout: Float) -> void
486
+ def press_sequentially: (String text, ?delay: Float, ?noWaitAfter: bool, ?timeout: Float) -> void
486
487
  def screenshot: (?animations: ("disabled" | "allow"), ?caret: ("hide" | "initial"), ?mask: Array[untyped], ?maskColor: String, ?omitBackground: bool, ?path: (String | File), ?quality: Integer, ?scale: ("css" | "device"), ?timeout: Float, ?type: ("png" | "jpeg")) -> String
487
488
  def scroll_into_view_if_needed: (?timeout: Float) -> void
488
489
  def select_option: (?element: (ElementHandle | Array[untyped]), ?index: (Integer | Array[untyped]), ?value: (String | Array[untyped]), ?label: (String | Array[untyped]), ?force: bool, ?noWaitAfter: bool, ?timeout: Float) -> Array[untyped]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: playwright-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.37.1
4
+ version: 1.38.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-16 00:00:00.000000000 Z
11
+ date: 2023-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -401,5 +401,5 @@ requirements: []
401
401
  rubygems_version: 3.3.26
402
402
  signing_key:
403
403
  specification_version: 4
404
- summary: The Ruby binding of playwright driver 1.37.0
404
+ summary: The Ruby binding of playwright driver 1.38.0
405
405
  test_files: []