playwright-ruby-client 1.17.1 → 1.18.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/documentation/docs/api/api_request_context.md +45 -133
- data/documentation/docs/api/browser_context.md +0 -4
- data/documentation/docs/api/download.md +1 -3
- data/documentation/docs/api/frame.md +1 -1
- data/documentation/docs/api/frame_locator.md +10 -1
- data/documentation/docs/api/locator.md +19 -47
- data/documentation/docs/api/page.md +1 -1
- data/documentation/docs/include/api_coverage.md +16 -28
- data/lib/playwright/channel_owners/api_request_context.rb +0 -232
- data/lib/playwright/channel_owners/browser_context.rb +6 -3
- data/lib/playwright/channel_owners/frame.rb +2 -2
- data/lib/playwright/channel_owners/local_utils.rb +14 -0
- data/lib/playwright/channel_owners/page.rb +2 -6
- data/lib/playwright/frame_locator_impl.rb +2 -1
- data/lib/playwright/locator_impl.rb +62 -3
- data/lib/playwright/tracing_impl.rb +21 -7
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright_api/api_request_context.rb +55 -8
- data/lib/playwright_api/browser_context.rb +6 -6
- data/lib/playwright_api/download.rb +0 -4
- data/lib/playwright_api/frame.rb +2 -2
- data/lib/playwright_api/frame_locator.rb +11 -2
- data/lib/playwright_api/local_utils.rb +9 -0
- data/lib/playwright_api/locator.rb +16 -46
- data/lib/playwright_api/page.rb +7 -7
- metadata +7 -10
- data/documentation/docs/api/api_request.md +0 -7
- data/documentation/docs/api/api_response.md +0 -90
- data/lib/playwright/api_response_impl.rb +0 -73
- data/lib/playwright_api/api_request.rb +0 -18
- data/lib/playwright_api/api_response.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36a3c1f293b4d9a4a27ac780ebce4eb4098af2cefeba6d4e66f4ddb8c49490d7
|
4
|
+
data.tar.gz: 3520c8afc689c71a27d9af6516461cb1871a206bc6c416aee5f99742217191c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69a7ff8c2880d9ce5bad599f102e5a0c4e710eaa25f9d5c9323cbd579cfaac6a4252eef9321a0ee453f0200fb2ac985f79f00c5ddb5717549a8d78c5f3348afe
|
7
|
+
data.tar.gz: b589f69e462f5dfba205af8ee98cb58a6bcb35b4ea6742fa8bd3f3bc26e4783e9ee7cbed2fe8dced6272c64de144465d767b00859e32f602ecb08b28b2cfc399
|
@@ -9,139 +9,51 @@ environment or the service to your e2e test. When used on [Page](./page) or a [B
|
|
9
9
|
the cookies from the corresponding [BrowserContext](./browser_context). This means that if you log in using this API, your e2e test will be
|
10
10
|
logged in and vice versa.
|
11
11
|
|
12
|
-
|
12
|
+
```python sync title=example_6db210740dd2dcb4551c2207b3204fde7127b24c7850226b273d15c0d6624ba5.py
|
13
|
+
import os
|
14
|
+
from playwright.sync_api import sync_playwright
|
15
|
+
|
16
|
+
REPO = "test-repo-1"
|
17
|
+
USER = "github-username"
|
18
|
+
API_TOKEN = os.getenv("GITHUB_API_TOKEN")
|
19
|
+
|
20
|
+
with sync_playwright() as p:
|
21
|
+
# This will launch a new browser, create a context and page. When making HTTP
|
22
|
+
# requests with the internal APIRequestContext (e.g. `context.request` or `page.request`)
|
23
|
+
# it will automatically set the cookies to the browser page and vise versa.
|
24
|
+
browser = playwright.chromium.launch()
|
25
|
+
context = browser.new_context(base_url="https://api.github.com")
|
26
|
+
api_request_context = context.request
|
27
|
+
page = context.new_page()
|
28
|
+
|
29
|
+
# Alternatively you can create a APIRequestContext manually without having a browser context attached:
|
30
|
+
# api_request_context = playwright.request.new_context(base_url="https://api.github.com")
|
31
|
+
|
32
|
+
|
33
|
+
# Create a repository.
|
34
|
+
response = api_request_context.post(
|
35
|
+
"/user/repos",
|
36
|
+
headers={
|
37
|
+
"Accept": "application/vnd.github.v3+json",
|
38
|
+
# Add GitHub personal access token.
|
39
|
+
"Authorization": f"token {API_TOKEN}",
|
40
|
+
},
|
41
|
+
data={"name": REPO},
|
42
|
+
)
|
43
|
+
assert response.ok
|
44
|
+
assert response.json()["name"] == REPO
|
45
|
+
|
46
|
+
# Delete a repository.
|
47
|
+
response = api_request_context.delete(
|
48
|
+
f"/repos/{USER}/{REPO}",
|
49
|
+
headers={
|
50
|
+
"Accept": "application/vnd.github.v3+json",
|
51
|
+
# Add GitHub personal access token.
|
52
|
+
"Authorization": f"token {API_TOKEN}",
|
53
|
+
},
|
54
|
+
)
|
55
|
+
assert response.ok
|
56
|
+
assert await response.body() == '{"status": "ok"}'
|
13
57
|
|
14
58
|
```
|
15
|
-
def delete(
|
16
|
-
url,
|
17
|
-
data: nil,
|
18
|
-
failOnStatusCode: nil,
|
19
|
-
form: nil,
|
20
|
-
headers: nil,
|
21
|
-
ignoreHTTPSErrors: nil,
|
22
|
-
multipart: nil,
|
23
|
-
params: nil,
|
24
|
-
timeout: nil)
|
25
|
-
```
|
26
|
-
|
27
|
-
Sends HTTP(S) [DELETE](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE) request and returns its
|
28
|
-
response. The method will populate request cookies from the context and update context cookies from the response. The
|
29
|
-
method will automatically follow redirects.
|
30
|
-
|
31
|
-
## dispose
|
32
|
-
|
33
|
-
```
|
34
|
-
def dispose
|
35
|
-
```
|
36
|
-
|
37
|
-
All responses returned by [APIRequestContext#get](./api_request_context#get) and similar methods are stored in the memory, so that you
|
38
|
-
can later call [APIResponse#body](./api_response#body). This method discards all stored responses, and makes
|
39
|
-
[APIResponse#body](./api_response#body) throw "Response disposed" error.
|
40
|
-
|
41
|
-
## fetch
|
42
|
-
|
43
|
-
```
|
44
|
-
def fetch(
|
45
|
-
urlOrRequest,
|
46
|
-
data: nil,
|
47
|
-
failOnStatusCode: nil,
|
48
|
-
form: nil,
|
49
|
-
headers: nil,
|
50
|
-
ignoreHTTPSErrors: nil,
|
51
|
-
method: nil,
|
52
|
-
multipart: nil,
|
53
|
-
params: nil,
|
54
|
-
timeout: nil)
|
55
|
-
```
|
56
|
-
|
57
|
-
Sends HTTP(S) request and returns its response. The method will populate request cookies from the context and update
|
58
|
-
context cookies from the response. The method will automatically follow redirects.
|
59
|
-
|
60
|
-
## get
|
61
|
-
|
62
|
-
```
|
63
|
-
def get(
|
64
|
-
url,
|
65
|
-
failOnStatusCode: nil,
|
66
|
-
headers: nil,
|
67
|
-
ignoreHTTPSErrors: nil,
|
68
|
-
params: nil,
|
69
|
-
timeout: nil)
|
70
|
-
```
|
71
|
-
|
72
|
-
Sends HTTP(S) [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET) request and returns its response. The
|
73
|
-
method will populate request cookies from the context and update context cookies from the response. The method will
|
74
|
-
automatically follow redirects.
|
75
|
-
|
76
|
-
## head
|
77
|
-
|
78
|
-
```
|
79
|
-
def head(
|
80
|
-
url,
|
81
|
-
failOnStatusCode: nil,
|
82
|
-
headers: nil,
|
83
|
-
ignoreHTTPSErrors: nil,
|
84
|
-
params: nil,
|
85
|
-
timeout: nil)
|
86
|
-
```
|
87
|
-
|
88
|
-
Sends HTTP(S) [HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD) request and returns its response.
|
89
|
-
The method will populate request cookies from the context and update context cookies from the response. The method will
|
90
|
-
automatically follow redirects.
|
91
|
-
|
92
|
-
## patch
|
93
|
-
|
94
|
-
```
|
95
|
-
def patch(
|
96
|
-
url,
|
97
|
-
data: nil,
|
98
|
-
failOnStatusCode: nil,
|
99
|
-
form: nil,
|
100
|
-
headers: nil,
|
101
|
-
ignoreHTTPSErrors: nil,
|
102
|
-
multipart: nil,
|
103
|
-
params: nil,
|
104
|
-
timeout: nil)
|
105
|
-
```
|
106
|
-
|
107
|
-
Sends HTTP(S) [PATCH](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH) request and returns its response.
|
108
|
-
The method will populate request cookies from the context and update context cookies from the response. The method will
|
109
|
-
automatically follow redirects.
|
110
|
-
|
111
|
-
## post
|
112
|
-
|
113
|
-
```
|
114
|
-
def post(
|
115
|
-
url,
|
116
|
-
data: nil,
|
117
|
-
failOnStatusCode: nil,
|
118
|
-
form: nil,
|
119
|
-
headers: nil,
|
120
|
-
ignoreHTTPSErrors: nil,
|
121
|
-
multipart: nil,
|
122
|
-
params: nil,
|
123
|
-
timeout: nil)
|
124
|
-
```
|
125
|
-
|
126
|
-
Sends HTTP(S) [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) request and returns its response.
|
127
|
-
The method will populate request cookies from the context and update context cookies from the response. The method will
|
128
|
-
automatically follow redirects.
|
129
|
-
|
130
|
-
## put
|
131
|
-
|
132
|
-
```
|
133
|
-
def put(
|
134
|
-
url,
|
135
|
-
data: nil,
|
136
|
-
failOnStatusCode: nil,
|
137
|
-
form: nil,
|
138
|
-
headers: nil,
|
139
|
-
ignoreHTTPSErrors: nil,
|
140
|
-
multipart: nil,
|
141
|
-
params: nil,
|
142
|
-
timeout: nil)
|
143
|
-
```
|
144
59
|
|
145
|
-
Sends HTTP(S) [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT) request and returns its response. The
|
146
|
-
method will populate request cookies from the context and update context cookies from the response. The method will
|
147
|
-
automatically follow redirects.
|
@@ -436,8 +436,4 @@ def expect_page(predicate: nil, timeout: nil)
|
|
436
436
|
Performs action and waits for a new [Page](./page) to be created in the context. If predicate is provided, it passes [Page](./page) value into the `predicate` and waits for `predicate.call(page)` to return a truthy value. Will throw an error if
|
437
437
|
the context closes before new [Page](./page) is created.
|
438
438
|
|
439
|
-
## request
|
440
|
-
|
441
|
-
API testing helper associated with this context. Requests made with this API will use context cookies.
|
442
|
-
|
443
439
|
## tracing
|
@@ -19,9 +19,7 @@ end
|
|
19
19
|
path = download.path
|
20
20
|
```
|
21
21
|
|
22
|
-
|
23
|
-
downloaded content. If `acceptDownloads` is not set, download events are emitted, but the actual download is not
|
24
|
-
performed and user has no access to the downloaded files.
|
22
|
+
|
25
23
|
|
26
24
|
## cancel
|
27
25
|
|
@@ -26,6 +26,15 @@ page.frame_locator('.result-frame').locator('button').click
|
|
26
26
|
page.frame_locator('.result-frame').first.locator('button').click
|
27
27
|
```
|
28
28
|
|
29
|
+
**Converting Locator to FrameLocator**
|
30
|
+
|
31
|
+
If you have a [Locator](./locator) object pointing to an `iframe` it can be converted to [FrameLocator](./frame_locator) using
|
32
|
+
[`:scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/:scope) CSS selector:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
frame_locator = locator.frame_locator(':scope')
|
36
|
+
```
|
37
|
+
|
29
38
|
|
30
39
|
|
31
40
|
## first
|
@@ -56,7 +65,7 @@ Returns locator to the last matching frame.
|
|
56
65
|
## locator
|
57
66
|
|
58
67
|
```
|
59
|
-
def locator(selector)
|
68
|
+
def locator(selector, hasText: nil)
|
60
69
|
```
|
61
70
|
|
62
71
|
The method finds an element matching the specified selector in the FrameLocator's subtree.
|
@@ -4,53 +4,10 @@ sidebar_position: 10
|
|
4
4
|
|
5
5
|
# Locator
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
locator = page.locator("text=Submit")
|
12
|
-
locator.click
|
13
|
-
```
|
14
|
-
|
15
|
-
The difference between the Locator and [ElementHandle](./element_handle) is that the latter points to a particular element, while Locator
|
16
|
-
captures the logic of how to retrieve that element.
|
17
|
-
|
18
|
-
In the example below, handle points to a particular DOM element on page. If that element changes text or is used by
|
19
|
-
React to render an entirely different component, handle is still pointing to that very DOM element. This can lead to
|
20
|
-
unexpected behaviors.
|
21
|
-
|
22
|
-
```ruby
|
23
|
-
handle = page.query_selector("text=Submit")
|
24
|
-
handle.hover
|
25
|
-
handle.click
|
26
|
-
```
|
27
|
-
|
28
|
-
With the locator, every time the `element` is used, up-to-date DOM element is located in the page using the selector. So
|
29
|
-
in the snippet below, underlying DOM element is going to be located twice.
|
30
|
-
|
31
|
-
```ruby
|
32
|
-
locator = page.locator("text=Submit")
|
33
|
-
locator.hover
|
34
|
-
locator.click
|
35
|
-
```
|
36
|
-
|
37
|
-
**Strictness**
|
38
|
-
|
39
|
-
Locators are strict. This means that all operations on locators that imply some target DOM element will throw if more
|
40
|
-
than one element matches given selector.
|
41
|
-
|
42
|
-
```ruby
|
43
|
-
# Throws if there are several buttons in DOM:
|
44
|
-
page.locator('button').click
|
45
|
-
|
46
|
-
# Works because we explicitly tell locator to pick the first element:
|
47
|
-
page.locator('button').first.click
|
48
|
-
|
49
|
-
# Works because count knows what to do with multiple matches:
|
50
|
-
page.locator('button').count
|
51
|
-
```
|
52
|
-
|
7
|
+
Locators are the central piece of Playwright's auto-waiting and retry-ability. In a nutshell, locators represent a way
|
8
|
+
to find element(s) on the page at any moment. Locator can be created with the [Page#locator](./page#locator) method.
|
53
9
|
|
10
|
+
[Learn more about locators](https://playwright.dev/python/docs/locators).
|
54
11
|
|
55
12
|
## all_inner_texts
|
56
13
|
|
@@ -220,6 +177,21 @@ element.dispatch_event("dragstart", eventInit: { dataTransfer: data_transfer })
|
|
220
177
|
|
221
178
|
|
222
179
|
|
180
|
+
## drag_to
|
181
|
+
|
182
|
+
```
|
183
|
+
def drag_to(
|
184
|
+
target,
|
185
|
+
force: nil,
|
186
|
+
noWaitAfter: nil,
|
187
|
+
sourcePosition: nil,
|
188
|
+
targetPosition: nil,
|
189
|
+
timeout: nil,
|
190
|
+
trial: nil)
|
191
|
+
```
|
192
|
+
|
193
|
+
|
194
|
+
|
223
195
|
## element_handle
|
224
196
|
|
225
197
|
```
|
@@ -458,7 +430,7 @@ Returns locator to the last matching element.
|
|
458
430
|
## locator
|
459
431
|
|
460
432
|
```
|
461
|
-
def locator(selector)
|
433
|
+
def locator(selector, hasText: nil)
|
462
434
|
```
|
463
435
|
|
464
436
|
The method finds an element matching the specified selector in the [Locator](./locator)'s subtree.
|
@@ -1,5 +1,17 @@
|
|
1
1
|
# API coverages
|
2
2
|
|
3
|
+
## APIRequestContext
|
4
|
+
|
5
|
+
* ~~delete~~
|
6
|
+
* ~~dispose~~
|
7
|
+
* ~~fetch~~
|
8
|
+
* ~~get~~
|
9
|
+
* ~~head~~
|
10
|
+
* ~~patch~~
|
11
|
+
* ~~post~~
|
12
|
+
* ~~put~~
|
13
|
+
* ~~storage_state~~
|
14
|
+
|
3
15
|
## Request
|
4
16
|
|
5
17
|
* all_headers
|
@@ -319,6 +331,7 @@
|
|
319
331
|
* accessibility
|
320
332
|
* keyboard
|
321
333
|
* mouse
|
334
|
+
* ~~request~~
|
322
335
|
* touchscreen
|
323
336
|
|
324
337
|
## BrowserContext
|
@@ -349,7 +362,7 @@
|
|
349
362
|
* expect_event
|
350
363
|
* expect_page
|
351
364
|
* ~~wait_for_event~~
|
352
|
-
* request
|
365
|
+
* ~~request~~
|
353
366
|
* tracing
|
354
367
|
|
355
368
|
## CDPSession
|
@@ -405,6 +418,7 @@
|
|
405
418
|
* count
|
406
419
|
* dblclick
|
407
420
|
* dispatch_event
|
421
|
+
* drag_to
|
408
422
|
* element_handle
|
409
423
|
* element_handles
|
410
424
|
* evaluate
|
@@ -449,34 +463,8 @@
|
|
449
463
|
* locator
|
450
464
|
* nth
|
451
465
|
|
452
|
-
##
|
453
|
-
|
454
|
-
* body
|
455
|
-
* dispose
|
456
|
-
* headers
|
457
|
-
* headers_array
|
458
|
-
* json
|
459
|
-
* ok
|
460
|
-
* status
|
461
|
-
* status_text
|
462
|
-
* text
|
463
|
-
* url
|
464
|
-
|
465
|
-
## APIRequestContext
|
466
|
-
|
467
|
-
* delete
|
468
|
-
* dispose
|
469
|
-
* fetch
|
470
|
-
* get
|
471
|
-
* head
|
472
|
-
* patch
|
473
|
-
* post
|
474
|
-
* put
|
475
|
-
* ~~storage_state~~
|
476
|
-
|
477
|
-
## ~~APIRequest~~
|
466
|
+
## LocalUtils
|
478
467
|
|
479
|
-
* ~~new_context~~
|
480
468
|
|
481
469
|
## Android
|
482
470
|
|
@@ -1,236 +1,4 @@
|
|
1
|
-
require 'base64'
|
2
|
-
|
3
1
|
module Playwright
|
4
2
|
define_channel_owner :APIRequestContext do
|
5
|
-
def dispose
|
6
|
-
@channel.send_message_to_server('dispose')
|
7
|
-
end
|
8
|
-
|
9
|
-
def delete(
|
10
|
-
url,
|
11
|
-
data: nil,
|
12
|
-
failOnStatusCode: nil,
|
13
|
-
form: nil,
|
14
|
-
headers: nil,
|
15
|
-
ignoreHTTPSErrors: nil,
|
16
|
-
multipart: nil,
|
17
|
-
params: nil,
|
18
|
-
timeout: nil)
|
19
|
-
fetch(
|
20
|
-
url,
|
21
|
-
method: 'DELETE',
|
22
|
-
data: data,
|
23
|
-
failOnStatusCode: failOnStatusCode,
|
24
|
-
form: form,
|
25
|
-
headers: headers,
|
26
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
27
|
-
multipart: multipart,
|
28
|
-
params: params,
|
29
|
-
timeout: timeout,
|
30
|
-
)
|
31
|
-
end
|
32
|
-
|
33
|
-
def head(
|
34
|
-
url,
|
35
|
-
failOnStatusCode: nil,
|
36
|
-
headers: nil,
|
37
|
-
ignoreHTTPSErrors: nil,
|
38
|
-
params: nil,
|
39
|
-
timeout: nil)
|
40
|
-
fetch(
|
41
|
-
url,
|
42
|
-
method: 'HEAD',
|
43
|
-
failOnStatusCode: failOnStatusCode,
|
44
|
-
headers: headers,
|
45
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
46
|
-
params: params,
|
47
|
-
timeout: timeout,
|
48
|
-
)
|
49
|
-
end
|
50
|
-
|
51
|
-
def get(
|
52
|
-
url,
|
53
|
-
failOnStatusCode: nil,
|
54
|
-
headers: nil,
|
55
|
-
ignoreHTTPSErrors: nil,
|
56
|
-
params: nil,
|
57
|
-
timeout: nil)
|
58
|
-
fetch(
|
59
|
-
url,
|
60
|
-
method: 'GET',
|
61
|
-
failOnStatusCode: failOnStatusCode,
|
62
|
-
headers: headers,
|
63
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
64
|
-
params: params,
|
65
|
-
timeout: timeout,
|
66
|
-
)
|
67
|
-
end
|
68
|
-
|
69
|
-
def patch(
|
70
|
-
url,
|
71
|
-
data: nil,
|
72
|
-
failOnStatusCode: nil,
|
73
|
-
form: nil,
|
74
|
-
headers: nil,
|
75
|
-
ignoreHTTPSErrors: nil,
|
76
|
-
multipart: nil,
|
77
|
-
params: nil,
|
78
|
-
timeout: nil)
|
79
|
-
fetch(
|
80
|
-
url,
|
81
|
-
method: 'PATCH',
|
82
|
-
data: data,
|
83
|
-
failOnStatusCode: failOnStatusCode,
|
84
|
-
form: form,
|
85
|
-
headers: headers,
|
86
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
87
|
-
multipart: multipart,
|
88
|
-
params: params,
|
89
|
-
timeout: timeout,
|
90
|
-
)
|
91
|
-
end
|
92
|
-
|
93
|
-
def put(
|
94
|
-
url,
|
95
|
-
data: nil,
|
96
|
-
failOnStatusCode: nil,
|
97
|
-
form: nil,
|
98
|
-
headers: nil,
|
99
|
-
ignoreHTTPSErrors: nil,
|
100
|
-
multipart: nil,
|
101
|
-
params: nil,
|
102
|
-
timeout: nil)
|
103
|
-
fetch(
|
104
|
-
url,
|
105
|
-
method: 'PUT',
|
106
|
-
data: data,
|
107
|
-
failOnStatusCode: failOnStatusCode,
|
108
|
-
form: form,
|
109
|
-
headers: headers,
|
110
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
111
|
-
multipart: multipart,
|
112
|
-
params: params,
|
113
|
-
timeout: timeout,
|
114
|
-
)
|
115
|
-
end
|
116
|
-
|
117
|
-
def post(
|
118
|
-
url,
|
119
|
-
data: nil,
|
120
|
-
failOnStatusCode: nil,
|
121
|
-
form: nil,
|
122
|
-
headers: nil,
|
123
|
-
ignoreHTTPSErrors: nil,
|
124
|
-
multipart: nil,
|
125
|
-
params: nil,
|
126
|
-
timeout: nil)
|
127
|
-
fetch(
|
128
|
-
url,
|
129
|
-
method: 'POST',
|
130
|
-
data: data,
|
131
|
-
failOnStatusCode: failOnStatusCode,
|
132
|
-
form: form,
|
133
|
-
headers: headers,
|
134
|
-
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
135
|
-
multipart: multipart,
|
136
|
-
params: params,
|
137
|
-
timeout: timeout,
|
138
|
-
)
|
139
|
-
end
|
140
|
-
|
141
|
-
def fetch(
|
142
|
-
urlOrRequest,
|
143
|
-
data: nil,
|
144
|
-
failOnStatusCode: nil,
|
145
|
-
form: nil,
|
146
|
-
headers: nil,
|
147
|
-
ignoreHTTPSErrors: nil,
|
148
|
-
method: nil,
|
149
|
-
multipart: nil,
|
150
|
-
params: nil,
|
151
|
-
timeout: nil)
|
152
|
-
|
153
|
-
if [ChannelOwners::Request, String].none? { |type| urlOrRequest.is_a?(type) }
|
154
|
-
raise ArgumentError.new("First argument must be either URL string or Request")
|
155
|
-
end
|
156
|
-
if [data, form, multipart].compact.count > 1
|
157
|
-
raise ArgumentError.new("Only one of 'data', 'form' or 'multipart' can be specified")
|
158
|
-
end
|
159
|
-
|
160
|
-
request = urlOrRequest.is_a?(ChannelOwners::Request) ? urlOrRequest : nil
|
161
|
-
headers_obj = headers || request&.headers
|
162
|
-
fetch_params = {
|
163
|
-
url: request&.url || urlOrRequest,
|
164
|
-
params: object_to_array(params),
|
165
|
-
method: method || request&.method || 'GET',
|
166
|
-
headers: headers_obj ? HttpHeaders.new(headers_obj).as_serialized : nil,
|
167
|
-
}
|
168
|
-
|
169
|
-
json_data = nil
|
170
|
-
form_data = nil
|
171
|
-
multipart_data = nil
|
172
|
-
post_data_buffer = nil
|
173
|
-
if data
|
174
|
-
case data
|
175
|
-
when String
|
176
|
-
if headers_obj&.any? { |key, value| key.downcase == 'content-type' && value == 'application/json' }
|
177
|
-
json_data = data
|
178
|
-
else
|
179
|
-
post_data_buffer = data
|
180
|
-
end
|
181
|
-
when Hash, Array, Numeric, true, false
|
182
|
-
json_data = data
|
183
|
-
else
|
184
|
-
raise ArgumentError.new("Unsupported 'data' type: #{data.class}")
|
185
|
-
end
|
186
|
-
elsif form
|
187
|
-
form_data = object_to_array(form)
|
188
|
-
elsif multipart
|
189
|
-
multipart_data = multipart.map do |name, value|
|
190
|
-
if file_payload?(value)
|
191
|
-
{ name: name, file: file_payload_to_json(value) }
|
192
|
-
else
|
193
|
-
{ name: name, value: value.to_s }
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
if !json_data && !form_data && !multipart_data
|
199
|
-
post_data_buffer ||= request&.post_data_buffer
|
200
|
-
end
|
201
|
-
if post_data_buffer
|
202
|
-
fetch_params[:postData] = Base64.strict_encode64(post_data_buffer)
|
203
|
-
end
|
204
|
-
|
205
|
-
fetch_params[:jsonData] = json_data
|
206
|
-
fetch_params[:formData] = form_data
|
207
|
-
fetch_params[:multipartData] = multipart_data
|
208
|
-
fetch_params[:timeout] = timeout
|
209
|
-
fetch_params[:failOnStatusCode] = failOnStatusCode
|
210
|
-
fetch_params[:ignoreHTTPSErrors] = ignoreHTTPSErrors
|
211
|
-
fetch_params.compact!
|
212
|
-
response = @channel.send_message_to_server('fetch', fetch_params)
|
213
|
-
|
214
|
-
APIResponseImpl.new(self, response)
|
215
|
-
end
|
216
|
-
|
217
|
-
private def file_payload?(value)
|
218
|
-
value.is_a?(Hash) &&
|
219
|
-
%w(name mimeType buffer).all? { |key| value.has_key?(key) || value.has_key?(key.to_sym) }
|
220
|
-
end
|
221
|
-
|
222
|
-
private def file_payload_to_json(payload)
|
223
|
-
{
|
224
|
-
name: payload[:name] || payload['name'],
|
225
|
-
mimeType: payload[:mimeType] || payload['mimeType'],
|
226
|
-
buffer: Base64.strict_encode64(payload[:buffer] || payload['buffer'])
|
227
|
-
}
|
228
|
-
end
|
229
|
-
|
230
|
-
private def object_to_array(hash)
|
231
|
-
hash&.map do |key, value|
|
232
|
-
{ name: key, value: value.to_s }
|
233
|
-
end
|
234
|
-
end
|
235
3
|
end
|
236
4
|
end
|
@@ -4,7 +4,7 @@ module Playwright
|
|
4
4
|
include Utils::Errors::SafeCloseError
|
5
5
|
attr_accessor :browser
|
6
6
|
attr_writer :owner_page, :options
|
7
|
-
attr_reader :tracing
|
7
|
+
attr_reader :tracing
|
8
8
|
|
9
9
|
private def after_initialize
|
10
10
|
@pages = Set.new
|
@@ -15,8 +15,6 @@ module Playwright
|
|
15
15
|
@background_pages = Set.new
|
16
16
|
|
17
17
|
@tracing = TracingImpl.new(@channel, self)
|
18
|
-
@request = ChannelOwners::APIRequestContext.from(@initializer['APIRequestContext'])
|
19
|
-
|
20
18
|
@channel.on('bindingCall', ->(params) { on_binding(ChannelOwners::BindingCall.from(params['binding'])) })
|
21
19
|
@channel.once('close', ->(_) { on_close })
|
22
20
|
@channel.on('page', ->(params) { on_page(ChannelOwners::Page.from(params['page']) )})
|
@@ -360,5 +358,10 @@ module Playwright
|
|
360
358
|
private def base_url
|
361
359
|
@options[:baseURL]
|
362
360
|
end
|
361
|
+
|
362
|
+
# called from Tracing
|
363
|
+
private def remote_connection?
|
364
|
+
@connection.remote?
|
365
|
+
end
|
363
366
|
end
|
364
367
|
end
|
@@ -400,8 +400,8 @@ module Playwright
|
|
400
400
|
nil
|
401
401
|
end
|
402
402
|
|
403
|
-
def locator(selector)
|
404
|
-
LocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), selector: selector)
|
403
|
+
def locator(selector, hasText: nil)
|
404
|
+
LocatorImpl.new(frame: self, timeout_settings: @page.send(:timeout_settings), selector: selector, hasText: hasText)
|
405
405
|
end
|
406
406
|
|
407
407
|
def frame_locator(selector)
|