playwright-ruby-client 1.14.beta3 → 1.15.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -14
- data/documentation/docs/api/browser.md +4 -0
- data/documentation/docs/api/browser_context.md +5 -1
- data/documentation/docs/api/browser_type.md +2 -0
- data/documentation/docs/api/element_handle.md +30 -5
- data/documentation/docs/api/experimental/android_device.md +2 -0
- data/documentation/docs/api/frame.md +32 -6
- data/documentation/docs/api/locator.md +67 -38
- data/documentation/docs/api/mouse.md +11 -0
- data/documentation/docs/api/page.md +38 -7
- data/documentation/docs/api/request.md +34 -1
- data/documentation/docs/api/response.md +37 -2
- data/documentation/docs/api/selectors.md +29 -3
- data/documentation/docs/api/tracing.md +42 -8
- data/documentation/docs/api/worker.md +12 -11
- data/documentation/docs/article/getting_started.md +10 -1
- data/documentation/docs/article/guides/download_playwright_driver.md +9 -0
- data/documentation/docs/article/guides/inspector.md +1 -1
- data/documentation/docs/article/guides/playwright_on_alpine_linux.md +56 -3
- data/documentation/docs/article/guides/rails_integration.md +4 -2
- data/documentation/docs/article/guides/rails_integration_with_null_driver.md +86 -0
- data/documentation/docs/article/guides/recording_video.md +1 -1
- data/documentation/docs/article/guides/semi_automation.md +2 -2
- data/documentation/docs/article/guides/use_storage_state.md +78 -0
- data/documentation/docs/include/api_coverage.md +15 -0
- data/documentation/docusaurus.config.js +1 -0
- data/documentation/package.json +2 -2
- data/documentation/src/pages/index.js +0 -1
- data/documentation/static/img/playwright-ruby-client.png +0 -0
- data/documentation/yarn.lock +625 -549
- data/lib/playwright/channel.rb +36 -2
- data/lib/playwright/channel_owners/artifact.rb +6 -2
- data/lib/playwright/channel_owners/browser.rb +4 -0
- data/lib/playwright/channel_owners/browser_context.rb +21 -14
- data/lib/playwright/channel_owners/browser_type.rb +0 -1
- data/lib/playwright/channel_owners/element_handle.rb +10 -2
- data/lib/playwright/channel_owners/frame.rb +8 -0
- data/lib/playwright/channel_owners/page.rb +20 -4
- data/lib/playwright/channel_owners/playwright.rb +9 -0
- data/lib/playwright/channel_owners/request.rb +53 -17
- data/lib/playwright/channel_owners/response.rb +48 -5
- data/lib/playwright/connection.rb +8 -11
- data/lib/playwright/http_headers.rb +0 -6
- data/lib/playwright/locator_impl.rb +8 -0
- data/lib/playwright/mouse_impl.rb +9 -0
- data/lib/playwright/raw_headers.rb +61 -0
- data/lib/playwright/{route_handler_entry.rb → route_handler.rb} +30 -2
- data/lib/playwright/tracing_impl.rb +18 -7
- data/lib/playwright/transport.rb +2 -0
- data/lib/playwright/utils.rb +8 -1
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright/web_socket_transport.rb +2 -0
- data/lib/playwright.rb +46 -5
- data/lib/playwright_api/android.rb +6 -6
- data/lib/playwright_api/android_device.rb +11 -9
- data/lib/playwright_api/browser.rb +12 -8
- data/lib/playwright_api/browser_context.rb +12 -8
- data/lib/playwright_api/browser_type.rb +9 -7
- data/lib/playwright_api/cdp_session.rb +7 -7
- data/lib/playwright_api/console_message.rb +6 -6
- data/lib/playwright_api/dialog.rb +6 -6
- data/lib/playwright_api/element_handle.rb +31 -8
- data/lib/playwright_api/frame.rb +35 -12
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/locator.rb +39 -0
- data/lib/playwright_api/mouse.rb +8 -0
- data/lib/playwright_api/page.rb +43 -15
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +33 -7
- data/lib/playwright_api/response.rb +31 -8
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/selectors.rb +38 -7
- data/lib/playwright_api/tracing.rb +33 -4
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/worker.rb +8 -8
- metadata +8 -4
@@ -66,3 +66,14 @@ def up(button: nil, clickCount: nil)
|
|
66
66
|
```
|
67
67
|
|
68
68
|
Dispatches a `mouseup` event.
|
69
|
+
|
70
|
+
## wheel
|
71
|
+
|
72
|
+
```
|
73
|
+
def wheel(deltaX, deltaY)
|
74
|
+
```
|
75
|
+
|
76
|
+
Dispatches a `wheel` event.
|
77
|
+
|
78
|
+
> NOTE: Wheel events may cause scrolling if they are not handled, and this method does not wait for the scrolling to
|
79
|
+
finish before returning.
|
@@ -281,7 +281,7 @@ def drag_and_drop(
|
|
281
281
|
## emulate_media
|
282
282
|
|
283
283
|
```
|
284
|
-
def emulate_media(colorScheme: nil, media: nil, reducedMotion: nil)
|
284
|
+
def emulate_media(colorScheme: nil, forcedColors: nil, media: nil, reducedMotion: nil)
|
285
285
|
```
|
286
286
|
|
287
287
|
This method changes the `CSS media type` through the `media` argument, and/or the `'prefers-colors-scheme'` media
|
@@ -622,18 +622,18 @@ def goto(url, referer: nil, timeout: nil, waitUntil: nil)
|
|
622
622
|
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
|
623
623
|
last redirect.
|
624
624
|
|
625
|
-
|
625
|
+
The method will throw an error if:
|
626
626
|
- there's an SSL error (e.g. in case of self-signed certificates).
|
627
627
|
- target URL is invalid.
|
628
628
|
- the `timeout` is exceeded during navigation.
|
629
629
|
- the remote server does not respond or is unreachable.
|
630
630
|
- the main resource failed to load.
|
631
631
|
|
632
|
-
|
632
|
+
The method will not throw an error when any valid HTTP status code is returned by the remote server, including 404 "Not
|
633
633
|
Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling
|
634
634
|
[Response#status](./response#status).
|
635
635
|
|
636
|
-
> NOTE:
|
636
|
+
> NOTE: The method either throws an error or returns a main resource response. The only exceptions are navigation to
|
637
637
|
`about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.
|
638
638
|
> NOTE: Headless mode doesn't support navigation to a PDF document. See the
|
639
639
|
[upstream issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
|
@@ -758,8 +758,6 @@ The method returns an element locator that can be used to perform actions on the
|
|
758
758
|
element immediately before performing an action, so a series of actions on the same locator can in fact be performed on
|
759
759
|
different DOM elements. That would happen if the DOM structure between those actions has changed.
|
760
760
|
|
761
|
-
Note that locator always implies visibility, so it will always be locating visible elements.
|
762
|
-
|
763
761
|
Shortcut for main frame's [Frame#locator](./frame#locator).
|
764
762
|
|
765
763
|
## main_frame
|
@@ -935,7 +933,7 @@ last redirect.
|
|
935
933
|
## route
|
936
934
|
|
937
935
|
```
|
938
|
-
def route(url, handler)
|
936
|
+
def route(url, handler, times: nil)
|
939
937
|
```
|
940
938
|
|
941
939
|
Routing provides the capability to modify network requests that are made by a page.
|
@@ -943,6 +941,9 @@ Routing provides the capability to modify network requests that are made by a pa
|
|
943
941
|
Once routing is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted.
|
944
942
|
|
945
943
|
> NOTE: The handler will only be called for the first url if the response is a redirect.
|
944
|
+
> NOTE: [Page#route](./page#route) will not intercept requests intercepted by Service Worker. See
|
945
|
+
[this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using
|
946
|
+
request interception. Via `await context.addInitScript(() => delete window.navigator.serviceWorker);`
|
946
947
|
|
947
948
|
An example of a naive handler that aborts all image requests:
|
948
949
|
|
@@ -1032,6 +1033,36 @@ page.select_option("select#colors", value: ["red", "green", "blue"])
|
|
1032
1033
|
|
1033
1034
|
Shortcut for main frame's [Frame#select_option](./frame#select_option).
|
1034
1035
|
|
1036
|
+
## set_checked
|
1037
|
+
|
1038
|
+
```
|
1039
|
+
def set_checked(
|
1040
|
+
selector,
|
1041
|
+
checked,
|
1042
|
+
force: nil,
|
1043
|
+
noWaitAfter: nil,
|
1044
|
+
position: nil,
|
1045
|
+
strict: nil,
|
1046
|
+
timeout: nil,
|
1047
|
+
trial: nil)
|
1048
|
+
```
|
1049
|
+
|
1050
|
+
This method checks or unchecks an element matching `selector` by performing the following steps:
|
1051
|
+
1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
1052
|
+
1. Ensure that matched element is a checkbox or a radio input. If not, this method throws.
|
1053
|
+
1. If the element already has the right checked state, this method returns immediately.
|
1054
|
+
1. Wait for [actionability](https://playwright.dev/python/docs/actionability) checks on the matched element, unless `force` option is set. If the
|
1055
|
+
element is detached during the checks, the whole action is retried.
|
1056
|
+
1. Scroll the element into view if needed.
|
1057
|
+
1. Use [Page#mouse](./page#mouse) to click in the center of the element.
|
1058
|
+
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
|
1059
|
+
1. Ensure that the element is now checked or unchecked. If not, this method throws.
|
1060
|
+
|
1061
|
+
When all steps combined have not finished during the specified `timeout`, this method throws a `TimeoutError`. Passing
|
1062
|
+
zero timeout disables this.
|
1063
|
+
|
1064
|
+
Shortcut for main frame's [Frame#set_checked](./frame#set_checked).
|
1065
|
+
|
1035
1066
|
## set_content
|
1036
1067
|
|
1037
1068
|
```
|
@@ -18,6 +18,14 @@ complete with `'requestfinished'` event.
|
|
18
18
|
If request gets a 'redirect' response, the request is successfully finished with the 'requestfinished' event, and a new
|
19
19
|
request is issued to a redirected url.
|
20
20
|
|
21
|
+
## all_headers
|
22
|
+
|
23
|
+
```
|
24
|
+
def all_headers
|
25
|
+
```
|
26
|
+
|
27
|
+
An object with all the request HTTP headers associated with this request. The header names are lower-cased.
|
28
|
+
|
21
29
|
## failure
|
22
30
|
|
23
31
|
```
|
@@ -48,7 +56,24 @@ Returns the [Frame](./frame) that initiated this request.
|
|
48
56
|
def headers
|
49
57
|
```
|
50
58
|
|
51
|
-
|
59
|
+
**DEPRECATED** Incomplete list of headers as seen by the rendering engine. Use [Request#all_headers](./request#all_headers) instead.
|
60
|
+
|
61
|
+
## headers_array
|
62
|
+
|
63
|
+
```
|
64
|
+
def headers_array
|
65
|
+
```
|
66
|
+
|
67
|
+
An array with all the request HTTP headers associated with this request. Unlike [Request#all_headers](./request#all_headers), header
|
68
|
+
names are NOT lower-cased. Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times.
|
69
|
+
|
70
|
+
## header_value
|
71
|
+
|
72
|
+
```
|
73
|
+
def header_value(name)
|
74
|
+
```
|
75
|
+
|
76
|
+
Returns the value of the header matching the name. The name is case insensitive.
|
52
77
|
|
53
78
|
## navigation_request?
|
54
79
|
|
@@ -156,6 +181,14 @@ def response
|
|
156
181
|
|
157
182
|
Returns the matching [Response](./response) object, or `null` if the response was not received due to error.
|
158
183
|
|
184
|
+
## sizes
|
185
|
+
|
186
|
+
```
|
187
|
+
def sizes
|
188
|
+
```
|
189
|
+
|
190
|
+
Returns resource size information for given request.
|
191
|
+
|
159
192
|
## timing
|
160
193
|
|
161
194
|
```
|
@@ -6,6 +6,14 @@ sidebar_position: 10
|
|
6
6
|
|
7
7
|
[Response](./response) class represents responses which are received by page.
|
8
8
|
|
9
|
+
## all_headers
|
10
|
+
|
11
|
+
```
|
12
|
+
def all_headers
|
13
|
+
```
|
14
|
+
|
15
|
+
An object with all the response HTTP headers associated with this response.
|
16
|
+
|
9
17
|
## body
|
10
18
|
|
11
19
|
```
|
@@ -20,7 +28,7 @@ Returns the buffer with response body.
|
|
20
28
|
def finished
|
21
29
|
```
|
22
30
|
|
23
|
-
Waits for this response to finish, returns
|
31
|
+
Waits for this response to finish, returns always `null`.
|
24
32
|
|
25
33
|
## frame
|
26
34
|
|
@@ -36,7 +44,34 @@ Returns the [Frame](./frame) that initiated this response.
|
|
36
44
|
def headers
|
37
45
|
```
|
38
46
|
|
39
|
-
|
47
|
+
**DEPRECATED** Incomplete list of headers as seen by the rendering engine. Use [Response#all_headers](./response#all_headers) instead.
|
48
|
+
|
49
|
+
## headers_array
|
50
|
+
|
51
|
+
```
|
52
|
+
def headers_array
|
53
|
+
```
|
54
|
+
|
55
|
+
An array with all the request HTTP headers associated with this response. Unlike [Response#all_headers](./response#all_headers), header
|
56
|
+
names are NOT lower-cased. Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times.
|
57
|
+
|
58
|
+
## header_value
|
59
|
+
|
60
|
+
```
|
61
|
+
def header_value(name)
|
62
|
+
```
|
63
|
+
|
64
|
+
Returns the value of the header matching the name. The name is case insensitive. If multiple headers have the same name
|
65
|
+
(except `set-cookie`), they are returned as a list separated by `, `. For `set-cookie`, the `\n` separator is used. If
|
66
|
+
no headers are found, `null` is returned.
|
67
|
+
|
68
|
+
## header_values
|
69
|
+
|
70
|
+
```
|
71
|
+
def header_values(name)
|
72
|
+
```
|
73
|
+
|
74
|
+
Returns all values of the headers matching the name, for example `set-cookie`. The name is case insensitive.
|
40
75
|
|
41
76
|
## json
|
42
77
|
|
@@ -15,9 +15,35 @@ def register(name, contentScript: nil, path: nil, script: nil)
|
|
15
15
|
|
16
16
|
An example of registering selector engine that queries elements based on a tag name:
|
17
17
|
|
18
|
-
```
|
19
|
-
|
20
|
-
|
18
|
+
```ruby
|
19
|
+
tag_selector = <<~JAVASCRIPT
|
20
|
+
{
|
21
|
+
// Returns the first element matching given selector in the root's subtree.
|
22
|
+
query(root, selector) {
|
23
|
+
return root.querySelector(selector);
|
24
|
+
},
|
25
|
+
// Returns all elements matching given selector in the root's subtree.
|
26
|
+
queryAll(root, selector) {
|
27
|
+
return Array.from(root.querySelectorAll(selector));
|
28
|
+
}
|
29
|
+
}
|
30
|
+
JAVASCRIPT
|
31
|
+
|
32
|
+
# Register the engine. Selectors will be prefixed with "tag=".
|
33
|
+
playwright.selectors.register("tag", script: tag_selector)
|
34
|
+
playwright.chromium.launch do |browser|
|
35
|
+
page = browser.new_page()
|
36
|
+
page.content = '<div><button>Click me</button></div>'
|
37
|
+
|
38
|
+
# Use the selector prefixed with its name.
|
39
|
+
button = page.query_selector('tag=button')
|
40
|
+
# Combine it with other selector engines.
|
41
|
+
page.click('tag=div >> text="Click me"')
|
42
|
+
|
43
|
+
# Can use it in any methods supporting selectors.
|
44
|
+
button_count = page.eval_on_selector_all('tag=button', 'buttons => buttons.length')
|
45
|
+
button_count # => 1
|
46
|
+
end
|
21
47
|
```
|
22
48
|
|
23
49
|
|
@@ -4,16 +4,15 @@ sidebar_position: 10
|
|
4
4
|
|
5
5
|
# Tracing
|
6
6
|
|
7
|
-
API for collecting and saving Playwright traces. Playwright traces can be opened
|
8
|
-
Playwright script runs.
|
7
|
+
API for collecting and saving Playwright traces. Playwright traces can be opened in [Trace Viewer](https://playwright.dev/python/docs/trace-viewer)
|
8
|
+
after Playwright script runs.
|
9
9
|
|
10
|
-
Start
|
10
|
+
Start recording a trace before performing actions. At the end, stop tracing and save it to a file.
|
11
11
|
|
12
12
|
```ruby
|
13
|
-
browser.
|
14
|
-
context = page.context
|
15
|
-
|
13
|
+
browser.new_context do |context|
|
16
14
|
context.tracing.start(screenshots: true, snapshots: true)
|
15
|
+
page = context.new_page
|
17
16
|
page.goto('https://playwright.dev')
|
18
17
|
context.tracing.stop(path: 'trace.zip')
|
19
18
|
end
|
@@ -30,15 +29,42 @@ def start(name: nil, screenshots: nil, snapshots: nil)
|
|
30
29
|
Start tracing.
|
31
30
|
|
32
31
|
```ruby
|
33
|
-
context = page.context
|
34
|
-
|
35
32
|
context.tracing.start(name: 'trace', screenshots: true, snapshots: true)
|
33
|
+
page = context.new_page
|
36
34
|
page.goto('https://playwright.dev')
|
37
35
|
context.tracing.stop(path: 'trace.zip')
|
38
36
|
```
|
39
37
|
|
40
38
|
|
41
39
|
|
40
|
+
## start_chunk
|
41
|
+
|
42
|
+
```
|
43
|
+
def start_chunk
|
44
|
+
```
|
45
|
+
|
46
|
+
Start a new trace chunk. If you'd like to record multiple traces on the same [BrowserContext](./browser_context), use
|
47
|
+
[Tracing#start](./tracing#start) once, and then create multiple trace chunks with [Tracing#start_chunk](./tracing#start_chunk) and
|
48
|
+
[Tracing#stop_chunk](./tracing#stop_chunk).
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
context.tracing.start(name: "trace", screenshots: true, snapshots: true)
|
52
|
+
page = context.new_page
|
53
|
+
page.goto("https://playwright.dev")
|
54
|
+
|
55
|
+
context.tracing.start_chunk
|
56
|
+
page.click("text=Get Started")
|
57
|
+
# Everything between start_chunk and stop_chunk will be recorded in the trace.
|
58
|
+
context.tracing.stop_chunk(path: "trace1.zip")
|
59
|
+
|
60
|
+
context.tracing.start_chunk
|
61
|
+
page.goto("http://example.com")
|
62
|
+
# Save a second trace file with different actions.
|
63
|
+
context.tracing.stop_chunk(path: "trace2.zip")
|
64
|
+
```
|
65
|
+
|
66
|
+
|
67
|
+
|
42
68
|
## stop
|
43
69
|
|
44
70
|
```
|
@@ -46,3 +72,11 @@ def stop(path: nil)
|
|
46
72
|
```
|
47
73
|
|
48
74
|
Stop tracing.
|
75
|
+
|
76
|
+
## stop_chunk
|
77
|
+
|
78
|
+
```
|
79
|
+
def stop_chunk(path: nil)
|
80
|
+
```
|
81
|
+
|
82
|
+
Stop the trace chunk. See [Tracing#start_chunk](./tracing#start_chunk) for more details about multiple trace chunks.
|
@@ -8,17 +8,18 @@ The Worker class represents a [WebWorker](https://developer.mozilla.org/en-US/do
|
|
8
8
|
event is emitted on the page object to signal a worker creation. `close` event is emitted on the worker object when the
|
9
9
|
worker is gone.
|
10
10
|
|
11
|
-
```
|
12
|
-
def handle_worker(worker)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
11
|
+
```ruby
|
12
|
+
def handle_worker(worker)
|
13
|
+
puts "worker created: #{worker.url}"
|
14
|
+
worker.once("close", -> (w) { puts "worker destroyed: #{w.url}" })
|
15
|
+
end
|
16
|
+
|
17
|
+
page.on('worker', method(:handle_worker))
|
18
|
+
|
19
|
+
puts "current workers:"
|
20
|
+
page.workers.each do |worker|
|
21
|
+
puts " #{worker.url}"
|
22
|
+
end
|
22
23
|
```
|
23
24
|
|
24
25
|
|
@@ -4,7 +4,14 @@ sidebar_position: 0
|
|
4
4
|
|
5
5
|
# Getting started
|
6
6
|
|
7
|
-
|
7
|
+
```
|
8
|
+
gem 'playwright-ruby-client'
|
9
|
+
```
|
10
|
+
|
11
|
+
Add the line above and then `bundle install`.
|
12
|
+
|
13
|
+
|
14
|
+
Since `playwright-ruby-client` doesn't include Playwright driver nor its downloader, **we have to install Playwright in advance**
|
8
15
|
|
9
16
|
```shell
|
10
17
|
$ npx playwright install
|
@@ -12,6 +19,8 @@ $ npx playwright install
|
|
12
19
|
|
13
20
|
and then set `playwright_cli_executable_path: "npx playwright"` into `Playwright.create`.
|
14
21
|
|
22
|
+
Other methods of installation is also available. See the detail in [Download Playwright driver](./guides/download_playwright_driver)
|
23
|
+
|
15
24
|
## Enjoy with examples
|
16
25
|
|
17
26
|
### Capture a site
|
@@ -12,6 +12,15 @@ Choose any of the three ways as you prefer to download the driver:
|
|
12
12
|
* `npm install`: the best choice for most use cases, with existing Node.js environment.
|
13
13
|
* Direct download: maybe a good choice for Docker :whale: integration.
|
14
14
|
|
15
|
+
:::note
|
16
|
+
|
17
|
+
Also the article [Playwright on Alpine Linux](./playwright_on_alpine_linux) would be helpful if you plan to
|
18
|
+
|
19
|
+
* Build a browser server/container like Selenium Grid
|
20
|
+
* Run automation scripts on Alpine Linux
|
21
|
+
|
22
|
+
:::
|
23
|
+
|
15
24
|
## Using `npx`
|
16
25
|
|
17
26
|
```shell
|
@@ -1,5 +1,5 @@
|
|
1
1
|
---
|
2
|
-
sidebar_position:
|
2
|
+
sidebar_position: 40
|
3
3
|
---
|
4
4
|
|
5
5
|
# Playwright on Alpine Linux
|
@@ -33,7 +33,23 @@ Playwright server is running on a container of [official Docker image](https://h
|
|
33
33
|
|
34
34
|
![overview](https://user-images.githubusercontent.com/11763113/124934448-ad4d0700-e03f-11eb-942e-b9f3282bb703.png)
|
35
35
|
|
36
|
-
|
36
|
+
### Playwright Server v.s. Browser Server
|
37
|
+
|
38
|
+
Playwright provides two kind of methods to share the browser environments for clients.
|
39
|
+
|
40
|
+
When you want to share only one browser environment, Browser server is suitable. This feature is officially supported in Playwright.
|
41
|
+
|
42
|
+
* Server can be launched with [BrowserType#launchServer](https://playwright.dev/docs/api/class-browsertype#browser-type-launch-server) instead of `BrowserType#launch`.
|
43
|
+
* Client can connect to server with [BrowserType#connect](https://playwright.dev/docs/api/class-browsertype#browser-type-connect). In playwright-ruby-client, `BrowserType#connect` and not implemented yet and use `Playwright#connect_to_browser_server()` instead.
|
44
|
+
|
45
|
+
Another method is sharing all browser environment. This method is very simple, but not an official feature, and can be changed in future.
|
46
|
+
|
47
|
+
* Server can be launched with `playwright run-server` (CLI command).
|
48
|
+
* Client can connect to server with `Playwright.connect_to_playwright_server` instead of `Playwright.create`
|
49
|
+
|
50
|
+
## Playwright server/client
|
51
|
+
|
52
|
+
### Client code
|
37
53
|
|
38
54
|
Many example uses `Playwright#create`, which internally uses Pipe (stdin/stdout) transport for Playwright-protocol messaging. Instead, **just use `Playwright#connect_to_playwright_server(endpoint)`** for WebSocket transport.
|
39
55
|
|
@@ -51,7 +67,7 @@ end
|
|
51
67
|
|
52
68
|
`wss://example.com:8888/ws` is an example of endpoint URL of the Playwright server. In local development environment, it is typically `"ws://127.0.0.1:#{port}/ws"`.
|
53
69
|
|
54
|
-
|
70
|
+
### Server code
|
55
71
|
|
56
72
|
With the [official Docker image](https://hub.docker.com/_/microsoft-playwright) or in the local development environment with Node.js, just execute `npx playwright install && npx playwright run-server $PORT`. (`$PORT` is a port number of the server)
|
57
73
|
|
@@ -67,6 +83,43 @@ ENV PORT 8888
|
|
67
83
|
CMD ["./node_modules/.bin/playwright", "run-server", "$PORT"]
|
68
84
|
```
|
69
85
|
|
86
|
+
## Browser server/client
|
87
|
+
|
88
|
+
### Client code
|
89
|
+
|
90
|
+
Use `Playwright#connect_to_playwright_server` and pass the WebSocket URL for browser server.
|
91
|
+
Note that this method requires a block with `Browser`, not `Playwright` or `BrowserType`.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
Playwright.connect_to_playwright_server(ws_url) do |browser|
|
95
|
+
page = browser.new_page
|
96
|
+
page.goto(...)
|
97
|
+
...
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
### Server code
|
102
|
+
|
103
|
+
For instant use, `npx playwright launch-server chromium` generates a WebSocket endpoint URL with a random path.
|
104
|
+
|
105
|
+
More customization can be done by implementing JavaScript server like below:
|
106
|
+
|
107
|
+
```js
|
108
|
+
const playwright = require('playwright')
|
109
|
+
|
110
|
+
option = {
|
111
|
+
channel: 'chrome-canary',
|
112
|
+
headless: false,
|
113
|
+
port: 8080,
|
114
|
+
wsPath: 'ws',
|
115
|
+
}
|
116
|
+
playwright.chromium.launchServer(option).then((server) => { console.log(server.wsEndpoint()) })
|
117
|
+
```
|
118
|
+
|
119
|
+
`port` and `wsPath` would be useful for generating static WebSocket endpoint URL.
|
120
|
+
Other available options for `BrowserType#launchServer` can be found here:
|
121
|
+
https://playwright.dev/docs/api/class-browsertype#browser-type-launch-server
|
122
|
+
|
70
123
|
## Debugging for connection
|
71
124
|
|
72
125
|
The client and server are really quiet. This chapter shows how to check if the communication on the WebSocket works well or not.
|