playwright-ruby-client 0.7.1 → 0.8.0

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -0
  3. data/documentation/docs/api/element_handle.md +11 -2
  4. data/documentation/docs/api/frame.md +15 -1
  5. data/documentation/docs/api/page.md +15 -1
  6. data/documentation/docs/api/response.md +16 -0
  7. data/documentation/docs/include/api_coverage.md +6 -0
  8. data/lib/playwright.rb +36 -3
  9. data/lib/playwright/channel_owners/element_handle.rb +11 -4
  10. data/lib/playwright/channel_owners/frame.rb +14 -2
  11. data/lib/playwright/channel_owners/page.rb +13 -2
  12. data/lib/playwright/channel_owners/response.rb +8 -0
  13. data/lib/playwright/connection.rb +2 -4
  14. data/lib/playwright/transport.rb +0 -1
  15. data/lib/playwright/version.rb +2 -2
  16. data/lib/playwright/web_socket_client.rb +164 -0
  17. data/lib/playwright/web_socket_transport.rb +104 -0
  18. data/lib/playwright_api/android.rb +6 -6
  19. data/lib/playwright_api/android_device.rb +8 -8
  20. data/lib/playwright_api/browser.rb +6 -6
  21. data/lib/playwright_api/browser_context.rb +6 -6
  22. data/lib/playwright_api/browser_type.rb +6 -6
  23. data/lib/playwright_api/cdp_session.rb +12 -12
  24. data/lib/playwright_api/console_message.rb +6 -6
  25. data/lib/playwright_api/dialog.rb +6 -6
  26. data/lib/playwright_api/element_handle.rb +17 -11
  27. data/lib/playwright_api/frame.rb +20 -9
  28. data/lib/playwright_api/js_handle.rb +6 -6
  29. data/lib/playwright_api/page.rb +20 -9
  30. data/lib/playwright_api/playwright.rb +6 -6
  31. data/lib/playwright_api/request.rb +6 -6
  32. data/lib/playwright_api/response.rb +16 -6
  33. data/lib/playwright_api/route.rb +11 -6
  34. data/lib/playwright_api/selectors.rb +6 -6
  35. data/lib/playwright_api/web_socket.rb +6 -6
  36. data/lib/playwright_api/worker.rb +6 -6
  37. metadata +6 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8e3e3982a30add91ed67641a29dcff9778c40788c8434d2ef581cb926951968
4
- data.tar.gz: bc7c51236c2d9c2632c53dfe25ae7f9f357c1118a434bb1c41f735a0c67c7625
3
+ metadata.gz: 05e5dff936dc4eda78a295d4f6935b5b92d6e82046de9a36c9f4b67aba24e89f
4
+ data.tar.gz: 85f30ee725facdc21d77645007cbeca689cd322dacb559146234fab1de0aab79
5
5
  SHA512:
6
- metadata.gz: b438126a715d3c427408fb4d0b13483bb6f96444cb9c359a946da70125f00b0eee488e5753493a5f9e37ff1294209fd58a044721e0c7b0b2e5c06ef2a8611aef
7
- data.tar.gz: a13605776cfca08333630a2e18cf53035d71b6b0ea454a27f76bf0562ef1d505844c70b1119bdca2c2cfd400d402d2c62e06fe38d53abf561c005b6127900c83
6
+ metadata.gz: 3c0fefff97e051805fb7d48aa134456d6a45ed5ab6b6818ea506251d93a1991c47bc6fc30aa1e2eae9369b1188564c08e23d083b6f8f8a896efe52d008cf6889
7
+ data.tar.gz: ebaf0d10fea440818cc182496b72c5ac16d192c76825db8aa271b89f891059b496ffdaaecdcfbaf7482ceb37ea868ac13feae678eee81b76c4e856f419627209
data/README.md CHANGED
@@ -159,6 +159,32 @@ end
159
159
 
160
160
  ```
161
161
 
162
+ ### Communicate with Playwright server
163
+
164
+ If your environment doesn't accept installing browser or creating browser process, consider separating Ruby client and Playwright server.
165
+
166
+ ![structure](https://user-images.githubusercontent.com/11763113/124934448-ad4d0700-e03f-11eb-942e-b9f3282bb703.png)
167
+
168
+ For launching Playwright server, just execute:
169
+
170
+ ```
171
+ npx playwright install && npx playwright run-server 8080
172
+ ```
173
+
174
+ and we can connect to the server with the code like this:
175
+
176
+ ```ruby
177
+ Playwright.connect_to_playwright_server('ws://127.0.0.1:8080') do |playwright|
178
+ playwright.chromium.launch do |browser|
179
+ page = browser.new_page
180
+ page.goto('https://github.com/YusukeIwaki')
181
+ page.screenshot(path: './YusukeIwaki.png')
182
+ end
183
+ end
184
+ ```
185
+
186
+ When `Playwright.connect_to_playwright_server` is used, playwright_cli_executable_path is not required.
187
+
162
188
  ## License
163
189
 
164
190
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -232,7 +232,7 @@ feed_handle.eval_on_selector_all(".tweet", "nodes => nodes.map(n => n.innerText)
232
232
  ## fill
233
233
 
234
234
  ```
