playwright-ruby-client 1.60.0 → 1.62.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/README.md +12 -17
- data/documentation/docs/api/api_response.md +30 -0
- data/documentation/docs/api/browser_context.md +11 -3
- data/documentation/docs/api/browser_type.md +3 -0
- data/documentation/docs/api/credentials.md +136 -0
- data/documentation/docs/api/element_handle.md +7 -0
- data/documentation/docs/api/frame.md +12 -4
- data/documentation/docs/api/locator.md +29 -0
- data/documentation/docs/api/locator_assertions.md +4 -2
- data/documentation/docs/api/page.md +26 -2
- data/documentation/docs/api/playwright.md +2 -2
- data/documentation/docs/api/touchscreen.md +1 -1
- data/documentation/docs/api/web_storage.md +65 -0
- data/documentation/docs/article/getting_started.md +12 -11
- data/documentation/docs/article/guides/download_playwright_driver.md +11 -32
- data/documentation/docs/article/guides/launch_browser.md +5 -4
- data/documentation/docs/article/guides/playwright_on_alpine_linux.md +6 -5
- data/documentation/docs/article/guides/rails_integration.md +72 -4
- data/documentation/docs/article/guides/rails_integration_with_null_driver.md +4 -3
- data/documentation/docs/article/guides/semi_automation.md +1 -1
- data/documentation/docs/article/guides/use_storage_state.md +1 -1
- data/documentation/docs/include/api_coverage.md +22 -0
- data/documentation/docusaurus.config.js +31 -0
- data/documentation/package.json +3 -0
- data/documentation/yarn.lock +159 -174
- data/lib/playwright/api_response_impl.rb +24 -0
- data/lib/playwright/channel_owners/browser_context.rb +8 -3
- data/lib/playwright/channel_owners/browser_type.rb +2 -1
- data/lib/playwright/channel_owners/element_handle.rb +14 -4
- data/lib/playwright/channel_owners/frame.rb +50 -17
- data/lib/playwright/channel_owners/page.rb +31 -10
- data/lib/playwright/connection.rb +16 -2
- data/lib/playwright/credentials_impl.rb +35 -0
- data/lib/playwright/errors.rb +4 -1
- data/lib/playwright/locator_assertions_impl.rb +14 -1
- data/lib/playwright/locator_impl.rb +28 -5
- data/lib/playwright/locator_utils.rb +9 -1
- data/lib/playwright/screencast.rb +22 -6
- data/lib/playwright/screenshot_utils.rb +24 -0
- data/lib/playwright/test.rb +12 -2
- data/lib/playwright/url_matcher.rb +120 -4
- data/lib/playwright/version.rb +2 -2
- data/lib/playwright/waiter.rb +9 -41
- data/lib/playwright/web_storage_impl.rb +34 -0
- data/lib/playwright.rb +2 -2
- data/lib/playwright_api/api_request_context.rb +6 -6
- data/lib/playwright_api/api_response.rb +21 -0
- data/lib/playwright_api/browser.rb +6 -6
- data/lib/playwright_api/browser_context.rb +27 -18
- data/lib/playwright_api/browser_type.rb +10 -7
- data/lib/playwright_api/cdp_session.rb +6 -6
- data/lib/playwright_api/credentials.rb +124 -0
- data/lib/playwright_api/dialog.rb +6 -6
- data/lib/playwright_api/element_handle.rb +20 -13
- data/lib/playwright_api/frame.rb +36 -28
- data/lib/playwright_api/js_handle.rb +6 -6
- data/lib/playwright_api/locator.rb +37 -11
- data/lib/playwright_api/locator_assertions.rb +6 -4
- data/lib/playwright_api/page.rb +55 -29
- data/lib/playwright_api/playwright.rb +6 -6
- data/lib/playwright_api/request.rb +6 -6
- data/lib/playwright_api/response.rb +6 -6
- data/lib/playwright_api/route.rb +6 -6
- data/lib/playwright_api/touchscreen.rb +1 -1
- data/lib/playwright_api/tracing.rb +6 -6
- data/lib/playwright_api/web_socket.rb +6 -6
- data/lib/playwright_api/web_storage.rb +48 -0
- data/lib/playwright_api/worker.rb +6 -6
- data/playwright.gemspec +5 -0
- data/sig/playwright.rbs +62 -40
- metadata +13 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7c78e6a1f2ee45aadb2b8a027d08a0264560172b843419e23376c80f74095ccd
|
|
4
|
+
data.tar.gz: b31e8c1c972865e68312f65ee23a821535f14592affadcc65580b10169819b81
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: de6ea998c746c0fa3107850695144b7204105c01daa6209f646c2a172bd59eb906e169b4b7ed7dca436e8084611496def05fc81bb23134d8475bedbc480d6fd5
|
|
7
|
+
data.tar.gz: 907612d4a87117af9d0c57ada0ec4144f7451f7a75176b2b93d3cf896ff6ce8492f7e72ff8a2c04ce1d5d2871fdf9af2f967de9e5175010574d09c276b160300
|
data/README.md
CHANGED
|
@@ -12,25 +12,22 @@ gem 'playwright-ruby-client'
|
|
|
12
12
|
|
|
13
13
|
and then 'bundle install'.
|
|
14
14
|
|
|
15
|
-
Since playwright-ruby-client doesn't include
|
|
15
|
+
Since playwright-ruby-client doesn't include Playwright, **we have to install Node.js and a compatible version of [playwright-core](https://www.npmjs.com/package/playwright-core) in advance**.
|
|
16
16
|
|
|
17
|
+
```sh
|
|
18
|
+
PLAYWRIGHT_CLI_VERSION=$(bundle exec ruby -e 'require "playwright/version"; puts Playwright::COMPATIBLE_PLAYWRIGHT_VERSION')
|
|
19
|
+
npm install "playwright-core@$PLAYWRIGHT_CLI_VERSION"
|
|
20
|
+
./node_modules/.bin/playwright-core install
|
|
17
21
|
```
|
|
18
|
-
npm install playwright
|
|
19
|
-
./node_modules/.bin/playwright install
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
And set `playwright_cli_executable_path: './node_modules/.bin/playwright'`
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Instead of npm, you can also directly download playwright driver from playwright.azureedge.net/builds/. The URL can be easily detected from [here](https://github.com/microsoft/playwright-python/blob/cb5409934629adaabc0cff1891080de2052fa778/setup.py#L73-L77)
|
|
23
|
+
And set `playwright_cli_executable_path: './node_modules/.bin/playwright-core'`.
|
|
27
24
|
|
|
28
25
|
### Capture a site
|
|
29
26
|
|
|
30
27
|
```ruby
|
|
31
28
|
require 'playwright'
|
|
32
29
|
|
|
33
|
-
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
|
|
30
|
+
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright-core') do |playwright|
|
|
34
31
|
playwright.chromium.launch(headless: false) do |browser|
|
|
35
32
|
page = browser.new_page
|
|
36
33
|
page.goto('https://github.com/YusukeIwaki')
|
|
@@ -46,7 +43,7 @@ end
|
|
|
46
43
|
```ruby
|
|
47
44
|
require 'playwright'
|
|
48
45
|
|
|
49
|
-
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
|
|
46
|
+
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright-core') do |playwright|
|
|
50
47
|
playwright.chromium.launch(headless: false) do |browser|
|
|
51
48
|
page = browser.new_page
|
|
52
49
|
page.goto('https://github.com/')
|
|
@@ -94,7 +91,7 @@ $ bundle exec ruby main.rb
|
|
|
94
91
|
```ruby
|
|
95
92
|
require 'playwright'
|
|
96
93
|
|
|
97
|
-
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
|
|
94
|
+
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright-core') do |playwright|
|
|
98
95
|
devices = playwright.android.devices
|
|
99
96
|
unless devices.empty?
|
|
100
97
|
device = devices.last
|
|
@@ -128,12 +125,10 @@ end
|
|
|
128
125
|
We have to download android-driver for Playwright in advance.
|
|
129
126
|
|
|
130
127
|
```
|
|
131
|
-
wget https://github.com/microsoft/playwright/raw/master/bin/android-driver-target.apk -O /
|
|
132
|
-
wget https://github.com/microsoft/playwright/raw/master/bin/android-driver.apk -O /
|
|
128
|
+
wget https://github.com/microsoft/playwright/raw/master/bin/android-driver-target.apk -O ./node_modules/playwright-core/bin/android-driver-target.apk
|
|
129
|
+
wget https://github.com/microsoft/playwright/raw/master/bin/android-driver.apk -O ./node_modules/playwright-core/bin/android-driver.apk
|
|
133
130
|
```
|
|
134
131
|
|
|
135
|
-
(If you downloaded Playwright via npm, replace `/path/to/playwright-driver/package/` with `./node_modules/playwright/` above.)
|
|
136
|
-
|
|
137
132
|
```ruby
|
|
138
133
|
require 'playwright'
|
|
139
134
|
|
|
@@ -168,7 +163,7 @@ If your environment doesn't accept installing browser or creating browser proces
|
|
|
168
163
|
For launching Playwright server, just execute:
|
|
169
164
|
|
|
170
165
|
```
|
|
171
|
-
|
|
166
|
+
./node_modules/.bin/playwright-core install && ./node_modules/.bin/playwright-core run-server --port 8080 --path /ws
|
|
172
167
|
```
|
|
173
168
|
|
|
174
169
|
and we can connect to the server with the code like this:
|
|
@@ -77,6 +77,24 @@ def ok
|
|
|
77
77
|
|
|
78
78
|
Contains a boolean stating whether the response was successful (status in the range 200-299) or not.
|
|
79
79
|
|
|
80
|
+
## security_details
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
def security_details
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
Returns SSL and other security information. Resolves to `null` for non-HTTPS responses. For redirected requests, returns the information for the last request in the redirect chain.
|
|
88
|
+
|
|
89
|
+
## server_addr
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
def server_addr
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
Returns the IP address and port of the server. Resolves to `null` if the server address is not available. For redirected requests, returns the information for the last request in the redirect chain.
|
|
97
|
+
|
|
80
98
|
## status
|
|
81
99
|
|
|
82
100
|
```
|
|
@@ -104,6 +122,18 @@ def text
|
|
|
104
122
|
|
|
105
123
|
Returns the text representation of response body.
|
|
106
124
|
|
|
125
|
+
## timing
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
def timing
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
Returns resource timing information for given response. For redirected requests, returns the information for the last
|
|
133
|
+
request in the redirect chain. When the response is served [from the HAR file](https://playwright.dev/python/docs/mock#replaying-from-har), timing
|
|
134
|
+
information is not available and all the values are -1. Find more information at
|
|
135
|
+
[Resource Timing API](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming).
|
|
136
|
+
|
|
107
137
|
## url
|
|
108
138
|
|
|
109
139
|
```
|
|
@@ -434,11 +434,11 @@ alias: `offline=`
|
|
|
434
434
|
## storage_state
|
|
435
435
|
|
|
436
436
|
```
|
|
437
|
-
def storage_state(indexedDB: nil, path: nil)
|
|
437
|
+
def storage_state(credentials: nil, indexedDB: nil, path: nil)
|
|
438
438
|
```
|
|
439
439
|
|
|
440
440
|
|
|
441
|
-
Returns storage state for this browser context, contains current cookies, local storage snapshot and
|
|
441
|
+
Returns storage state for this browser context, contains current cookies, local storage snapshot, IndexedDB snapshot and virtual WebAuthn credentials.
|
|
442
442
|
|
|
443
443
|
## set_storage_state
|
|
444
444
|
|
|
@@ -448,7 +448,9 @@ def set_storage_state(storageState)
|
|
|
448
448
|
alias: `storage_state=`
|
|
449
449
|
|
|
450
450
|
|
|
451
|
-
Clears the existing cookies, local storage
|
|
451
|
+
Clears the existing cookies, local storage, IndexedDB entries and virtual WebAuthn credentials, and sets the new storage
|
|
452
|
+
state. When the storage state contains credentials, the virtual WebAuthn authenticator is installed (equivalent to
|
|
453
|
+
[Credentials#install](./credentials#install)), preventing all real authenticators from working in this context.
|
|
452
454
|
|
|
453
455
|
**Usage**
|
|
454
456
|
|
|
@@ -521,6 +523,12 @@ Will throw an error if the context closes before new [Page](./page) is created.
|
|
|
521
523
|
|
|
522
524
|
Playwright has ability to mock clock and passage of time.
|
|
523
525
|
|
|
526
|
+
## credentials
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
Virtual WebAuthn authenticator for this context. Lets tests seed credentials and intercept
|
|
530
|
+
`navigator.credentials.create()` / `navigator.credentials.get()` ceremonies.
|
|
531
|
+
|
|
524
532
|
## request
|
|
525
533
|
|
|
526
534
|
|
|
@@ -41,6 +41,7 @@ This method attaches Playwright to an existing browser instance created via `Bro
|
|
|
41
41
|
```
|
|
42
42
|
def connect_over_cdp(
|
|
43
43
|
endpointURL,
|
|
44
|
+
artifactsDir: nil,
|
|
44
45
|
headers: nil,
|
|
45
46
|
isLocal: nil,
|
|
46
47
|
noDefaults: nil,
|
|
@@ -58,6 +59,8 @@ The default browser context is accessible via [Browser#contexts](./browser#conte
|
|
|
58
59
|
|
|
59
60
|
**NOTE**: This connection is significantly lower fidelity than the Playwright protocol connection via [BrowserType#connect](./browser_type#connect). If you are experiencing issues or attempting to use advanced functionality, you probably want to use [BrowserType#connect](./browser_type#connect).
|
|
60
61
|
|
|
62
|
+
**NOTE**: Playwright maintains a curated list of arguments for launching the browser. If you launch the browser without Playwright and do not pass the exact same arguments, some of Playwright functionality may be broken upon connecting to the browser.
|
|
63
|
+
|
|
61
64
|
**Usage**
|
|
62
65
|
|
|
63
66
|
```ruby
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 10
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Credentials
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
[Credentials](./credentials) is a virtual WebAuthn authenticator scoped to a [BrowserContext](./browser_context). It lets tests
|
|
9
|
+
register passkeys and answer `navigator.credentials.create()` / `navigator.credentials.get()`
|
|
10
|
+
ceremonies in the page, without a real authenticator or hardware security key.
|
|
11
|
+
|
|
12
|
+
There are three common ways to use it:
|
|
13
|
+
|
|
14
|
+
**Usage: seed a known credential**
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
context = browser.new_context
|
|
18
|
+
|
|
19
|
+
# A passkey your backend already provisioned for a test user.
|
|
20
|
+
context.credentials.create(
|
|
21
|
+
"example.com",
|
|
22
|
+
id: known_credential_id, # base64url
|
|
23
|
+
userHandle: known_user_handle, # base64url
|
|
24
|
+
privateKey: known_private_key, # base64url PKCS#8 (DER)
|
|
25
|
+
publicKey: known_public_key, # base64url SPKI (DER)
|
|
26
|
+
)
|
|
27
|
+
context.credentials.install
|
|
28
|
+
|
|
29
|
+
page = context.new_page
|
|
30
|
+
page.goto("https://example.com/login")
|
|
31
|
+
# The page's navigator.credentials.get() is answered with the seeded passkey.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Usage: capture a credential, then reuse it**
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
# setup test: let the app register a passkey, then save it.
|
|
38
|
+
context = browser.new_context
|
|
39
|
+
context.credentials.install
|
|
40
|
+
|
|
41
|
+
page = context.new_page
|
|
42
|
+
page.goto("https://example.com/register")
|
|
43
|
+
page.get_by_role("button", name: "Create a passkey").click
|
|
44
|
+
|
|
45
|
+
# Read back the passkey the page registered - it includes the private key.
|
|
46
|
+
credential = context.credentials.get(rpId: "example.com").first
|
|
47
|
+
File.write("playwright/.auth/passkey.json", JSON.generate(credential))
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
# later test: seed the captured passkey so the app starts already enrolled.
|
|
52
|
+
credential = JSON.parse(File.read("playwright/.auth/passkey.json"))
|
|
53
|
+
context = browser.new_context
|
|
54
|
+
context.credentials.create(
|
|
55
|
+
credential["rpId"],
|
|
56
|
+
id: credential["id"],
|
|
57
|
+
userHandle: credential["userHandle"],
|
|
58
|
+
privateKey: credential["privateKey"],
|
|
59
|
+
publicKey: credential["publicKey"],
|
|
60
|
+
)
|
|
61
|
+
context.credentials.install
|
|
62
|
+
|
|
63
|
+
page = context.new_page
|
|
64
|
+
page.goto("https://example.com/login")
|
|
65
|
+
# navigator.credentials.get() resolves the captured passkey - already signed in.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Usage: save credentials in the storage state, restore later**
|
|
69
|
+
|
|
70
|
+
See [authentication guide](https://playwright.dev/python/docs/auth) for examples of using saving and resotring the storage state.
|
|
71
|
+
|
|
72
|
+
**Defaults**
|
|
73
|
+
|
|
74
|
+
## install
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
def install
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
Installs the virtual WebAuthn authenticator into the context, overriding
|
|
82
|
+
`navigator.credentials.create()` and `navigator.credentials.get()` in all current
|
|
83
|
+
and future pages. Call this before the page first touches `navigator.credentials`.
|
|
84
|
+
|
|
85
|
+
Required: until [Credentials#install](./credentials#install) is called, no interception is in place and the page sees
|
|
86
|
+
the platform's native (or absent) WebAuthn behaviour. Seeding credentials with
|
|
87
|
+
[Credentials#create](./credentials#create) without installing populates the authenticator, but the
|
|
88
|
+
page will never see those credentials.
|
|
89
|
+
|
|
90
|
+
## create
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
def create(
|
|
94
|
+
rpId,
|
|
95
|
+
id: nil,
|
|
96
|
+
privateKey: nil,
|
|
97
|
+
publicKey: nil,
|
|
98
|
+
userHandle: nil)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
Seeds a virtual WebAuthn credential and returns it.
|
|
103
|
+
|
|
104
|
+
With only `rpId`, generates a fresh **ECDSA P-256** keypair, credential id and user handle. The
|
|
105
|
+
seeded credential is discoverable (resident), so the page can resolve it from both
|
|
106
|
+
username-then-passkey and usernameless passkey flows. The returned object carries the private and public keys, so it can be persisted to disk and re-seeded in a later test.
|
|
107
|
+
|
|
108
|
+
To **import a known credential**, supply all four of `id`, `userHandle`, `privateKey` and
|
|
109
|
+
`publicKey` together.
|
|
110
|
+
|
|
111
|
+
Call [Credentials#install](./credentials#install) before navigating to a page that uses WebAuthn.
|
|
112
|
+
|
|
113
|
+
## delete
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
def delete(id)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
Removes a credential from the authenticator by its id. Works for any credential currently held —
|
|
121
|
+
both those seeded with [Credentials#create](./credentials#create) and those the page registered itself by
|
|
122
|
+
calling `navigator.credentials.create()`.
|
|
123
|
+
|
|
124
|
+
## get
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
def get(id: nil, rpId: nil)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
Returns every credential currently held by the authenticator, optionally filtered by `rpId` or
|
|
132
|
+
`id`. This includes both credentials seeded with [Credentials#create](./credentials#create) and credentials
|
|
133
|
+
the page registered itself by calling `navigator.credentials.create()`.
|
|
134
|
+
|
|
135
|
+
Each returned credential includes its private and public keys, so a passkey the app just
|
|
136
|
+
registered can be saved and re-seeded into a later test with [Credentials#create](./credentials#create) — see the second example in the class overview.
|
|
@@ -75,6 +75,7 @@ def check(
|
|
|
75
75
|
force: nil,
|
|
76
76
|
noWaitAfter: nil,
|
|
77
77
|
position: nil,
|
|
78
|
+
scroll: nil,
|
|
78
79
|
timeout: nil,
|
|
79
80
|
trial: nil)
|
|
80
81
|
```
|
|
@@ -103,6 +104,7 @@ def click(
|
|
|
103
104
|
modifiers: nil,
|
|
104
105
|
noWaitAfter: nil,
|
|
105
106
|
position: nil,
|
|
107
|
+
scroll: nil,
|
|
106
108
|
steps: nil,
|
|
107
109
|
timeout: nil,
|
|
108
110
|
trial: nil)
|
|
@@ -139,6 +141,7 @@ def dblclick(
|
|
|
139
141
|
modifiers: nil,
|
|
140
142
|
noWaitAfter: nil,
|
|
141
143
|
position: nil,
|
|
144
|
+
scroll: nil,
|
|
142
145
|
steps: nil,
|
|
143
146
|
timeout: nil,
|
|
144
147
|
trial: nil)
|
|
@@ -290,6 +293,7 @@ def hover(
|
|
|
290
293
|
modifiers: nil,
|
|
291
294
|
noWaitAfter: nil,
|
|
292
295
|
position: nil,
|
|
296
|
+
scroll: nil,
|
|
293
297
|
timeout: nil,
|
|
294
298
|
trial: nil)
|
|
295
299
|
```
|
|
@@ -538,6 +542,7 @@ def set_checked(
|
|
|
538
542
|
force: nil,
|
|
539
543
|
noWaitAfter: nil,
|
|
540
544
|
position: nil,
|
|
545
|
+
scroll: nil,
|
|
541
546
|
timeout: nil,
|
|
542
547
|
trial: nil)
|
|
543
548
|
```
|
|
@@ -578,6 +583,7 @@ def tap_point(
|
|
|
578
583
|
modifiers: nil,
|
|
579
584
|
noWaitAfter: nil,
|
|
580
585
|
position: nil,
|
|
586
|
+
scroll: nil,
|
|
581
587
|
timeout: nil,
|
|
582
588
|
trial: nil)
|
|
583
589
|
```
|
|
@@ -630,6 +636,7 @@ def uncheck(
|
|
|
630
636
|
force: nil,
|
|
631
637
|
noWaitAfter: nil,
|
|
632
638
|
position: nil,
|
|
639
|
+
scroll: nil,
|
|
633
640
|
timeout: nil,
|
|
634
641
|
trial: nil)
|
|
635
642
|
```
|
|
@@ -58,6 +58,7 @@ def check(
|
|
|
58
58
|
force: nil,
|
|
59
59
|
noWaitAfter: nil,
|
|
60
60
|
position: nil,
|
|
61
|
+
scroll: nil,
|
|
61
62
|
strict: nil,
|
|
62
63
|
timeout: nil,
|
|
63
64
|
trial: nil)
|
|
@@ -95,6 +96,7 @@ def click(
|
|
|
95
96
|
modifiers: nil,
|
|
96
97
|
noWaitAfter: nil,
|
|
97
98
|
position: nil,
|
|
99
|
+
scroll: nil,
|
|
98
100
|
strict: nil,
|
|
99
101
|
timeout: nil,
|
|
100
102
|
trial: nil)
|
|
@@ -131,6 +133,7 @@ def dblclick(
|
|
|
131
133
|
modifiers: nil,
|
|
132
134
|
noWaitAfter: nil,
|
|
133
135
|
position: nil,
|
|
136
|
+
scroll: nil,
|
|
134
137
|
strict: nil,
|
|
135
138
|
timeout: nil,
|
|
136
139
|
trial: nil)
|
|
@@ -202,6 +205,7 @@ def drag_and_drop(
|
|
|
202
205
|
target,
|
|
203
206
|
force: nil,
|
|
204
207
|
noWaitAfter: nil,
|
|
208
|
+
scroll: nil,
|
|
205
209
|
sourcePosition: nil,
|
|
206
210
|
steps: nil,
|
|
207
211
|
strict: nil,
|
|
@@ -291,7 +295,7 @@ puts frame.evaluate("1 + #{x}") # => "11"
|
|
|
291
295
|
[ElementHandle](./element_handle) instances can be passed as an argument to the [Frame#evaluate](./frame#evaluate):
|
|
292
296
|
|
|
293
297
|
```ruby
|
|
294
|
-
body_handle = frame.
|
|
298
|
+
body_handle = frame.evaluate_handle("document.body")
|
|
295
299
|
html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", arg: [body_handle, "hello"])
|
|
296
300
|
body_handle.dispose
|
|
297
301
|
```
|
|
@@ -321,14 +325,14 @@ a_window_handle # handle for the window object.
|
|
|
321
325
|
A string can also be passed in instead of a function.
|
|
322
326
|
|
|
323
327
|
```ruby
|
|
324
|
-
a_handle =
|
|
328
|
+
a_handle = frame.evaluate_handle("document") # handle for the "document"
|
|
325
329
|
```
|
|
326
330
|
|
|
327
331
|
[JSHandle](./js_handle) instances can be passed as an argument to the [Frame#evaluate_handle](./frame#evaluate_handle):
|
|
328
332
|
|
|
329
333
|
```ruby
|
|
330
|
-
|
|
331
|
-
result_handle =
|
|
334
|
+
a_handle = frame.evaluate_handle("document.body")
|
|
335
|
+
result_handle = frame.evaluate_handle("body => body.innerHTML", arg: a_handle)
|
|
332
336
|
puts result_handle.json_value
|
|
333
337
|
result_handle.dispose
|
|
334
338
|
```
|
|
@@ -671,6 +675,7 @@ def hover(
|
|
|
671
675
|
modifiers: nil,
|
|
672
676
|
noWaitAfter: nil,
|
|
673
677
|
position: nil,
|
|
678
|
+
scroll: nil,
|
|
674
679
|
strict: nil,
|
|
675
680
|
timeout: nil,
|
|
676
681
|
trial: nil)
|
|
@@ -932,6 +937,7 @@ def set_checked(
|
|
|
932
937
|
force: nil,
|
|
933
938
|
noWaitAfter: nil,
|
|
934
939
|
position: nil,
|
|
940
|
+
scroll: nil,
|
|
935
941
|
strict: nil,
|
|
936
942
|
timeout: nil,
|
|
937
943
|
trial: nil)
|
|
@@ -987,6 +993,7 @@ def tap_point(
|
|
|
987
993
|
modifiers: nil,
|
|
988
994
|
noWaitAfter: nil,
|
|
989
995
|
position: nil,
|
|
996
|
+
scroll: nil,
|
|
990
997
|
strict: nil,
|
|
991
998
|
timeout: nil,
|
|
992
999
|
trial: nil)
|
|
@@ -1056,6 +1063,7 @@ def uncheck(
|
|
|
1056
1063
|
force: nil,
|
|
1057
1064
|
noWaitAfter: nil,
|
|
1058
1065
|
position: nil,
|
|
1066
|
+
scroll: nil,
|
|
1059
1067
|
strict: nil,
|
|
1060
1068
|
timeout: nil,
|
|
1061
1069
|
trial: nil)
|
|
@@ -179,6 +179,7 @@ def check(
|
|
|
179
179
|
force: nil,
|
|
180
180
|
noWaitAfter: nil,
|
|
181
181
|
position: nil,
|
|
182
|
+
scroll: nil,
|
|
182
183
|
timeout: nil,
|
|
183
184
|
trial: nil)
|
|
184
185
|
```
|
|
@@ -238,6 +239,7 @@ def click(
|
|
|
238
239
|
modifiers: nil,
|
|
239
240
|
noWaitAfter: nil,
|
|
240
241
|
position: nil,
|
|
242
|
+
scroll: nil,
|
|
241
243
|
steps: nil,
|
|
242
244
|
timeout: nil,
|
|
243
245
|
trial: nil)
|
|
@@ -300,6 +302,7 @@ def dblclick(
|
|
|
300
302
|
modifiers: nil,
|
|
301
303
|
noWaitAfter: nil,
|
|
302
304
|
position: nil,
|
|
305
|
+
scroll: nil,
|
|
303
306
|
steps: nil,
|
|
304
307
|
timeout: nil,
|
|
305
308
|
trial: nil)
|
|
@@ -410,6 +413,7 @@ def drag_to(
|
|
|
410
413
|
target,
|
|
411
414
|
force: nil,
|
|
412
415
|
noWaitAfter: nil,
|
|
416
|
+
scroll: nil,
|
|
413
417
|
sourcePosition: nil,
|
|
414
418
|
steps: nil,
|
|
415
419
|
targetPosition: nil,
|
|
@@ -921,6 +925,7 @@ def hover(
|
|
|
921
925
|
modifiers: nil,
|
|
922
926
|
noWaitAfter: nil,
|
|
923
927
|
position: nil,
|
|
928
|
+
scroll: nil,
|
|
924
929
|
timeout: nil,
|
|
925
930
|
trial: nil)
|
|
926
931
|
```
|
|
@@ -1367,6 +1372,7 @@ def set_checked(
|
|
|
1367
1372
|
force: nil,
|
|
1368
1373
|
noWaitAfter: nil,
|
|
1369
1374
|
position: nil,
|
|
1375
|
+
scroll: nil,
|
|
1370
1376
|
timeout: nil,
|
|
1371
1377
|
trial: nil)
|
|
1372
1378
|
```
|
|
@@ -1438,6 +1444,7 @@ def tap_point(
|
|
|
1438
1444
|
modifiers: nil,
|
|
1439
1445
|
noWaitAfter: nil,
|
|
1440
1446
|
position: nil,
|
|
1447
|
+
scroll: nil,
|
|
1441
1448
|
timeout: nil,
|
|
1442
1449
|
trial: nil)
|
|
1443
1450
|
```
|
|
@@ -1496,6 +1503,7 @@ def uncheck(
|
|
|
1496
1503
|
force: nil,
|
|
1497
1504
|
noWaitAfter: nil,
|
|
1498
1505
|
position: nil,
|
|
1506
|
+
scroll: nil,
|
|
1499
1507
|
timeout: nil,
|
|
1500
1508
|
trial: nil)
|
|
1501
1509
|
```
|
|
@@ -1541,3 +1549,24 @@ If target element already satisfies the condition, the method returns immediatel
|
|
|
1541
1549
|
order_sent = page.locator("#order-sent")
|
|
1542
1550
|
order_sent.wait_for
|
|
1543
1551
|
```
|
|
1552
|
+
|
|
1553
|
+
## wait_for_function
|
|
1554
|
+
|
|
1555
|
+
```
|
|
1556
|
+
def wait_for_function(expression, arg: nil, timeout: nil)
|
|
1557
|
+
```
|
|
1558
|
+
|
|
1559
|
+
|
|
1560
|
+
Returns when `expression` returns a truthy value, called with the matching element as a first argument, and `arg` as a second argument.
|
|
1561
|
+
|
|
1562
|
+
This is a generic way to wait for an element to reach a custom condition without asserting it. The locator is re-resolved on each retry, so it tolerates the element being re-rendered while waiting.
|
|
1563
|
+
|
|
1564
|
+
If `expression` returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), this method will wait for the promise to resolve before checking its value.
|
|
1565
|
+
|
|
1566
|
+
If `expression` throws or rejects, this method throws.
|
|
1567
|
+
|
|
1568
|
+
**Usage**
|
|
1569
|
+
|
|
1570
|
+
Wait for an attribute to appear:
|
|
1571
|
+
|
|
1572
|
+
Passing argument to `expression`:
|
|
@@ -164,7 +164,7 @@ The opposite of [LocatorAssertions#to_have_accessible_name](./locator_assertions
|
|
|
164
164
|
## not_to_have_attribute
|
|
165
165
|
|
|
166
166
|
```ruby
|
|
167
|
-
expect(locator).not_to have_attribute(name, value, ignoreCase: nil, timeout: nil)
|
|
167
|
+
expect(locator).not_to have_attribute(name, value: nil, ignoreCase: nil, timeout: nil)
|
|
168
168
|
```
|
|
169
169
|
|
|
170
170
|
|
|
@@ -587,7 +587,7 @@ expect(locator).to have_accessible_name("Save to disk")
|
|
|
587
587
|
## to_have_attribute
|
|
588
588
|
|
|
589
589
|
```ruby
|
|
590
|
-
expect(locator).to have_attribute(name, value, ignoreCase: nil, timeout: nil)
|
|
590
|
+
expect(locator).to have_attribute(name, value: nil, ignoreCase: nil, timeout: nil)
|
|
591
591
|
```
|
|
592
592
|
|
|
593
593
|
|
|
@@ -598,6 +598,8 @@ Ensures the [Locator](./locator) points to an element with given attribute.
|
|
|
598
598
|
```ruby
|
|
599
599
|
locator = page.locator("input")
|
|
600
600
|
expect(locator).to have_attribute("type", "text")
|
|
601
|
+
expect(locator).to have_attribute("disabled")
|
|
602
|
+
expect(locator).not_to have_attribute("readonly")
|
|
601
603
|
```
|
|
602
604
|
|
|
603
605
|
## to_have_class
|
|
@@ -112,6 +112,7 @@ def check(
|
|
|
112
112
|
force: nil,
|
|
113
113
|
noWaitAfter: nil,
|
|
114
114
|
position: nil,
|
|
115
|
+
scroll: nil,
|
|
115
116
|
strict: nil,
|
|
116
117
|
timeout: nil,
|
|
117
118
|
trial: nil)
|
|
@@ -141,6 +142,7 @@ def click(
|
|
|
141
142
|
modifiers: nil,
|
|
142
143
|
noWaitAfter: nil,
|
|
143
144
|
position: nil,
|
|
145
|
+
scroll: nil,
|
|
144
146
|
strict: nil,
|
|
145
147
|
timeout: nil,
|
|
146
148
|
trial: nil)
|
|
@@ -201,6 +203,7 @@ def dblclick(
|
|
|
201
203
|
modifiers: nil,
|
|
202
204
|
noWaitAfter: nil,
|
|
203
205
|
position: nil,
|
|
206
|
+
scroll: nil,
|
|
204
207
|
strict: nil,
|
|
205
208
|
timeout: nil,
|
|
206
209
|
trial: nil)
|
|
@@ -275,6 +278,7 @@ def drag_and_drop(
|
|
|
275
278
|
target,
|
|
276
279
|
force: nil,
|
|
277
280
|
noWaitAfter: nil,
|
|
281
|
+
scroll: nil,
|
|
278
282
|
sourcePosition: nil,
|
|
279
283
|
steps: nil,
|
|
280
284
|
strict: nil,
|
|
@@ -413,7 +417,7 @@ puts page.evaluate("1 + #{x}") # => "11"
|
|
|
413
417
|
[ElementHandle](./element_handle) instances can be passed as an argument to the [Page#evaluate](./page#evaluate):
|
|
414
418
|
|
|
415
419
|
```ruby
|
|
416
|
-
body_handle = page.
|
|
420
|
+
body_handle = page.evaluate_handle("document.body")
|
|
417
421
|
html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", arg: [body_handle, "hello"])
|
|
418
422
|
body_handle.dispose
|
|
419
423
|
```
|
|
@@ -851,6 +855,9 @@ last redirect. If cannot go back, returns `null`.
|
|
|
851
855
|
|
|
852
856
|
Navigate to the previous page in history.
|
|
853
857
|
|
|
858
|
+
**NOTE**: **Testing Back/Forward Cache (BFCache) is not supported.**
|
|
859
|
+
By default, Playwright disables the Back/Forward Cache across all browsers. Even if explicitly enabled, Playwright's internal state relies on network-level navigation events. Because BFCache restores unfreeze the DOM without firing these events, using `page.goBack()` or `page.goForward()` to trigger a BFCache restore will result in timeouts and a desynchronized [Page](./page) state.
|
|
860
|
+
|
|
854
861
|
## go_forward
|
|
855
862
|
|
|
856
863
|
```
|
|
@@ -863,6 +870,9 @@ last redirect. If cannot go forward, returns `null`.
|
|
|
863
870
|
|
|
864
871
|
Navigate to the next page in history.
|
|
865
872
|
|
|
873
|
+
**NOTE**: **Testing Back/Forward Cache (BFCache) is not supported.**
|
|
874
|
+
By default, Playwright disables the Back/Forward Cache across all browsers. Even if explicitly enabled, Playwright's internal state relies on network-level navigation events. Because BFCache restores unfreeze the DOM without firing these events, using `page.goBack()` or `page.goForward()` to trigger a BFCache restore will result in timeouts and a desynchronized [Page](./page) state.
|
|
875
|
+
|
|
866
876
|
## goto
|
|
867
877
|
|
|
868
878
|
```
|
|
@@ -908,6 +918,7 @@ def hover(
|
|
|
908
918
|
modifiers: nil,
|
|
909
919
|
noWaitAfter: nil,
|
|
910
920
|
position: nil,
|
|
921
|
+
scroll: nil,
|
|
911
922
|
strict: nil,
|
|
912
923
|
timeout: nil,
|
|
913
924
|
trial: nil)
|
|
@@ -1416,6 +1427,7 @@ def set_checked(
|
|
|
1416
1427
|
force: nil,
|
|
1417
1428
|
noWaitAfter: nil,
|
|
1418
1429
|
position: nil,
|
|
1430
|
+
scroll: nil,
|
|
1419
1431
|
strict: nil,
|
|
1420
1432
|
timeout: nil,
|
|
1421
1433
|
trial: nil)
|
|
@@ -1546,6 +1558,7 @@ def tap_point(
|
|
|
1546
1558
|
modifiers: nil,
|
|
1547
1559
|
noWaitAfter: nil,
|
|
1548
1560
|
position: nil,
|
|
1561
|
+
scroll: nil,
|
|
1549
1562
|
strict: nil,
|
|
1550
1563
|
timeout: nil,
|
|
1551
1564
|
trial: nil)
|
|
@@ -1561,7 +1574,7 @@ This method taps an element matching `selector` by performing the following step
|
|
|
1561
1574
|
When all steps combined have not finished during the specified `timeout`, this method throws a
|
|
1562
1575
|
`TimeoutError`. Passing zero timeout disables this.
|
|
1563
1576
|
|
|
1564
|
-
**NOTE**: [Page#tap_point](./page#tap_point)
|
|
1577
|
+
**NOTE**: [Page#tap_point](./page#tap_point) will throw if the `hasTouch` option of the browser context is false.
|
|
1565
1578
|
|
|
1566
1579
|
## text_content
|
|
1567
1580
|
|
|
@@ -1615,6 +1628,7 @@ def uncheck(
|
|
|
1615
1628
|
force: nil,
|
|
1616
1629
|
noWaitAfter: nil,
|
|
1617
1630
|
position: nil,
|
|
1631
|
+
scroll: nil,
|
|
1618
1632
|
strict: nil,
|
|
1619
1633
|
timeout: nil,
|
|
1620
1634
|
trial: nil)
|
|
@@ -2001,6 +2015,16 @@ Playwright has ability to mock clock and passage of time.
|
|
|
2001
2015
|
|
|
2002
2016
|
## keyboard
|
|
2003
2017
|
|
|
2018
|
+
## local_storage
|
|
2019
|
+
|
|
2020
|
+
|
|
2021
|
+
Provides access to the page's `localStorage` for the current origin. See [WebStorage](./web_storage).
|
|
2022
|
+
|
|
2023
|
+
## session_storage
|
|
2024
|
+
|
|
2025
|
+
|
|
2026
|
+
Provides access to the page's `sessionStorage` for the current origin. See [WebStorage](./web_storage).
|
|
2027
|
+
|
|
2004
2028
|
## mouse
|
|
2005
2029
|
|
|
2006
2030
|
## request
|