playwright-ruby-client 1.17.1 → 1.18.beta1
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.
- 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)
|