235
- def fill(value, noWaitAfter: nil, timeout: nil)
235
+ def fill(value, force: nil, noWaitAfter: nil, timeout: nil)
236
236
  ```
237
237
 
238
238
  This method waits for [actionability](https://playwright.dev/python/docs/actionability) checks, focuses the element, fills it and triggers an `input`
@@ -300,6 +300,14 @@ def inner_text
300
300
 
301
301
  Returns the `element.innerText`.
302
302
 
303
+ ## input_value
304
+
305
+ ```
306
+ def input_value(timeout: nil)
307
+ ```
308
+
309
+ Returns `input.value` for `<input>` or `<textarea>` element. Throws for non-input elements.
310
+
303
311
  ## checked?
304
312
 
305
313
  ```
@@ -436,6 +444,7 @@ def select_option(
436
444
  index: nil,
437
445
  value: nil,
438
446
  label: nil,
447
+ force: nil,
439
448
  noWaitAfter: nil,
440
449
  timeout: nil)
441
450
  ```
@@ -470,7 +479,7 @@ element_handle.select_option(value: "blue", index: 2, label: "red")
470
479
  ## select_text
471
480
 
472
481
  ```
473
- def select_text(timeout: nil)
482
+ def select_text(force: nil, timeout: nil)
474
483
  ```
475
484
 
476
485
  This method waits for [actionability](https://playwright.dev/python/docs/actionability) checks, then focuses the element and selects all its text
@@ -326,7 +326,12 @@ result_handle.dispose
326
326
  ## fill
327
327
 
328
328
  ```
329
- def fill(selector, value, noWaitAfter: nil, timeout: nil)
329
+ def fill(
330
+ selector,
331
+ value,
332
+ force: nil,
333
+ noWaitAfter: nil,
334
+ timeout: nil)
330
335
  ```
331
336
 
332
337
  This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/python/docs/actionability) checks, focuses the
@@ -443,6 +448,14 @@ def inner_text(selector, timeout: nil)
443
448
 
444
449
  Returns `element.innerText`.
445
450
 
451
+ ## input_value
452
+
453
+ ```
454
+ def input_value(selector, timeout: nil)
455
+ ```
456
+
457
+ Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
458
+
446
459
  ## checked?
447
460
 
448
461
  ```
@@ -588,6 +601,7 @@ def select_option(
588
601
  index: nil,
589
602
  value: nil,
590
603
  label: nil,
604
+ force: nil,
591
605
  noWaitAfter: nil,
592
606
  timeout: nil)
593
607
  ```
@@ -499,7 +499,12 @@ page.click("button")
499
499
  ## fill
500
500
 
501
501
  ```
502
- def fill(selector, value, noWaitAfter: nil, timeout: nil)
502
+ def fill(
503
+ selector,
504
+ value,
505
+ force: nil,
506
+ noWaitAfter: nil,
507
+ timeout: nil)
503
508
  ```
504
509
 
505
510
  This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/python/docs/actionability) checks, focuses the
@@ -650,6 +655,14 @@ def inner_text(selector, timeout: nil)
650
655
 
651
656
  Returns `element.innerText`.
652
657
 
658
+ ## input_value
659
+
660
+ ```
661
+ def input_value(selector, timeout: nil)
662
+ ```
663
+
664
+ Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
665
+
653
666
  ## checked?
654
667
 
655
668
  ```
@@ -934,6 +947,7 @@ def select_option(
934
947
  index: nil,
935
948
  value: nil,
936
949
  label: nil,
950
+ force: nil,
937
951
  noWaitAfter: nil,
938
952
  timeout: nil)
939
953
  ```
@@ -64,6 +64,22 @@ def request
64
64
 
65
65
  Returns the matching [Request](./request) object.
66
66
 
67
+ ## security_details
68
+
69
+ ```
70
+ def security_details
71
+ ```
72
+
73
+ Returns SSL and other security information.
74
+
75
+ ## server_addr
76
+
77
+ ```
78
+ def server_addr
79
+ ```
80
+
81
+ Returns the IP address and port of the server.
82
+
67
83
  ## status
68
84
 
69
85
  ```
@@ -26,6 +26,8 @@
26
26
  * json
27
27
  * ok
28
28
  * request
29
+ * security_details
30
+ * server_addr
29
31
  * status
30
32
  * status_text
31
33
  * text
@@ -36,6 +38,7 @@
36
38
  * abort
37
39
  * continue
38
40
  * fulfill
