playwright-ruby-client 0.0.8 → 1.58.1.alpha1

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.
Files changed (209) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +4 -0
  3. data/CLAUDE/api_generation.md +28 -0
  4. data/CLAUDE/ci_expectations.md +23 -0
  5. data/CLAUDE/gem_release_flow.md +39 -0
  6. data/CLAUDE/past_upgrade_pr_patterns.md +42 -0
  7. data/CLAUDE/playwright_upgrade_workflow.md +35 -0
  8. data/CLAUDE/rspec_debugging.md +30 -0
  9. data/CLAUDE/unimplemented_examples.md +18 -0
  10. data/CLAUDE.md +32 -0
  11. data/CONTRIBUTING.md +5 -0
  12. data/README.md +60 -16
  13. data/documentation/README.md +33 -0
  14. data/documentation/babel.config.js +3 -0
  15. data/documentation/docs/api/api_request.md +7 -0
  16. data/documentation/docs/api/api_request_context.md +298 -0
  17. data/documentation/docs/api/api_response.md +114 -0
  18. data/documentation/docs/api/browser.md +237 -0
  19. data/documentation/docs/api/browser_context.md +503 -0
  20. data/documentation/docs/api/browser_type.md +184 -0
  21. data/documentation/docs/api/cdp_session.md +44 -0
  22. data/documentation/docs/api/clock.md +154 -0
  23. data/documentation/docs/api/console_message.md +85 -0
  24. data/documentation/docs/api/dialog.md +84 -0
  25. data/documentation/docs/api/download.md +111 -0
  26. data/documentation/docs/api/element_handle.md +694 -0
  27. data/documentation/docs/api/experimental/_category_.yml +3 -0
  28. data/documentation/docs/api/experimental/android.md +42 -0
  29. data/documentation/docs/api/experimental/android_device.md +109 -0
  30. data/documentation/docs/api/experimental/android_input.md +43 -0
  31. data/documentation/docs/api/experimental/android_socket.md +7 -0
  32. data/documentation/docs/api/experimental/android_web_view.md +7 -0
  33. data/documentation/docs/api/file_chooser.md +53 -0
  34. data/documentation/docs/api/frame.md +1218 -0
  35. data/documentation/docs/api/frame_locator.md +348 -0
  36. data/documentation/docs/api/js_handle.md +121 -0
  37. data/documentation/docs/api/keyboard.md +170 -0
  38. data/documentation/docs/api/locator.md +1495 -0
  39. data/documentation/docs/api/locator_assertions.md +827 -0
  40. data/documentation/docs/api/mouse.md +86 -0
  41. data/documentation/docs/api/page.md +1946 -0
  42. data/documentation/docs/api/page_assertions.md +65 -0
  43. data/documentation/docs/api/playwright.md +66 -0
  44. data/documentation/docs/api/request.md +255 -0
  45. data/documentation/docs/api/response.md +176 -0
  46. data/documentation/docs/api/route.md +205 -0
  47. data/documentation/docs/api/selectors.md +63 -0
  48. data/documentation/docs/api/touchscreen.md +22 -0
  49. data/documentation/docs/api/tracing.md +129 -0
  50. data/documentation/docs/api/web_socket.md +51 -0
  51. data/documentation/docs/api/worker.md +83 -0
  52. data/documentation/docs/article/api_coverage.mdx +11 -0
  53. data/documentation/docs/article/getting_started.md +161 -0
  54. data/documentation/docs/article/guides/_category_.yml +3 -0
  55. data/documentation/docs/article/guides/download_playwright_driver.md +55 -0
  56. data/documentation/docs/article/guides/inspector.md +31 -0
  57. data/documentation/docs/article/guides/launch_browser.md +121 -0
  58. data/documentation/docs/article/guides/playwright_on_alpine_linux.md +112 -0
  59. data/documentation/docs/article/guides/rails_integration.md +278 -0
  60. data/documentation/docs/article/guides/rails_integration_with_null_driver.md +145 -0
  61. data/documentation/docs/article/guides/recording_video.md +79 -0
  62. data/documentation/docs/article/guides/rspec_integration.md +59 -0
  63. data/documentation/docs/article/guides/semi_automation.md +71 -0
  64. data/documentation/docs/article/guides/use_storage_state.md +78 -0
  65. data/documentation/docs/include/api_coverage.md +671 -0
  66. data/documentation/docusaurus.config.js +114 -0
  67. data/documentation/package.json +39 -0
  68. data/documentation/sidebars.js +15 -0
  69. data/documentation/src/components/HomepageFeatures.js +61 -0
  70. data/documentation/src/components/HomepageFeatures.module.css +13 -0
  71. data/documentation/src/css/custom.css +44 -0
  72. data/documentation/src/pages/index.js +49 -0
  73. data/documentation/src/pages/index.module.css +41 -0
  74. data/documentation/src/pages/markdown-page.md +7 -0
  75. data/documentation/static/.nojekyll +0 -0
  76. data/documentation/static/img/playwright-logo.svg +9 -0
  77. data/documentation/static/img/playwright-ruby-client.png +0 -0
  78. data/documentation/static/img/undraw_dropdown_menu.svg +1 -0
  79. data/documentation/static/img/undraw_web_development.svg +1 -0
  80. data/documentation/static/img/undraw_windows.svg +1 -0
  81. data/documentation/yarn.lock +9005 -0
  82. data/lib/playwright/{input_types/android_input.rb → android_input_impl.rb} +5 -1
  83. data/lib/playwright/api_implementation.rb +18 -0
  84. data/lib/playwright/api_response_impl.rb +77 -0
  85. data/lib/playwright/channel.rb +62 -1
  86. data/lib/playwright/channel_owner.rb +70 -7
  87. data/lib/playwright/channel_owners/android.rb +16 -3
  88. data/lib/playwright/channel_owners/android_device.rb +22 -66
  89. data/lib/playwright/channel_owners/api_request_context.rb +247 -0
  90. data/lib/playwright/channel_owners/artifact.rb +40 -0
  91. data/lib/playwright/channel_owners/binding_call.rb +70 -0
  92. data/lib/playwright/channel_owners/browser.rb +114 -22
  93. data/lib/playwright/channel_owners/browser_context.rb +589 -15
  94. data/lib/playwright/channel_owners/browser_type.rb +90 -1
  95. data/lib/playwright/channel_owners/cdp_session.rb +19 -0
  96. data/lib/playwright/channel_owners/dialog.rb +32 -0
  97. data/lib/playwright/channel_owners/element_handle.rb +107 -43
  98. data/lib/playwright/channel_owners/fetch_request.rb +8 -0
  99. data/lib/playwright/channel_owners/frame.rb +334 -104
  100. data/lib/playwright/channel_owners/js_handle.rb +9 -13
  101. data/lib/playwright/channel_owners/local_utils.rb +82 -0
  102. data/lib/playwright/channel_owners/page.rb +778 -95
  103. data/lib/playwright/channel_owners/playwright.rb +25 -30
  104. data/lib/playwright/channel_owners/request.rb +120 -18
  105. data/lib/playwright/channel_owners/response.rb +113 -0
  106. data/lib/playwright/channel_owners/route.rb +181 -0
  107. data/lib/playwright/channel_owners/stream.rb +30 -0
  108. data/lib/playwright/channel_owners/tracing.rb +117 -0
  109. data/lib/playwright/channel_owners/web_socket.rb +96 -0
  110. data/lib/playwright/channel_owners/worker.rb +46 -0
  111. data/lib/playwright/channel_owners/writable_stream.rb +14 -0
  112. data/lib/playwright/clock_impl.rb +67 -0
  113. data/lib/playwright/connection.rb +111 -63
  114. data/lib/playwright/console_message_impl.rb +29 -0
  115. data/lib/playwright/download_impl.rb +32 -0
  116. data/lib/playwright/errors.rb +42 -5
  117. data/lib/playwright/event_emitter.rb +17 -3
  118. data/lib/playwright/event_emitter_proxy.rb +49 -0
  119. data/lib/playwright/events.rb +10 -5
  120. data/lib/playwright/file_chooser_impl.rb +24 -0
  121. data/lib/playwright/frame_locator_impl.rb +66 -0
  122. data/lib/playwright/har_router.rb +89 -0
  123. data/lib/playwright/http_headers.rb +14 -0
  124. data/lib/playwright/input_files.rb +102 -15
  125. data/lib/playwright/javascript/expression.rb +7 -11
  126. data/lib/playwright/javascript/regex.rb +23 -0
  127. data/lib/playwright/javascript/source_url.rb +16 -0
  128. data/lib/playwright/javascript/value_parser.rb +108 -19
  129. data/lib/playwright/javascript/value_serializer.rb +47 -8
  130. data/lib/playwright/javascript/visitor_info.rb +26 -0
  131. data/lib/playwright/javascript.rb +2 -10
  132. data/lib/playwright/{input_types/keyboard.rb → keyboard_impl.rb} +6 -2
  133. data/lib/playwright/locator_assertions_impl.rb +571 -0
  134. data/lib/playwright/locator_impl.rb +544 -0
  135. data/lib/playwright/locator_utils.rb +136 -0
  136. data/lib/playwright/mouse_impl.rb +57 -0
  137. data/lib/playwright/page_assertions_impl.rb +154 -0
  138. data/lib/playwright/playwright_api.rb +102 -30
  139. data/lib/playwright/raw_headers.rb +61 -0
  140. data/lib/playwright/route_handler.rb +78 -0
  141. data/lib/playwright/select_option_values.rb +34 -13
  142. data/lib/playwright/selectors_impl.rb +45 -0
  143. data/lib/playwright/test.rb +102 -0
  144. data/lib/playwright/timeout_settings.rb +9 -4
  145. data/lib/playwright/touchscreen_impl.rb +14 -0
  146. data/lib/playwright/transport.rb +61 -10
  147. data/lib/playwright/url_matcher.rb +24 -2
  148. data/lib/playwright/utils.rb +48 -13
  149. data/lib/playwright/version.rb +2 -1
  150. data/lib/playwright/video.rb +54 -0
  151. data/lib/playwright/waiter.rb +166 -0
  152. data/lib/playwright/web_socket_client.rb +167 -0
  153. data/lib/playwright/web_socket_transport.rb +116 -0
  154. data/lib/playwright.rb +188 -11
  155. data/lib/playwright_api/android.rb +46 -11
  156. data/lib/playwright_api/android_device.rb +182 -31
  157. data/lib/playwright_api/android_input.rb +22 -13
  158. data/lib/playwright_api/android_socket.rb +18 -0
  159. data/lib/playwright_api/android_web_view.rb +24 -0
  160. data/lib/playwright_api/api_request.rb +26 -0
  161. data/lib/playwright_api/api_request_context.rb +311 -0
  162. data/lib/playwright_api/api_response.rb +92 -0
  163. data/lib/playwright_api/browser.rb +116 -103
  164. data/lib/playwright_api/browser_context.rb +290 -389
  165. data/lib/playwright_api/browser_type.rb +96 -118
  166. data/lib/playwright_api/cdp_session.rb +36 -39
  167. data/lib/playwright_api/clock.rb +121 -0
  168. data/lib/playwright_api/console_message.rb +35 -19
  169. data/lib/playwright_api/dialog.rb +53 -50
  170. data/lib/playwright_api/download.rb +49 -43
  171. data/lib/playwright_api/element_handle.rb +354 -402
  172. data/lib/playwright_api/file_chooser.rb +15 -18
  173. data/lib/playwright_api/frame.rb +703 -603
  174. data/lib/playwright_api/frame_locator.rb +285 -0
  175. data/lib/playwright_api/js_handle.rb +50 -76
  176. data/lib/playwright_api/keyboard.rb +67 -146
  177. data/lib/playwright_api/locator.rb +1304 -0
  178. data/lib/playwright_api/locator_assertions.rb +704 -0
  179. data/lib/playwright_api/mouse.rb +23 -29
  180. data/lib/playwright_api/page.rb +1196 -1176
  181. data/lib/playwright_api/page_assertions.rb +60 -0
  182. data/lib/playwright_api/playwright.rb +54 -122
  183. data/lib/playwright_api/request.rb +112 -74
  184. data/lib/playwright_api/response.rb +92 -20
  185. data/lib/playwright_api/route.rb +152 -62
  186. data/lib/playwright_api/selectors.rb +47 -61
  187. data/lib/playwright_api/touchscreen.rb +8 -2
  188. data/lib/playwright_api/tracing.rb +128 -0
  189. data/lib/playwright_api/web_socket.rb +43 -5
  190. data/lib/playwright_api/worker.rb +74 -34
  191. data/playwright.gemspec +14 -9
  192. data/sig/playwright.rbs +658 -0
  193. metadata +216 -50
  194. data/docs/api_coverage.md +0 -354
  195. data/lib/playwright/channel_owners/chromium_browser.rb +0 -8
  196. data/lib/playwright/channel_owners/chromium_browser_context.rb +0 -8
  197. data/lib/playwright/channel_owners/console_message.rb +0 -21
  198. data/lib/playwright/channel_owners/firefox_browser.rb +0 -8
  199. data/lib/playwright/channel_owners/selectors.rb +0 -4
  200. data/lib/playwright/channel_owners/webkit_browser.rb +0 -8
  201. data/lib/playwright/input_type.rb +0 -19
  202. data/lib/playwright/input_types/mouse.rb +0 -4
  203. data/lib/playwright/input_types/touchscreen.rb +0 -4
  204. data/lib/playwright/javascript/function.rb +0 -67
  205. data/lib/playwright/wait_helper.rb +0 -73
  206. data/lib/playwright_api/accessibility.rb +0 -93
  207. data/lib/playwright_api/binding_call.rb +0 -23
  208. data/lib/playwright_api/chromium_browser_context.rb +0 -57
  209. data/lib/playwright_api/video.rb +0 -24
