playwright-ruby-client 1.62.0 → 1.63.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.
- checksums.yaml +4 -4
- data/documentation/docs/api/api_request_context.md +3 -0
- data/documentation/docs/api/browser_context.md +3 -3
- data/documentation/docs/api/frame.md +12 -1
- data/documentation/docs/api/frame_locator.md +20 -0
- data/documentation/docs/api/locator.md +28 -0
- data/documentation/docs/api/page.md +12 -1
- data/documentation/docs/api/tracing.md +3 -1
- data/documentation/docs/article/guides/playwright_on_alpine_linux.md +1 -1
- data/documentation/docs/include/api_coverage.md +1 -0
- data/lib/playwright/api_request_impl.rb +3 -1
- data/lib/playwright/channel.rb +2 -1
- data/lib/playwright/channel_owners/browser.rb +1 -0
- data/lib/playwright/channel_owners/browser_context.rb +17 -2
- data/lib/playwright/channel_owners/frame.rb +2 -2
- data/lib/playwright/channel_owners/page.rb +2 -1
- data/lib/playwright/channel_owners/tracing.rb +43 -13
- data/lib/playwright/events.rb +2 -0
- data/lib/playwright/frame_locator_impl.rb +20 -5
- data/lib/playwright/locator_impl.rb +4 -0
- data/lib/playwright/utils.rb +12 -0
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright_api/api_request_context.rb +9 -7
- data/lib/playwright_api/browser.rb +6 -6
- data/lib/playwright_api/browser_context.rb +17 -17
- data/lib/playwright_api/browser_type.rb +6 -6
- data/lib/playwright_api/cdp_session.rb +6 -6
- data/lib/playwright_api/dialog.rb +6 -6
- data/lib/playwright_api/element_handle.rb +6 -6
- data/lib/playwright_api/frame.rb +25 -14
- data/lib/playwright_api/frame_locator.rb +20 -0
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/locator.rb +25 -0
- data/lib/playwright_api/page.rb +28 -17
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +8 -8
- data/lib/playwright_api/response.rb +6 -6
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/tracing.rb +10 -8
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/worker.rb +8 -8
- data/sig/playwright.rbs +9 -8
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 275e62d0e3c798dd08cdb59a52299af990f93b7fd5fe1cf2a1f9b1c5441a1680
|
|
4
|
+
data.tar.gz: 1711ed5665344b5c52b6f45c2621e03e2ac8983d698e6717303cad3bbb80659b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9180d7ceb51f46c828e8a08aaffdd1e813bc57b842f268556990030a9003686841842cd8d3f5c98ea8b5c2ea3e6fdb63a4ff45afb6e44adb2b2a9a6c7c6ef861
|
|
7
|
+
data.tar.gz: 5efd8cd40f2e8b5d2cf2e22943ae6df4e3791b66874ca3cb0f72bbb66a1bd50442e8e481c990eed9fe958f4bfe82102e58634c5bfd2bc1823a0ff25b16036bbf
|
|
@@ -434,11 +434,11 @@ alias: `offline=`
|
|
|
434
434
|
## storage_state
|
|
435
435
|
|
|
436
436
|
```
|
|
437
|
-
def storage_state(credentials: nil, indexedDB: nil, path: nil)
|
|
437
|
+
def storage_state(credentials: nil, indexedDB: nil, opfs: nil, path: nil)
|
|
438
438
|
```
|
|
439
439
|
|
|
440
440
|
|
|
441
|
-
Returns storage state for this browser context, contains current cookies, local storage snapshot, IndexedDB snapshot and virtual WebAuthn credentials.
|
|
441
|
+
Returns storage state for this browser context, contains current cookies, local storage snapshot, IndexedDB snapshot, origin private file system snapshot and virtual WebAuthn credentials.
|
|
442
442
|
|
|
443
443
|
## set_storage_state
|
|
444
444
|
|
|
@@ -448,7 +448,7 @@ def set_storage_state(storageState)
|
|
|
448
448
|
alias: `storage_state=`
|
|
449
449
|
|
|
450
450
|
|
|
451
|
-
Clears the existing cookies, local storage, IndexedDB entries and virtual WebAuthn credentials, and sets the new storage
|
|
451
|
+
Clears the existing cookies, local storage, IndexedDB entries, origin private file system entries and virtual WebAuthn credentials, and sets the new storage
|
|
452
452
|
state. When the storage state contains credentials, the virtual WebAuthn authenticator is installed (equivalent to
|
|
453
453
|
[Credentials#install](./credentials#install)), preventing all real authenticators from working in this context.
|
|
454
454
|
|
|
@@ -391,13 +391,17 @@ puts frame == content_frame # => true
|
|
|
391
391
|
## frame_locator
|
|
392
392
|
|
|
393
393
|
```
|
|
394
|
-
def frame_locator(selector)
|
|
394
|
+
def frame_locator(selector = nil)
|
|
395
395
|
```
|
|
396
396
|
|
|
397
397
|
|
|
398
398
|
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements
|
|
399
399
|
in that iframe.
|
|
400
400
|
|
|
401
|
+
When called without `selector`, the search starts in this frame or in any of the iframes inside it,
|
|
402
|
+
so that you don't need to locate each iframe first. Note that the rest of the locator is resolved inside a single
|
|
403
|
+
frame, just like any other locator. If it matches elements inside multiple frames, an error is thrown.
|
|
404
|
+
|
|
401
405
|
**Usage**
|
|
402
406
|
|
|
403
407
|
Following snippet locates element with text "Submit" in the iframe with id `my-frame`, like `<iframe id="my-frame">`:
|
|
@@ -407,6 +411,13 @@ locator = frame.frame_locator("#my-iframe").get_by_text("Submit")
|
|
|
407
411
|
locator.click
|
|
408
412
|
```
|
|
409
413
|
|
|
414
|
+
Following snippet locates a button, either in the frame or in one of the iframes inside it:
|
|
415
|
+
|
|
416
|
+
```ruby
|
|
417
|
+
locator = frame.frame_locator.get_by_role('button')
|
|
418
|
+
locator.click
|
|
419
|
+
```
|
|
420
|
+
|
|
410
421
|
## get_attribute
|
|
411
422
|
|
|
412
423
|
```
|
|
@@ -24,6 +24,26 @@ page.locator('.result-frame').content_frame.get_by_role('button').click
|
|
|
24
24
|
page.locator('.result-frame').first.content_frame.get_by_role('button').click
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
**Any frame**
|
|
28
|
+
|
|
29
|
+
Calling [Page#frame_locator](./page#frame_locator) or [Frame#frame_locator](./frame#frame_locator) without a selector creates a frame locator that
|
|
30
|
+
starts the search in any frame of the subtree - so that you don't
|
|
31
|
+
need to locate the iframe first.
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
# Finds the button in any frame on the page:
|
|
35
|
+
page.frame_locator.get_by_role('button').click
|
|
36
|
+
|
|
37
|
+
# Finds the iframe anywhere on the page and clicks the button inside it:
|
|
38
|
+
page.frame_locator.locator('#my-frame').content_frame.get_by_role('button').click
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Only the start of the search is affected - the rest of the locator is resolved inside a single frame, just like any
|
|
42
|
+
other locator. Following the strictness rules above, an error is thrown when elements are matched in multiple frames.
|
|
43
|
+
|
|
44
|
+
Such a frame locator does not point to a particular `iframe`, so [FrameLocator#owner](./frame_locator#owner),
|
|
45
|
+
[FrameLocator#first](./frame_locator#first), [FrameLocator#last](./frame_locator#last) and [FrameLocator#nth](./frame_locator#nth) are not supported on it.
|
|
46
|
+
|
|
27
47
|
**Converting Locator to FrameLocator**
|
|
28
48
|
|
|
29
49
|
If you have a [Locator](./locator) object pointing to an `iframe` it can be converted to [FrameLocator](./frame_locator) using [Locator#content_frame](./locator#content_frame).
|
|
@@ -1531,6 +1531,34 @@ If the element is detached from the DOM at any moment during the action, this me
|
|
|
1531
1531
|
When all steps combined have not finished during the specified `timeout`, this method throws a
|
|
1532
1532
|
`TimeoutError`. Passing zero timeout disables this.
|
|
1533
1533
|
|
|
1534
|
+
## visible
|
|
1535
|
+
|
|
1536
|
+
```
|
|
1537
|
+
def visible
|
|
1538
|
+
```
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
Returns a locator that matches only [visible](https://playwright.dev/python/docs/actionability#visible) elements, ignoring the invisible ones. This is the recommended way to distinguish elements by visibility, as opposed to the `:visible` CSS pseudo-class.
|
|
1542
|
+
|
|
1543
|
+
Note that visibility is checked every time the locator is used, and not at the moment of the [Locator#visible](./locator#visible) call.
|
|
1544
|
+
|
|
1545
|
+
**Usage**
|
|
1546
|
+
|
|
1547
|
+
Consider a page with two buttons, the first invisible and the second visible.
|
|
1548
|
+
|
|
1549
|
+
```html
|
|
1550
|
+
<button style='display: none'>Invisible</button>
|
|
1551
|
+
<button>Visible</button>
|
|
1552
|
+
```
|
|
1553
|
+
|
|
1554
|
+
This will only find the second button, because it is visible, and then click it.
|
|
1555
|
+
|
|
1556
|
+
```ruby
|
|
1557
|
+
page.locator('button').visible.click
|
|
1558
|
+
```
|
|
1559
|
+
|
|
1560
|
+
To match invisible elements instead, use [Locator#filter](./locator#filter) with the `visible` option set to `false`.
|
|
1561
|
+
|
|
1534
1562
|
## wait_for
|
|
1535
1563
|
|
|
1536
1564
|
```
|
|
@@ -585,13 +585,17 @@ frame = page.frame(url: /.*domain.*/)
|
|
|
585
585
|
## frame_locator
|
|
586
586
|
|
|
587
587
|
```
|
|
588
|
-
def frame_locator(selector)
|
|
588
|
+
def frame_locator(selector = nil)
|
|
589
589
|
```
|
|
590
590
|
|
|
591
591
|
|
|
592
592
|
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements
|
|
593
593
|
in that iframe.
|
|
594
594
|
|
|
595
|
+
When called without `selector`, the search starts in any frame on the page - the main frame or any of
|
|
596
|
+
the iframes - so that you don't need to locate each iframe first. Note that the rest of the locator is resolved
|
|
597
|
+
inside a single frame, just like any other locator. If it matches elements inside multiple frames, an error is thrown.
|
|
598
|
+
|
|
595
599
|
**Usage**
|
|
596
600
|
|
|
597
601
|
Following snippet locates element with text "Submit" in the iframe with id `my-frame`,
|
|
@@ -602,6 +606,13 @@ locator = page.frame_locator("#my-iframe").get_by_text("Submit")
|
|
|
602
606
|
locator.click
|
|
603
607
|
```
|
|
604
608
|
|
|
609
|
+
Following snippet locates a button, either in the main frame or in one of the iframes:
|
|
610
|
+
|
|
611
|
+
```ruby
|
|
612
|
+
locator = page.frame_locator.get_by_role('button')
|
|
613
|
+
locator.click
|
|
614
|
+
```
|
|
615
|
+
|
|
605
616
|
## frames
|
|
606
617
|
|
|
607
618
|
```
|
|
@@ -26,9 +26,11 @@ end
|
|
|
26
26
|
|
|
27
27
|
```
|
|
28
28
|
def start(
|
|
29
|
+
ariaSnapshots: nil,
|
|
29
30
|
live: nil,
|
|
30
31
|
name: nil,
|
|
31
32
|
screenshots: nil,
|
|
33
|
+
screenSnapshots: nil,
|
|
32
34
|
snapshots: nil,
|
|
33
35
|
sources: nil,
|
|
34
36
|
title: nil)
|
|
@@ -86,7 +88,7 @@ def start_har(path, content: nil, mode: nil, urlFilter: nil)
|
|
|
86
88
|
|
|
87
89
|
Start recording a HAR (HTTP Archive) of network activity in this context. The HAR file is written to disk when [Tracing#stop_har](./tracing#stop_har) is called, or when the returned `Disposable` is disposed.
|
|
88
90
|
|
|
89
|
-
Only one HAR recording can be active at a time per [
|
|
91
|
+
Only one HAR recording can be active at a time per [Tracing](./tracing) instance.
|
|
90
92
|
|
|
91
93
|
**Usage**
|
|
92
94
|
|
|
@@ -83,7 +83,7 @@ If custom Docker image is preferred, build it as follows:
|
|
|
83
83
|
FROM mcr.microsoft.com/playwright
|
|
84
84
|
|
|
85
85
|
WORKDIR /root
|
|
86
|
-
ARG PLAYWRIGHT_CORE_VERSION=1.
|
|
86
|
+
ARG PLAYWRIGHT_CORE_VERSION=1.63.0
|
|
87
87
|
RUN npm install "playwright-core@$PLAYWRIGHT_CORE_VERSION" && ./node_modules/.bin/playwright-core install
|
|
88
88
|
|
|
89
89
|
ENV PORT 8888
|
|
@@ -3,6 +3,8 @@ require 'json'
|
|
|
3
3
|
|
|
4
4
|
module Playwright
|
|
5
5
|
define_api_implementation :APIRequestImpl do
|
|
6
|
+
include Utils::PrepareHttpCredentials
|
|
7
|
+
|
|
6
8
|
def initialize(playwright)
|
|
7
9
|
@playwright = playwright
|
|
8
10
|
end
|
|
@@ -24,7 +26,7 @@ module Playwright
|
|
|
24
26
|
clientCertificates: prepare_client_certificates(clientCertificates),
|
|
25
27
|
extraHTTPHeaders: extraHTTPHeaders ? HttpHeaders.new(extraHTTPHeaders).as_serialized : nil,
|
|
26
28
|
failOnStatusCode: failOnStatusCode,
|
|
27
|
-
httpCredentials: httpCredentials,
|
|
29
|
+
httpCredentials: prepare_http_credentials(httpCredentials),
|
|
28
30
|
ignoreHTTPSErrors: ignoreHTTPSErrors,
|
|
29
31
|
maxRedirects: maxRedirects,
|
|
30
32
|
proxy: proxy,
|
data/lib/playwright/channel.rb
CHANGED
|
@@ -75,7 +75,8 @@ module Playwright
|
|
|
75
75
|
wallTime: (Time.now.to_f * 1000).to_i,
|
|
76
76
|
apiName: api_name,
|
|
77
77
|
stack: stacks.map do |loc|
|
|
78
|
-
|
|
78
|
+
# Ruby backtraces do not provide a column, but the trace protocol requires one.
|
|
79
|
+
{ file: loc.absolute_path || '', line: loc.lineno, column: 0, function: loc.label }
|
|
79
80
|
end,
|
|
80
81
|
}
|
|
81
82
|
end
|
|
@@ -156,6 +156,7 @@ module Playwright
|
|
|
156
156
|
|
|
157
157
|
private def setup_browser_context(context)
|
|
158
158
|
context.tracing.send(:update_traces_dir, @traces_dir)
|
|
159
|
+
context.request.tracing.send(:update_traces_dir, @traces_dir)
|
|
159
160
|
@browser_type.send(:playwright_selectors_browser_contexts) << context
|
|
160
161
|
end
|
|
161
162
|
|
|
@@ -42,6 +42,11 @@ module Playwright
|
|
|
42
42
|
@channel.on('dialog', ->(params) {
|
|
43
43
|
on_dialog(ChannelOwners::Dialog.from(params['dialog']))
|
|
44
44
|
})
|
|
45
|
+
@channel.on('dialogClosed', ->(params) {
|
|
46
|
+
dialog = ChannelOwners::Dialog.from(params['dialog'])
|
|
47
|
+
emit(Events::BrowserContext::DialogClosed, dialog)
|
|
48
|
+
dialog.page&.emit(Events::Page::DialogClosed, dialog)
|
|
49
|
+
})
|
|
45
50
|
@channel.on('request', ->(params) {
|
|
46
51
|
on_request(
|
|
47
52
|
ChannelOwners::Request.from(params['request']),
|
|
@@ -69,6 +74,7 @@ module Playwright
|
|
|
69
74
|
set_event_to_subscription_mapping({
|
|
70
75
|
Events::BrowserContext::Console => 'console',
|
|
71
76
|
Events::BrowserContext::Dialog => 'dialog',
|
|
77
|
+
Events::BrowserContext::DialogClosed => 'dialogClosed',
|
|
72
78
|
Events::BrowserContext::Request => "request",
|
|
73
79
|
Events::BrowserContext::Response => "response",
|
|
74
80
|
Events::BrowserContext::RequestFinished => "requestFinished",
|
|
@@ -93,6 +99,7 @@ module Playwright
|
|
|
93
99
|
private def update_options(context_options:, browser_options:)
|
|
94
100
|
@options = context_options
|
|
95
101
|
@tracing.send(:update_traces_dir, browser_options[:tracesDir])
|
|
102
|
+
@request.tracing.send(:update_traces_dir, browser_options[:tracesDir])
|
|
96
103
|
end
|
|
97
104
|
|
|
98
105
|
private def on_page(page)
|
|
@@ -418,6 +425,7 @@ module Playwright
|
|
|
418
425
|
@browser.browser_type.send(:playwright_selectors_browser_contexts).delete(self)
|
|
419
426
|
end
|
|
420
427
|
@tracing.send(:reset_stack_counter)
|
|
428
|
+
@request.tracing.send(:reset_stack_counter)
|
|
421
429
|
emit(Events::BrowserContext::Close)
|
|
422
430
|
@closed_promise.fulfill(true)
|
|
423
431
|
end
|
|
@@ -427,9 +435,15 @@ module Playwright
|
|
|
427
435
|
@close_was_called = true
|
|
428
436
|
@close_reason = reason
|
|
429
437
|
@request.dispose(reason: reason)
|
|
430
|
-
|
|
438
|
+
har_error = nil
|
|
439
|
+
begin
|
|
440
|
+
@tracing.send(:export_all_hars)
|
|
441
|
+
rescue => error
|
|
442
|
+
har_error = error
|
|
443
|
+
end
|
|
431
444
|
@channel.send_message_to_server('close', { reason: reason }.compact)
|
|
432
445
|
@closed_promise.value!
|
|
446
|
+
raise har_error if har_error
|
|
433
447
|
nil
|
|
434
448
|
end
|
|
435
449
|
|
|
@@ -462,9 +476,10 @@ module Playwright
|
|
|
462
476
|
@channel.send_message_to_server('pause')
|
|
463
477
|
end
|
|
464
478
|
|
|
465
|
-
def storage_state(path: nil, indexedDB: nil, credentials: nil)
|
|
479
|
+
def storage_state(path: nil, indexedDB: nil, opfs: nil, credentials: nil)
|
|
466
480
|
params = {
|
|
467
481
|
indexedDB: indexedDB,
|
|
482
|
+
opfs: opfs,
|
|
468
483
|
credentials: credentials,
|
|
469
484
|
}.compact
|
|
470
485
|
@channel.send_message_to_server_result('storageState', params).tap do |result|
|
|
@@ -506,8 +506,8 @@ module Playwright
|
|
|
506
506
|
hasText: hasText)
|
|
507
507
|
end
|
|
508
508
|
|
|
509
|
-
def frame_locator(selector)
|
|
510
|
-
FrameLocatorImpl.new(frame: self, frame_selector: selector)
|
|
509
|
+
def frame_locator(selector = nil)
|
|
510
|
+
FrameLocatorImpl.new(frame: self, frame_selector: selector || 'internal:control=any-frame')
|
|
511
511
|
end
|
|
512
512
|
|
|
513
513
|
def focus(selector, strict: nil, timeout: nil)
|
|
@@ -72,6 +72,7 @@ module Playwright
|
|
|
72
72
|
set_event_to_subscription_mapping({
|
|
73
73
|
Events::Page::Console => "console",
|
|
74
74
|
Events::Page::Dialog => "dialog",
|
|
75
|
+
Events::Page::DialogClosed => "dialogClosed",
|
|
75
76
|
Events::Page::Request => "request",
|
|
76
77
|
Events::Page::Response => "response",
|
|
77
78
|
Events::Page::RequestFinished => "requestFinished",
|
|
@@ -723,7 +724,7 @@ module Playwright
|
|
|
723
724
|
hasText: hasText)
|
|
724
725
|
end
|
|
725
726
|
|
|
726
|
-
def frame_locator(selector)
|
|
727
|
+
def frame_locator(selector = nil)
|
|
727
728
|
@main_frame.frame_locator(selector)
|
|
728
729
|
end
|
|
729
730
|
|
|
@@ -5,15 +5,16 @@ module Playwright
|
|
|
5
5
|
@har_id = nil
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
def start(name: nil, title: nil, screenshots: nil, snapshots: nil, sources: nil, live: nil)
|
|
8
|
+
def start(name: nil, title: nil, screenshots: nil, snapshots: nil, ariaSnapshots: nil, screenSnapshots: nil, sources: nil, live: nil)
|
|
9
9
|
params = {
|
|
10
10
|
name: name,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
screencast: screenshots,
|
|
12
|
+
snapshotDom: snapshots,
|
|
13
|
+
snapshotAria: ariaSnapshots,
|
|
14
|
+
snapshotScreen: screenSnapshots,
|
|
14
15
|
live: live,
|
|
15
16
|
}.compact
|
|
16
|
-
@include_sources =
|
|
17
|
+
@include_sources = sources || false
|
|
17
18
|
@channel.send_message_to_server('tracingStart', params)
|
|
18
19
|
trace_name = @channel.send_message_to_server('tracingStartChunk', { title: title, name: name }.compact)
|
|
19
20
|
start_collecting_stacks(trace_name)
|
|
@@ -38,19 +39,43 @@ module Playwright
|
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
def stop(path: nil)
|
|
41
|
-
|
|
42
|
+
save_error = nil
|
|
43
|
+
begin
|
|
44
|
+
do_stop_chunk(file_path: path)
|
|
45
|
+
rescue => error
|
|
46
|
+
save_error = error
|
|
47
|
+
end
|
|
42
48
|
@channel.send_message_to_server('tracingStop')
|
|
49
|
+
raise save_error if save_error
|
|
43
50
|
end
|
|
44
51
|
|
|
45
52
|
private def do_stop_chunk(file_path:)
|
|
46
53
|
reset_stack_counter
|
|
54
|
+
stacks_id = @stacks_id
|
|
55
|
+
@stacks_id = nil
|
|
56
|
+
begin
|
|
57
|
+
save_chunk(file_path: file_path, stacks_id: stacks_id)
|
|
58
|
+
rescue
|
|
59
|
+
# Release the session even if saving fails so subsequent traces start fresh.
|
|
60
|
+
if stacks_id
|
|
61
|
+
begin
|
|
62
|
+
@connection.local_utils&.trace_discarded(stacks_id)
|
|
63
|
+
rescue
|
|
64
|
+
# Preserve the error from saving the trace.
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
raise
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private def save_chunk(file_path:, stacks_id:)
|
|
47
72
|
local_utils = @connection.local_utils
|
|
48
73
|
|
|
49
74
|
unless file_path
|
|
50
75
|
# Not interested in any artifacts
|
|
51
76
|
@channel.send_message_to_server('tracingStopChunk', mode: 'discard')
|
|
52
|
-
if
|
|
53
|
-
local_utils.trace_discarded(
|
|
77
|
+
if stacks_id
|
|
78
|
+
local_utils.trace_discarded(stacks_id) if local_utils
|
|
54
79
|
end
|
|
55
80
|
|
|
56
81
|
return
|
|
@@ -66,7 +91,7 @@ module Playwright
|
|
|
66
91
|
local_utils.zip(
|
|
67
92
|
zipFile: file_path,
|
|
68
93
|
entries: result['entries'],
|
|
69
|
-
stacksId:
|
|
94
|
+
stacksId: stacks_id,
|
|
70
95
|
mode: 'write',
|
|
71
96
|
includeSources: @include_sources,
|
|
72
97
|
)
|
|
@@ -78,8 +103,8 @@ module Playwright
|
|
|
78
103
|
result = @channel.send_message_to_server_result('tracingStopChunk', mode: 'archive')
|
|
79
104
|
# The artifact may be missing if the browser closed while stopping tracing.
|
|
80
105
|
unless result['artifact']
|
|
81
|
-
if
|
|
82
|
-
local_utils.trace_discarded(
|
|
106
|
+
if stacks_id
|
|
107
|
+
local_utils.trace_discarded(stacks_id) if local_utils
|
|
83
108
|
end
|
|
84
109
|
|
|
85
110
|
return
|
|
@@ -87,7 +112,12 @@ module Playwright
|
|
|
87
112
|
|
|
88
113
|
# Save trace to the final local file.
|
|
89
114
|
artifact = ChannelOwners::Artifact.from(result['artifact'])
|
|
90
|
-
|
|
115
|
+
begin
|
|
116
|
+
artifact.save_as(file_path)
|
|
117
|
+
rescue
|
|
118
|
+
artifact.delete rescue nil
|
|
119
|
+
raise
|
|
120
|
+
end
|
|
91
121
|
artifact.delete
|
|
92
122
|
|
|
93
123
|
return unless local_utils
|
|
@@ -95,7 +125,7 @@ module Playwright
|
|
|
95
125
|
local_utils.zip(
|
|
96
126
|
zipFile: file_path,
|
|
97
127
|
entries: [],
|
|
98
|
-
stacksId:
|
|
128
|
+
stacksId: stacks_id,
|
|
99
129
|
mode: 'append',
|
|
100
130
|
includeSources: @include_sources,
|
|
101
131
|
)
|
data/lib/playwright/events.rb
CHANGED
|
@@ -29,6 +29,7 @@ end
|
|
|
29
29
|
Close: 'close',
|
|
30
30
|
Console: 'console',
|
|
31
31
|
Dialog: 'dialog',
|
|
32
|
+
DialogClosed: 'dialogclosed',
|
|
32
33
|
Download: 'download',
|
|
33
34
|
FrameAttached: 'frameattached',
|
|
34
35
|
FrameDetached: 'framedetached',
|
|
@@ -53,6 +54,7 @@ end
|
|
|
53
54
|
Crash: 'crash',
|
|
54
55
|
Console: 'console',
|
|
55
56
|
Dialog: 'dialog',
|
|
57
|
+
DialogClosed: 'dialogclosed',
|
|
56
58
|
Download: 'download',
|
|
57
59
|
FileChooser: 'filechooser',
|
|
58
60
|
DOMContentLoaded: 'domcontentloaded',
|
|
@@ -13,6 +13,21 @@ module Playwright
|
|
|
13
13
|
@frame.send(:_timeout, timeout)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
private def child_selector(selector)
|
|
17
|
+
if @frame_selector == 'internal:control=any-frame'
|
|
18
|
+
"#{@frame_selector} >> #{selector}"
|
|
19
|
+
else
|
|
20
|
+
"#{@frame_selector} >> internal:control=enter-frame >> #{selector}"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private def nth_selector(index)
|
|
25
|
+
if @frame_selector == 'internal:control=any-frame'
|
|
26
|
+
raise 'Selecting the nth frame is not allowed on frameLocator().'
|
|
27
|
+
end
|
|
28
|
+
"#{@frame_selector} >> nth=#{index}"
|
|
29
|
+
end
|
|
30
|
+
|
|
16
31
|
def locator(
|
|
17
32
|
selector,
|
|
18
33
|
has: nil,
|
|
@@ -21,7 +36,7 @@ module Playwright
|
|
|
21
36
|
hasText: nil)
|
|
22
37
|
LocatorImpl.new(
|
|
23
38
|
frame: @frame,
|
|
24
|
-
selector:
|
|
39
|
+
selector: child_selector(selector),
|
|
25
40
|
has: has,
|
|
26
41
|
hasNot: hasNot,
|
|
27
42
|
hasNotText: hasNotText,
|
|
@@ -38,28 +53,28 @@ module Playwright
|
|
|
38
53
|
def frame_locator(selector)
|
|
39
54
|
FrameLocatorImpl.new(
|
|
40
55
|
frame: @frame,
|
|
41
|
-
frame_selector:
|
|
56
|
+
frame_selector: child_selector(selector),
|
|
42
57
|
)
|
|
43
58
|
end
|
|
44
59
|
|
|
45
60
|
def first
|
|
46
61
|
FrameLocatorImpl.new(
|
|
47
62
|
frame: @frame,
|
|
48
|
-
frame_selector:
|
|
63
|
+
frame_selector: nth_selector(0),
|
|
49
64
|
)
|
|
50
65
|
end
|
|
51
66
|
|
|
52
67
|
def last
|
|
53
68
|
FrameLocatorImpl.new(
|
|
54
69
|
frame: @frame,
|
|
55
|
-
frame_selector:
|
|
70
|
+
frame_selector: nth_selector(-1),
|
|
56
71
|
)
|
|
57
72
|
end
|
|
58
73
|
|
|
59
74
|
def nth(index)
|
|
60
75
|
FrameLocatorImpl.new(
|
|
61
76
|
frame: @frame,
|
|
62
|
-
frame_selector:
|
|
77
|
+
frame_selector: nth_selector(index),
|
|
63
78
|
)
|
|
64
79
|
end
|
|
65
80
|
end
|
data/lib/playwright/utils.rb
CHANGED
|
@@ -18,9 +18,21 @@ module Playwright
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
module Utils
|
|
21
|
+
module PrepareHttpCredentials
|
|
22
|
+
private def prepare_http_credentials(credentials)
|
|
23
|
+
return nil unless credentials
|
|
24
|
+
|
|
25
|
+
list = credentials.is_a?(Array) ? credentials : [credentials]
|
|
26
|
+
list.empty? ? nil : list
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
21
30
|
module PrepareBrowserContextOptions
|
|
31
|
+
include PrepareHttpCredentials
|
|
32
|
+
|
|
22
33
|
# @see https://github.com/microsoft/playwright/blob/5a2cfdbd47ed3c3deff77bb73e5fac34241f649d/src/client/browserContext.ts#L265
|
|
23
34
|
private def prepare_browser_context_options(params)
|
|
35
|
+
params[:httpCredentials] = prepare_http_credentials(params[:httpCredentials])
|
|
24
36
|
if params[:noViewport] == 0
|
|
25
37
|
params.delete(:noViewport)
|
|
26
38
|
params[:noDefaultViewport] = true
|
data/lib/playwright/version.rb
CHANGED
|
@@ -67,6 +67,8 @@ module Playwright
|
|
|
67
67
|
# ```
|
|
68
68
|
class APIRequestContext < PlaywrightApi
|
|
69
69
|
|
|
70
|
+
#
|
|
71
|
+
# Tracing recorder for requests made through this API request context.
|
|
70
72
|
def tracing # property
|
|
71
73
|
wrap_impl(@impl.tracing)
|
|
72
74
|
end
|
|
@@ -286,26 +288,26 @@ module Playwright
|
|
|
286
288
|
|
|
287
289
|
#
|
|
288
290
|
# Returns storage state for this request context, contains current cookies and local storage snapshot if it was passed to the constructor.
|
|
289
|
-
def storage_state(indexedDB: nil, path: nil)
|
|
291
|
+
def storage_state(indexedDB: nil, opfs: nil, path: nil)
|
|
290
292
|
raise NotImplementedError.new('storage_state is not implemented yet.')
|
|
291
293
|
end
|
|
292
294
|
|
|
293
295
|
# -- inherited from EventEmitter --
|
|
294
296
|
# @nodoc
|
|
295
|
-
def
|
|
296
|
-
event_emitter_proxy.
|
|
297
|
+
def off(event, callback)
|
|
298
|
+
event_emitter_proxy.off(event, callback)
|
|
297
299
|
end
|
|
298
300
|
|
|
299
301
|
# -- inherited from EventEmitter --
|
|
300
302
|
# @nodoc
|
|
301
|
-
def
|
|
302
|
-
event_emitter_proxy.
|
|
303
|
+
def once(event, callback)
|
|
304
|
+
event_emitter_proxy.once(event, callback)
|
|
303
305
|
end
|
|
304
306
|
|
|
305
307
|
# -- inherited from EventEmitter --
|
|
306
308
|
# @nodoc
|
|
307
|
-
def
|
|
308
|
-
event_emitter_proxy.
|
|
309
|
+
def on(event, callback)
|
|
310
|
+
event_emitter_proxy.on(event, callback)
|
|
309
311
|
end
|
|
310
312
|
|
|
311
313
|
private def event_emitter_proxy
|
|
@@ -217,20 +217,20 @@ module Playwright
|
|
|
217
217
|
|
|
218
218
|
# -- inherited from EventEmitter --
|
|
219
219
|
# @nodoc
|
|
220
|
-
def
|
|
221
|
-
event_emitter_proxy.
|
|
220
|
+
def off(event, callback)
|
|
221
|
+
event_emitter_proxy.off(event, callback)
|
|
222
222
|
end
|
|
223
223
|
|
|
224
224
|
# -- inherited from EventEmitter --
|
|
225
225
|
# @nodoc
|
|
226
|
-
def
|
|
227
|
-
event_emitter_proxy.
|
|
226
|
+
def once(event, callback)
|
|
227
|
+
event_emitter_proxy.once(event, callback)
|
|
228
228
|
end
|
|
229
229
|
|
|
230
230
|
# -- inherited from EventEmitter --
|
|
231
231
|
# @nodoc
|
|
232
|
-
def
|
|
233
|
-
event_emitter_proxy.
|
|
232
|
+
def on(event, callback)
|
|
233
|
+
event_emitter_proxy.on(event, callback)
|
|
234
234
|
end
|
|
235
235
|
|
|
236
236
|
private def event_emitter_proxy
|