41
+ * ~~intercept~~
39
42
  * request
40
43
 
41
44
  ## WebSocket
@@ -91,6 +94,7 @@
91
94
  * hover
92
95
  * inner_html
93
96
  * inner_text
97
+ * input_value
94
98
  * checked?
95
99
  * disabled?
96
100
  * editable?
@@ -146,6 +150,7 @@
146
150
  * hover
147
151
  * inner_html
148
152
  * inner_text
153
+ * input_value
149
154
  * checked?
150
155
  * detached?
151
156
  * disabled?
@@ -231,6 +236,7 @@
231
236
  * hover
232
237
  * inner_html
233
238
  * inner_text
239
+ * input_value
234
240
  * checked?
235
241
  * closed?
236
242
  * disabled?
data/lib/playwright.rb CHANGED
@@ -59,7 +59,8 @@ module Playwright
59
59
  # and we *must* call execution.stop on the end.
60
60
  # The instance of playwright is available by calling execution.playwright
61
61
  module_function def create(playwright_cli_executable_path:, &block)
62
- connection = Connection.new(playwright_cli_executable_path: playwright_cli_executable_path)
62
+ transport = Transport.new(playwright_cli_executable_path: playwright_cli_executable_path)
63
+ connection = Connection.new(transport)
63
64
  connection.async_run
64
65
 
65
66
  execution =
@@ -82,7 +83,39 @@ module Playwright
82
83
  end
83
84
  end
84
85
 
85
- module_function def instance
86
- @playwright_instance
86
+ # Connects to Playwright server, launched by `npx playwright run-server` via WebSocket transport.
87
+ #
88
+ # Playwright.connect_to_playwright_server(...) do |playwright|
89
+ # browser = playwright.chromium.launch
90
+ # ...
91
+ # end
92
+ #
93
+ # @experimental
94
+ module_function def connect_to_playwright_server(ws_endpoint, &block)
95
+ require 'playwright/web_socket_client'
96
+ require 'playwright/web_socket_transport'
97
+
98
+ transport = WebSocketTransport.new(ws_endpoint: ws_endpoint)
99
+ connection = Connection.new(transport)
100
+ connection.async_run
101
+
102
+ execution =
103
+ begin
104
+ playwright = connection.wait_for_object_with_known_name('Playwright')
105
+ Execution.new(connection, PlaywrightApi.wrap(playwright))
106
+ rescue
107
+ connection.stop
108
+ raise
109
+ end
110
+
111
+ if block
112
+ begin
113
+ block.call(execution.playwright)
114
+ ensure
115
+ execution.stop
116
+ end
117
+ else
118
+ execution
119
+ end
87
120
  end
88
121
  end
@@ -146,6 +146,7 @@ module Playwright
146
146
  index: nil,
147
147
  value: nil,
148
148
  label: nil,
149
+ force: nil,
149
150
  noWaitAfter: nil,
150
151
  timeout: nil)
151
152
  base_params = SelectOptionValues.new(
@@ -154,7 +155,7 @@ module Playwright
154
155
  value: value,
155
156
  label: label,
156
157
  ).as_params
157
- params = base_params.merge({ noWaitAfter: noWaitAfter, timeout: timeout }.compact)
158
+ params = base_params.merge({ force: force, noWaitAfter: noWaitAfter, timeout: timeout }.compact)
158
159
  @channel.send_message_to_server('selectOption', params)
159
160
  end
160
161
 
@@ -179,9 +180,10 @@ module Playwright
179
180
  nil
180
181
  end
181
182
 
182
- def fill(value, noWaitAfter: nil, timeout: nil)
183
+ def fill(value, force: nil, noWaitAfter: nil, timeout: nil)
183
184
  params = {
184
185
  value: value,
186
+ force: force,
185
187
  noWaitAfter: noWaitAfter,
186
188
  timeout: timeout,
187
189
  }.compact
@@ -190,13 +192,18 @@ module Playwright
190
192
  nil
191
193
  end
192
194
 
193
- def select_text(timeout: nil)
194
- params = { timeout: timeout }.compact
195
+ def select_text(force: nil, timeout: nil)
196
+ params = { force: force, timeout: timeout }.compact
195
197
  @channel.send_message_to_server('selectText', params)
196
198
 
197
199
  nil
198
200
  end
199
201
 
202
+ def input_value(timeout: nil)
203
+ params = { timeout: timeout }.compact
204
+ @channel.send_message_to_server('inputValue', params)
205
+ end
206
+
200
207
  def set_input_files(files, noWaitAfter: nil, timeout: nil)
201
208
  file_payloads = InputFiles.new(files).as_params
202
209
  params = { files: file_payloads, noWaitAfter: noWaitAfter, timeout: timeout }.compact
@@ -342,10 +342,16 @@ module Playwright
342
342
  nil