@@ -0,0 +1,348 @@
1
+ ---
2
+ sidebar_position: 10
3
+ ---
4
+
5
+ # FrameLocator
6
+
7
+
8
+ FrameLocator represents a view to the `iframe` on the page. It captures the logic sufficient to retrieve the `iframe` and locate elements in that iframe. FrameLocator can be created with either [Locator#content_frame](./locator#content_frame), [Page#frame_locator](./page#frame_locator) or [Locator#frame_locator](./locator#frame_locator) method.
9
+
10
+ ```ruby
11
+ locator = page.locator("my-frame").content_frame.get_by_text("Submit")
12
+ locator.click
13
+ ```
14
+
15
+ **Strictness**
16
+
17
+ Frame locators are strict. This means that all operations on frame locators will throw if more than one element matches a given selector.
18
+
19
+ ```ruby
20
+ # Throws if there are several frames in DOM:
21
+ page.locator('.result-frame').content_frame.get_by_role('button').click
22
+
23
+ # Works because we explicitly tell locator to pick the first frame:
24
+ page.locator('.result-frame').first.content_frame.get_by_role('button').click
25
+ ```
26
+
27
+ **Converting Locator to FrameLocator**
28
+
29
+ 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).
30
+
31
+ **Converting FrameLocator to Locator**
32
+
33
+ If you have a [FrameLocator](./frame_locator) object it can be converted to [Locator](./locator) pointing to the same `iframe` using [FrameLocator#owner](./frame_locator#owner).
34
+
35
+ ## first
36
+
37
+ ```
38
+ def first
39
+ ```
40
+
41
+ :::warning
42
+
43
+ Use [Locator#first](./locator#first) followed by [Locator#content_frame](./locator#content_frame) instead.
44
+
45
+ :::
46
+
47
+
48
+ Returns locator to the first matching frame.
49
+
50
+ ## frame_locator
51
+
52
+ ```
53
+ def frame_locator(selector)
54
+ ```
55
+
56
+
57
+ When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements
58
+ in that iframe.
59
+
60
+ ## get_by_alt_text
61
+
62
+ ```
63
+ def get_by_alt_text(text, exact: nil)
64
+ ```
65
+
66
+
67
+ Allows locating elements by their alt text.
68
+
69
+ **Usage**
70
+
71
+ For example, this method will find the image by alt text "Playwright logo":
72
+
73
+ ```html
74
+ <img alt='Playwright logo'>
75
+ ```
76
+
77
+ ```ruby
78
+ page.get_by_alt_text("Playwright logo").click
79
+ ```
80
+
81
+ ## get_by_label
82
+
83
+ ```
84
+ def get_by_label(text, exact: nil)
85
+ ```
86
+
87
+
88
+ Allows locating input elements by the text of the associated `<label>` or `aria-labelledby` element, or by the `aria-label` attribute.
89
+
90
+ **Usage**
91
+
92
+ For example, this method will find inputs by label "Username" and "Password" in the following DOM:
93
+
94
+ ```html
95
+ <input aria-label="Username">
96
+ <label for="password-input">Password:</label>
97
+ <input id="password-input">
98
+ ```
99
+
100
+ ```ruby
101
+ page.get_by_label("Username").fill("john")
102
+ page.get_by_label("Password").fill("secret")
103
+ ```
104
+
105
+ ## get_by_placeholder
106
+
107
+ ```
108
+ def get_by_placeholder(text, exact: nil)
109
+ ```
110
+
111
+
112
+ Allows locating input elements by the placeholder text.
113
+
114
+ **Usage**
115
+
116
+ For example, consider the following DOM structure.
117
+
118
+ ```html
119
+ <input type="email" placeholder="name@example.com" />
120
+ ```
121
+
122
+ You can fill the input after locating it by the placeholder text:
123
+
124
+ ```ruby
125
+ page.get_by_placeholder("name@example.com").fill("playwright@microsoft.com")
126
+ ```
127
+
128
+ ## get_by_role
129
+
130
+ ```
131
+ def get_by_role(
132
+ role,
133
+ checked: nil,
134
+ disabled: nil,
135
+ exact: nil,
136
+ expanded: nil,
137
+ includeHidden: nil,
138
+ level: nil,
139
+ name: nil,
140
+ pressed: nil,
141
+ selected: nil)
142
+ ```
143
+
144
+
145
+ Allows locating elements by their [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles), [ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and [accessible name](https://w3c.github.io/accname/#dfn-accessible-name).
146
+
147
+ **Usage**
148
+
149
+ Consider the following DOM structure.
150
+
151
+ ```html
152
+ <h3>Sign up</h3>
153
+ <label>
154
+ <input type="checkbox" /> Subscribe
155
+ </label>
156
+ <br/>
157
+ <button>Submit</button>
158
+ ```
159
+
160
+ You can locate each element by it's implicit role:
161
+
162
+ ```ruby
163
+ page.get_by_role("heading", name: "Sign up").visible? # => true
164
+ page.get_by_role("checkbox", name: "Subscribe").check
165
+ page.get_by_role("button", name: /submit/i).click
166
+ ```
167
+
168
+ **Details**
169
+
170
+ Role selector **does not replace** accessibility audits and conformance tests, but rather gives early feedback about the ARIA guidelines.
171
+
172
+ Many html elements have an implicitly [defined role](https://w3c.github.io/html-aam/#html-element-role-mappings) that is recognized by the role selector. You can find all the [supported roles here](https://www.w3.org/TR/wai-aria-1.2/#role_definitions). ARIA guidelines **do not recommend** duplicating implicit roles and attributes by setting `role` and/or `aria-*` attributes to default values.
173
+
174
+ ## get_by_test_id
175
+
176
+ ```
177
+ def get_by_test_id(testId)
178
+ ```
179
+ alias: `get_by_testid`
180
+
181
+
182
+ Locate element by the test id.
183
+
184
+ **Usage**
185
+
186
+ Consider the following DOM structure.
187
+
188
+ ```html
189
+ <button data-testid="directions">Itinéraire</button>
190
+ ```
191
+
192
+ You can locate the element by it's test id:
193
+
194
+ ```ruby
195
+ page.get_by_test_id("directions").click
196
+ ```
197
+
198
+ **Details**
199
+
200
+ By default, the `data-testid` attribute is used as a test id. Use [Selectors#set_test_id_attribute](./selectors#set_test_id_attribute) to configure a different test id attribute if necessary.
201
+
202
+ ## get_by_text
203
+
204
+ ```
205
+ def get_by_text(text, exact: nil)
206
+ ```
207
+
208
+
209
+ Allows locating elements that contain given text.
210
+
211
+ See also [Locator#filter](./locator#filter) that allows to match by another criteria, like an accessible role, and then filter by the text content.
212
+
213
+ **Usage**
214
+
215
+ Consider the following DOM structure:
216
+
217
+ ```html
218
+ <div>Hello <span>world</span></div>
219
+ <div>Hello</div>
220
+ ```
221
+
222
+ You can locate by text substring, exact string, or a regular expression:
223
+
224
+ ```ruby
225
+ page.content = <<~HTML
226
+ <div>Hello <span>world</span></div>
227
+ <div>Hello</div>
228
+ HTML
229
+
230
+ # Matches <span>
231
+ locator = page.get_by_text("world")
232
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<span>world</span>')
233
+
234
+ # Matches first <div>
235
+ locator = page.get_by_text("Hello world")
236
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello <span>world</span></div>')
237
+
238
+ # Matches second <div>
239
+ locator = page.get_by_text("Hello", exact: true)
240
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
241
+
242
+ # Matches both <div>s
243
+ locator = page.get_by_text(/Hello/)
244
+ expect(locator.count).to eq(2)
245
+ expect(locator.first.evaluate('e => e.outerHTML')).to eq('<div>Hello <span>world</span></div>')
246
+ expect(locator.last.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
247
+
248
+ # Matches second <div>
249
+ locator = page.get_by_text(/^hello$/i)
250
+ expect(locator.evaluate('e => e.outerHTML')).to eq('<div>Hello</div>')
251
+ ```
252
+
253
+ **Details**
254
+
255
+ Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into one, turns line breaks into spaces and ignores leading and trailing whitespace.
256
+
257
+ Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
258
+
259
+ ## get_by_title
260
+
261
+ ```
262
+ def get_by_title(text, exact: nil)
263
+ ```
264
+
265
+
266
+ Allows locating elements by their title attribute.
267
+
268
+ **Usage**
269
+
270
+ Consider the following DOM structure.
271
+
272
+ ```html
273
+ <span title='Issues count'>25 issues</span>
274
+ ```
275
+
276
+ You can check the issues count after locating it by the title text:
277
+
278
+ ```ruby
279
+ page.get_by_title("Issues count").text_content # => "25 issues"
280
+ ```
281
+
282
+ ## last
283
+
284
+ ```
285
+ def last
286
+ ```
287
+
288
+ :::warning
289
+
290
+ Use [Locator#last](./locator#last) followed by [Locator#content_frame](./locator#content_frame) instead.
291
+
292
+ :::
293
+
294
+
295
+ Returns locator to the last matching frame.
296
+
297
+ ## locator
298
+
299
+ ```
300
+ def locator(
301
+ selectorOrLocator,
302
+ has: nil,
303
+ hasNot: nil,
304
+ hasNotText: nil,
305
+ hasText: nil)
306
+ ```
307
+
308
+
309
+ The method finds an element matching the specified selector in the locator's subtree. It also accepts filter options, similar to [Locator#filter](./locator#filter) method.
310
+
311
+ [Learn more about locators](https://playwright.dev/python/docs/locators).
312
+
313
+ ## nth
314
+
315
+ ```
316
+ def nth(index)
317
+ ```
318
+
319
+ :::warning
320
+
321
+ Use [Locator#nth](./locator#nth) followed by [Locator#content_frame](./locator#content_frame) instead.
322
+
323
+ :::
324
+
325
+
326
+ Returns locator to the n-th matching frame. It's zero based, `nth(0)` selects the first frame.
327
+
328
+ ## owner
329
+
330
+ ```
331
+ def owner
332
+ ```
333
+
334
+
335
+ Returns a [Locator](./locator) object pointing to the same `iframe` as this frame locator.
336
+
337
+ Useful when you have a [FrameLocator](./frame_locator) object obtained somewhere, and later on would like to interact with the `iframe` element.
338
+
339
+ For a reverse operation, use [Locator#content_frame](./locator#content_frame).
340
+
341
+ **Usage**
342
+
343
+ ```ruby
344
+ frame_locator = page.locator('iframe[name="embedded"]').content_frame
345
+ # ...
346
+ locator = frame_locator.owner
347
+ locator.get_attribute('src') # => frame1.html
348
+ ```
@@ -0,0 +1,121 @@
1
+ ---
2
+ sidebar_position: 10
3
+ ---
4
+
5
+ # JSHandle
6
+
7
+
8
+ JSHandle represents an in-page JavaScript object. JSHandles can be created with the [Page#evaluate_handle](./page#evaluate_handle)
9
+ method.
10
+
11
+ ```ruby
12
+ window_handle = page.evaluate_handle("window")
13
+ # ...
14
+ ```
15
+
16
+ JSHandle prevents the referenced JavaScript object being garbage collected unless the handle is exposed with
17
+ [JSHandle#dispose](./js_handle#dispose). JSHandles are auto-disposed when their origin frame gets navigated or the parent context
18
+ gets destroyed.
19
+
20
+ JSHandle instances can be used as an argument in [Page#eval_on_selector](./page#eval_on_selector), [Page#evaluate](./page#evaluate) and
21
+ [Page#evaluate_handle](./page#evaluate_handle) methods.
22
+
23
+ ## as_element
24
+
25
+ ```
26
+ def as_element
27
+ ```
28
+
29
+
30
+ Returns either `null` or the object handle itself, if the object handle is an instance of [ElementHandle](./element_handle).
31
+
32
+ ## dispose
33
+
34
+ ```
35
+ def dispose
36
+ ```
37
+
38
+
39
+ The `jsHandle.dispose` method stops referencing the element handle.
40
+
41
+ ## evaluate
42
+
43
+ ```
44
+ def evaluate(expression, arg: nil)
45
+ ```
46
+
47
+
48
+ Returns the return value of `expression`.
49
+
50
+ This method passes this handle as the first argument to `expression`.
51
+
52
+ If `expression` returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), then `handle.evaluate` would wait for the promise to resolve and return
53
+ its value.
54
+
55
+ **Usage**
56
+
57
+ ```ruby
58
+ tweet_handle = page.query_selector(".tweet .retweets")
59
+ tweet_handle.evaluate("node => node.innerText") # => "10 retweets"
60
+ ```
61
+
62
+ ## evaluate_handle
63
+
64
+ ```
65
+ def evaluate_handle(expression, arg: nil)
66
+ ```
67
+
68
+
69
+ Returns the return value of `expression` as a [JSHandle](./js_handle).
70
+
71
+ This method passes this handle as the first argument to `expression`.
72
+
73
+ The only difference between [JSHandle#evaluate](./js_handle#evaluate) and [JSHandle#evaluate_handle](./js_handle#evaluate_handle) is that [JSHandle#evaluate_handle](./js_handle#evaluate_handle) returns [JSHandle](./js_handle).
74
+
75
+ If the function passed to the [JSHandle#evaluate_handle](./js_handle#evaluate_handle) returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), then [JSHandle#evaluate_handle](./js_handle#evaluate_handle) would wait
76
+ for the promise to resolve and return its value.
77
+
78
+ See [Page#evaluate_handle](./page#evaluate_handle) for more details.
79
+
80
+ ## get_properties
81
+
82
+ ```
83
+ def get_properties
84
+ ```
85
+ alias: `properties`
86
+
87
+
88
+ The method returns a map with **own property names** as keys and JSHandle instances for the property values.
89
+
90
+ **Usage**
91
+
92
+ ```ruby
93
+ page.goto('https://example.com/')
94
+ handle = page.evaluate_handle("({window, document})")
95
+ properties = handle.properties
96
+ puts properties
97
+ window_handle = properties["window"]
98
+ document_handle = properties["document"]
99
+ handle.dispose
100
+ ```
101
+
102
+ ## get_property
103
+
104
+ ```
105
+ def get_property(propertyName)
106
+ ```
107
+
108
+
109
+ Fetches a single property from the referenced object.
110
+
111
+ ## json_value
112
+
113
+ ```
114
+ def json_value
115
+ ```
116
+
117
+
118
+ Returns a JSON representation of the object. If the object has a `toJSON` function, it **will not be called**.
119
+
120
+ **NOTE**: The method will return an empty JSON object if the referenced object is not stringifiable. It will throw an error if the
121
+ object has circular references.
@@ -0,0 +1,170 @@
1
+ ---
2
+ sidebar_position: 10
3
+ ---
4
+
5
+ # Keyboard
6
+
7
+
8
+ Keyboard provides an api for managing a virtual keyboard. The high level api is [Keyboard#type](./keyboard#type), which takes
9
+ raw characters and generates proper `keydown`, `keypress`/`input`, and `keyup` events on your page.
10
+
11
+ For finer control, you can use [Keyboard#down](./keyboard#down), [Keyboard#up](./keyboard#up), and [Keyboard#insert_text](./keyboard#insert_text)
12
+ to manually fire events as if they were generated from a real keyboard.
13
+
14
+ An example of holding down `Shift` in order to select and delete some text:
15
+
16
+ ```ruby
17
+ page.keyboard.type("Hello World!")
18
+ page.keyboard.press("ArrowLeft")
19
+ page.keyboard.down("Shift")
20
+ 6.times { page.keyboard.press("ArrowLeft") }
21
+ page.keyboard.up("Shift")
22
+ page.keyboard.press("Backspace")
23
+ # result text will end up saying "Hello!"
24
+ ```
25
+
26
+ An example of pressing uppercase `A`
27
+
28
+ ```ruby
29
+ page.keyboard.press("Shift+KeyA")
30
+ # or
31
+ page.keyboard.press("Shift+A")
32
+ ```
33
+
34
+ An example to trigger select-all with the keyboard
35
+
36
+ ```ruby
37
+ # RECOMMENDED
38
+ page.keyboard.press("ControlOrMeta+A")
39
+
40
+ # or just on windows and linux
41
+ page.keyboard.press("Control+A")
42
+ # or just on macOS
43
+ page.keyboard.press("Meta+A")
44
+ ```
45
+
46
+ ## down
47
+
48
+ ```
49
+ def down(key)
50
+ ```
51
+
52
+
53
+ Dispatches a `keydown` event.
54
+
55
+ `key` can specify the intended
56
+ [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to
57
+ generate the text for. A superset of the `key` values can be found
58
+ [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are:
59
+
60
+ `F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`,
61
+ `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
62
+
63
+ Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`, `ControlOrMeta`.
64
+ `ControlOrMeta` resolves to `Control` on Windows and Linux and to `Meta` on macOS.
65
+
66
+ Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
67
+
68
+ If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different
69
+ respective texts.
70
+
71
+ If `key` is a modifier key, `Shift`, `Meta`, `Control`, or `Alt`, subsequent key presses will be sent with that
72
+ modifier active. To release the modifier key, use [Keyboard#up](./keyboard#up).
73
+
74
+ After the key is pressed once, subsequent calls to [Keyboard#down](./keyboard#down) will have
75
+ [repeat](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat) set to true. To release the key, use
76
+ [Keyboard#up](./keyboard#up).
77
+
78
+ **NOTE**: Modifier keys DO influence `keyboard.down`. Holding down `Shift` will type the text in upper case.
79
+
80
+ ## insert_text
81
+
82
+ ```
83
+ def insert_text(text)
84
+ ```
85
+
86
+
87
+ Dispatches only `input` event, does not emit the `keydown`, `keyup` or `keypress` events.
88
+
89
+ **Usage**
90
+
91
+ ```ruby
92
+ page.keyboard.insert_text("嗨")
93
+ ```
94
+
95
+ **NOTE**: Modifier keys DO NOT effect `keyboard.insertText`. Holding down `Shift` will not type the text in upper case.
96
+
97
+ ## press
98
+
99
+ ```
100
+ def press(key, delay: nil)
101
+ ```
102
+
103
+
104
+ **NOTE**: In most cases, you should use [Locator#press](./locator#press) instead.
105
+
106
+ `key` can specify the intended
107
+ [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to
108
+ generate the text for. A superset of the `key` values can be found
109
+ [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are:
110
+
111
+ `F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`,
112
+ `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
113
+
114
+ Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`, `ControlOrMeta`.
115
+ `ControlOrMeta` resolves to `Control` on Windows and Linux and to `Meta` on macOS.
116
+
117
+ Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
118
+
119
+ If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different
120
+ respective texts.
121
+
122
+ Shortcuts such as `key: "Control+o"`, `key: "Control++` or `key: "Control+Shift+T"` are supported as well. When specified with the
123
+ modifier, modifier is pressed and being held while the subsequent key is being pressed.
124
+
125
+ **Usage**
126
+
127
+ ```ruby
128
+ page.goto("https://keycode.info")
129
+ page.keyboard.press("a")
130
+ page.screenshot(path: "a.png")
131
+ page.keyboard.press("ArrowLeft")
132
+ page.screenshot(path: "arrow_left.png")
133
+ page.keyboard.press("Shift+O")
134
+ page.screenshot(path: "o.png")
135
+ ```
136
+
137
+ Shortcut for [Keyboard#down](./keyboard#down) and [Keyboard#up](./keyboard#up).
138
+
139
+ ## type
140
+
141
+ ```
142
+ def type(text, delay: nil)
143
+ ```
144
+
145
+
146
+ **NOTE**: In most cases, you should use [Locator#fill](./locator#fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator#press_sequentially](./locator#press_sequentially).
147
+
148
+ Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
149
+
150
+ To press a special key, like `Control` or `ArrowDown`, use [Keyboard#press](./keyboard#press).
151
+
152
+ **Usage**
153
+
154
+ ```ruby
155
+ page.keyboard.type("Hello") # types instantly
156
+ page.keyboard.type("World", delay: 100) # types slower, like a user
157
+ ```
158
+
159
+ **NOTE**: Modifier keys DO NOT effect `keyboard.type`. Holding down `Shift` will not type the text in upper case.
160
+
161
+ **NOTE**: For characters that are not on a US keyboard, only an `input` event will be sent.
162
+
163
+ ## up
164
+
165
+ ```
166
+ def up(key)
167
+ ```
168
+
169
+
170
+ Dispatches a `keyup` event.