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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/api_request_context.md +45 -133
  3. data/documentation/docs/api/browser_context.md +0 -4
  4. data/documentation/docs/api/download.md +1 -3
  5. data/documentation/docs/api/frame.md +1 -1
  6. data/documentation/docs/api/frame_locator.md +10 -1
  7. data/documentation/docs/api/locator.md +19 -47
  8. data/documentation/docs/api/page.md +1 -1
  9. data/documentation/docs/include/api_coverage.md +16 -28
  10. data/lib/playwright/channel_owners/api_request_context.rb +0 -232
  11. data/lib/playwright/channel_owners/browser_context.rb +6 -3
  12. data/lib/playwright/channel_owners/frame.rb +2 -2
  13. data/lib/playwright/channel_owners/local_utils.rb +14 -0
  14. data/lib/playwright/channel_owners/page.rb +2 -6
  15. data/lib/playwright/frame_locator_impl.rb +2 -1
  16. data/lib/playwright/locator_impl.rb +62 -3
  17. data/lib/playwright/tracing_impl.rb +21 -7
  18. data/lib/playwright/version.rb +2 -2
  19. data/lib/playwright_api/api_request_context.rb +55 -8
  20. data/lib/playwright_api/browser_context.rb +6 -6
  21. data/lib/playwright_api/download.rb +0 -4
  22. data/lib/playwright_api/frame.rb +2 -2
  23. data/lib/playwright_api/frame_locator.rb +11 -2
  24. data/lib/playwright_api/local_utils.rb +9 -0
  25. data/lib/playwright_api/locator.rb +16 -46
  26. data/lib/playwright_api/page.rb +7 -7
  27. metadata +7 -10
  28. data/documentation/docs/api/api_request.md +0 -7
  29. data/documentation/docs/api/api_response.md +0 -90
  30. data/lib/playwright/api_response_impl.rb +0 -73
  31. data/lib/playwright_api/api_request.rb +0 -18
  32. data/lib/playwright_api/api_response.rb +0 -68
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9407fc7093bb4cdb7539eec09b879e4bfd665626801594c764798ae41d3c7823
4
- data.tar.gz: e6047ebe532d15fa5600986ae3fc9f42a23ea670923e1ec8fac6f6ecbb7f01c4
3
+ metadata.gz: 36a3c1f293b4d9a4a27ac780ebce4eb4098af2cefeba6d4e66f4ddb8c49490d7
4
+ data.tar.gz: 3520c8afc689c71a27d9af6516461cb1871a206bc6c416aee5f99742217191c8
5
5
  SHA512:
6
- metadata.gz: 70b935777666f43236ec9df9b8462ebebf7fb883cde2d57e167d3342a18280a86e286e99e206f47e6ee2c739f23f6afe43daa2def9ea0a322b5e09f3b36bfc81
7
- data.tar.gz: 3392ad01696c2c22ba411d7e4821e0bf0a2f641526481201927ff6510d7bb077c9fb6b20fcafabd55e5067ff7b1153b950d6b3c532c0bd14d77b9a0b3ac7c4c0
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
- ## delete
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
- > NOTE: Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
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
 
@@ -549,7 +549,7 @@ considered not visible.
549
549
  ## locator
550
550
 
551
551
  ```
552
- def locator(selector)
552
+ def locator(selector, hasText: nil)
553
553
  ```
554
554
 
555
555
  The method returns an element locator that can be used to perform actions in the frame. Locator is resolved to the
@@ -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
- Locator represents a view to the element(s) on the page. It captures the logic sufficient to retrieve the element at any
8
- given moment. Locator can be created with the [Page#locator](./page#locator) method.
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.
@@ -774,7 +774,7 @@ considered not visible.
774
774
  ## locator
775
775
 
776
776
  ```
777
- def locator(selector)
777
+ def locator(selector, hasText: nil)
778
778
  ```
779
779
 
780
780
  The method returns an element locator that can be used to perform actions on the page. Locator is resolved to the
@@ -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
- ## APIResponse
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, :request
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)