playwright-ruby-client 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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'