343
343
  end
344
344
 
345
- def fill(selector, value, noWaitAfter: nil, timeout: nil)
345
+ def fill(
346
+ selector,
347
+ value,
348
+ force: nil,
349
+ noWaitAfter: nil,
350
+ timeout: nil)
346
351
  params = {
347
352
  selector: selector,
348
353
  value: value,
354
+ force: force,
349
355
  noWaitAfter: noWaitAfter,
350
356
  timeout: timeout,
351
357
  }.compact
@@ -410,6 +416,7 @@ module Playwright
410
416
  index: nil,
411
417
  value: nil,
412
418
  label: nil,
419
+ force: nil,
413
420
  noWaitAfter: nil,
414
421
  timeout: nil)
415
422
  base_params = SelectOptionValues.new(
@@ -418,10 +425,15 @@ module Playwright
418
425
  value: value,
419
426
  label: label,
420
427
  ).as_params
421
- params = base_params.merge({ selector: selector, noWaitAfter: noWaitAfter, timeout: timeout }.compact)
428
+ params = base_params.merge({ selector: selector, force: force, noWaitAfter: noWaitAfter, timeout: timeout }.compact)
422
429
  @channel.send_message_to_server('selectOption', params)
423
430
  end
424
431
 
432
+ def input_value(selector, timeout: nil)
433
+ params = { selector: selector, timeout: timeout }.compact
434
+ @channel.send_message_to_server('inputValue', params)
435
+ end
436
+
425
437
  def set_input_files(selector, files, noWaitAfter: nil, timeout: nil)
426
438
  file_payloads = InputFiles.new(files).as_params
427
439
  params = { files: file_payloads, selector: selector, noWaitAfter: noWaitAfter, timeout: timeout }.compact
@@ -505,8 +505,13 @@ module Playwright
505
505
  )
506
506
  end
507
507
 
508
- def fill(selector, value, noWaitAfter: nil, timeout: nil)
509
- @main_frame.fill(selector, value, noWaitAfter: noWaitAfter, timeout: timeout)
508
+ def fill(
509
+ selector,
510
+ value,
511
+ force: nil,
512
+ noWaitAfter: nil,
513
+ timeout: nil)
514
+ @main_frame.fill(selector, value, force: force, noWaitAfter: noWaitAfter, timeout: timeout)
510
515
  end
511
516
 
512
517
  def focus(selector, timeout: nil)
@@ -552,6 +557,7 @@ module Playwright
552
557
  index: nil,
553
558
  value: nil,
554
559
  label: nil,
560
+ force: nil,
555
561
  noWaitAfter: nil,
556
562
  timeout: nil)
557
563
  @main_frame.select_option(
@@ -560,11 +566,16 @@ module Playwright
560
566
  index: index,
561
567
  value: value,
562
568
  label: label,
569
+ force: force,
563
570
  noWaitAfter: noWaitAfter,
564
571
  timeout: timeout,
565
572
  )
566
573
  end
567
574
 
575
+ def input_value(selector, timeout: nil)
576
+ @main_frame.input_value(selector, timeout: timeout)
577
+ end
578
+
568
579
  def set_input_files(selector, files, noWaitAfter: nil, timeout: nil)
569
580
  @main_frame.set_input_files(selector, files, noWaitAfter: noWaitAfter, timeout: timeout)
570
581
  end
@@ -44,6 +44,14 @@ module Playwright
44
44
  end.to_h
45
45
  end
46
46
 
47
+ def server_addr
48
+ @channel.send_message_to_server('serverAddr')
49
+ end
50
+
51
+ def security_details
52
+ @channel.send_message_to_server('securityDetails')
53
+ end
54
+
47
55
  def finished
48
56
  @channel.send_message_to_server('finished')
49
57
  end
@@ -5,10 +5,8 @@ module Playwright
5
5
  # https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_connection.py
6
6
  # https://github.com/microsoft/playwright-java/blob/master/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java
7
7
  class Connection
8
- def initialize(playwright_cli_executable_path:)
9
- @transport = Transport.new(
10
- playwright_cli_executable_path: playwright_cli_executable_path
11
- )
8
+ def initialize(transport)
9
+ @transport = transport
12
10
  @transport.on_message_received do |message|
13
11
  dispatch(message)
14
12
  end
@@ -8,7 +8,6 @@ module Playwright
8
8
  # ref: https://github.com/microsoft/playwright-python/blob/master/playwright/_impl/_transport.py
9
9
  class Transport
10
10
  # @param playwright_cli_executable_path [String] path to playwright-cli.
11
- # @param debug [Boolean]
12
11
  def initialize(playwright_cli_executable_path:)
13
12
  @driver_executable_path = playwright_cli_executable_path
14
13
  @debug = ENV['DEBUG'].to_s == 'true' || ENV['DEBUG'].to_s == '1'