playwright-ruby-client 0.0.5 → 0.0.6

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/playwright.rb +2 -0
  3. data/lib/playwright/channel_owners/element_handle.rb +75 -0
  4. data/lib/playwright/channel_owners/frame.rb +117 -0
  5. data/lib/playwright/channel_owners/page.rb +68 -11
  6. data/lib/playwright/channel_owners/request.rb +90 -0
  7. data/lib/playwright/input_type.rb +19 -0
  8. data/lib/playwright/input_types/keyboard.rb +32 -0
  9. data/lib/playwright/input_types/mouse.rb +4 -0
  10. data/lib/playwright/input_types/touchscreen.rb +4 -0
  11. data/lib/playwright/javascript/expression.rb +22 -0
  12. data/lib/playwright/javascript/function.rb +22 -0
  13. data/lib/playwright/playwright_api.rb +31 -23
  14. data/lib/playwright/timeout_settings.rb +1 -1
  15. data/lib/playwright/url_matcher.rb +19 -0
  16. data/lib/playwright/version.rb +1 -1
  17. data/lib/playwright_api/accessibility.rb +46 -6
  18. data/lib/playwright_api/binding_call.rb +6 -6
  19. data/lib/playwright_api/browser.rb +76 -16
  20. data/lib/playwright_api/browser_context.rb +284 -30
  21. data/lib/playwright_api/browser_type.rb +54 -9
  22. data/lib/playwright_api/cdp_session.rb +23 -1
  23. data/lib/playwright_api/chromium_browser_context.rb +16 -6
  24. data/lib/playwright_api/console_message.rb +10 -10
  25. data/lib/playwright_api/dialog.rb +42 -0
  26. data/lib/playwright_api/download.rb +19 -4
  27. data/lib/playwright_api/element_handle.rb +174 -21
  28. data/lib/playwright_api/file_chooser.rb +8 -0
  29. data/lib/playwright_api/frame.rb +355 -68
  30. data/lib/playwright_api/js_handle.rb +45 -9
  31. data/lib/playwright_api/keyboard.rb +98 -8
  32. data/lib/playwright_api/mouse.rb +22 -0
  33. data/lib/playwright_api/page.rb +779 -127
  34. data/lib/playwright_api/playwright.rb +98 -19
  35. data/lib/playwright_api/request.rb +70 -23
  36. data/lib/playwright_api/response.rb +6 -6
  37. data/lib/playwright_api/route.rb +48 -0
  38. data/lib/playwright_api/selectors.rb +14 -6
  39. data/lib/playwright_api/video.rb +8 -0
  40. data/lib/playwright_api/web_socket.rb +3 -5
  41. data/lib/playwright_api/worker.rb +12 -0
  42. metadata +7 -2
@@ -14,6 +14,39 @@ module Playwright
14
14
  # await browser.close();
15
15
  # })();
16
16
  # ```
17
+ #
18
+ # ```python async
19
+ # import asyncio
20
+ # from playwright.async_api import async_playwright
21
+ #
22
+ # async def run(playwright):
23
+ # chromium = playwright.chromium
24
+ # browser = await chromium.launch()
25
+ # page = await browser.new_page()
26
+ # await page.goto("https://example.com")
27
+ # # other actions...
28
+ # await browser.close()
29
+ #
30
+ # async def main():
31
+ # async with async_playwright() as playwright:
32
+ # await run(playwright)
33
+ # asyncio.run(main())
34
+ # ```
35
+ #
36
+ # ```python sync
37
+ # from playwright.sync_api import sync_playwright
38
+ #
39
+ # def run(playwright):
40
+ # chromium = playwright.chromium
41
+ # browser = chromium.launch()
42
+ # page = browser.new_page()
43
+ # page.goto("https://example.com")
44
+ # # other actions...
45
+ # browser.close()
46
+ #
47
+ # with sync_playwright() as playwright:
48
+ # run(playwright)
49
+ # ```
17
50
  class BrowserType < PlaywrightApi
18
51
 
19
52
  # This methods attaches Playwright to an existing browser instance.
@@ -23,7 +56,7 @@ module Playwright
23
56
 
24
57
  # A path where Playwright expects to find a bundled browser executable.
25
58
  def executable_path
26
- wrap_channel_owner(@channel_owner.executable_path)
59
+ wrap_impl(@impl.executable_path)
27
60
  end
28
61
 
29
62
  # Returns the browser instance.
@@ -37,6 +70,18 @@ module Playwright
37
70
  # });
38
71
  # ```
39
72
  #
73
+ # ```python async
74
+ # browser = await playwright.chromium.launch( # or "firefox" or "webkit".
75
+ # ignore_default_args=["--mute-audio"]
76
+ # )
77
+ # ```
78
+ #
79
+ # ```python sync
80
+ # browser = playwright.chromium.launch( # or "firefox" or "webkit".
81
+ # ignore_default_args=["--mute-audio"]
82
+ # )
83
+ # ```
84
+ #
40
85
  # > **Chromium-only** Playwright can also be used to control the Chrome browser, but it works best with the version of
41
86
  # Chromium it is bundled with. There is no guarantee it will work with any other version. Use `executablePath` option with
42
87
  # extreme caution.
@@ -69,7 +114,7 @@ module Playwright
69
114
  slowMo: nil,
70
115
  timeout: nil,
71
116
  &block)
72
- wrap_channel_owner(@channel_owner.launch(args: args, chromiumSandbox: chromiumSandbox, devtools: devtools, downloadsPath: downloadsPath, env: env, executablePath: executablePath, firefoxUserPrefs: firefoxUserPrefs, handleSIGHUP: handleSIGHUP, handleSIGINT: handleSIGINT, handleSIGTERM: handleSIGTERM, headless: headless, ignoreDefaultArgs: ignoreDefaultArgs, logger: logger, proxy: proxy, slowMo: slowMo, timeout: timeout, &wrap_block_call(block)))
117
+ wrap_impl(@impl.launch(args: args, chromiumSandbox: chromiumSandbox, devtools: devtools, downloadsPath: downloadsPath, env: env, executablePath: executablePath, firefoxUserPrefs: firefoxUserPrefs, handleSIGHUP: handleSIGHUP, handleSIGINT: handleSIGINT, handleSIGTERM: handleSIGTERM, headless: headless, ignoreDefaultArgs: ignoreDefaultArgs, logger: logger, proxy: proxy, slowMo: slowMo, timeout: timeout, &wrap_block_call(block)))
73
118
  end
74
119
 
75
120
  # Returns the persistent browser context instance.
@@ -157,25 +202,25 @@ module Playwright
157
202
 
158
203
  # Returns browser name. For example: `'chromium'`, `'webkit'` or `'firefox'`.
159
204
  def name
160
- wrap_channel_owner(@channel_owner.name)
205
+ wrap_impl(@impl.name)
161
206
  end
162
207
 
163
208
  # -- inherited from EventEmitter --
164
209
  # @nodoc
165
- def off(event, callback)
166
- wrap_channel_owner(@channel_owner.off(event, callback))
210
+ def on(event, callback)
211
+ wrap_impl(@impl.on(event, callback))
167
212
  end
168
213
 
169
214
  # -- inherited from EventEmitter --
170
215
  # @nodoc
171
- def once(event, callback)
172
- wrap_channel_owner(@channel_owner.once(event, callback))
216
+ def off(event, callback)
217
+ wrap_impl(@impl.off(event, callback))
173
218
  end
174
219
 
175
220
  # -- inherited from EventEmitter --
176
221
  # @nodoc
177
- def on(event, callback)
178
- wrap_channel_owner(@channel_owner.on(event, callback))
222
+ def once(event, callback)
223
+ wrap_impl(@impl.once(event, callback))
179
224
  end
180
225
  end
181
226
  end
@@ -1,5 +1,5 @@
1
1
  module Playwright
2
- # - extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
2
+ # - extends: [EventEmitter]
3
3
  #
4
4
  # The `CDPSession` instances are used to talk raw Chrome Devtools Protocol:
5
5
  # - protocol methods can be called with `session.send` method.
@@ -22,6 +22,28 @@ module Playwright
22
22
  # playbackRate: response.playbackRate / 2
23
23
  # });
24
24
  # ```
25
+ #
26
+ # ```python async
27
+ # client = await page.context().new_cdp_session(page)
28
+ # await client.send("animation.enable")
29
+ # client.on("animation.animation_created", lambda: print("animation created!"))
30
+ # response = await client.send("animation.get_playback_rate")
31
+ # print("playback rate is " + response["playback_rate"])
32
+ # await client.send("animation.set_playback_rate", {
33
+ # playback_rate: response["playback_rate"] / 2
34
+ # })
35
+ # ```
36
+ #
37
+ # ```python sync
38
+ # client = page.context().new_cdp_session(page)
39
+ # client.send("animation.enable")
40
+ # client.on("animation.animation_created", lambda: print("animation created!"))
41
+ # response = client.send("animation.get_playback_rate")
42
+ # print("playback rate is " + response["playback_rate"])
43
+ # client.send("animation.set_playback_rate", {
44
+ # playback_rate: response["playback_rate"] / 2
45
+ # })
46
+ # ```
25
47
  class CDPSession < PlaywrightApi
26
48
 
27
49
  # Detaches the CDPSession from the target. Once detached, the CDPSession object won't emit any events and can't be used to
@@ -9,6 +9,16 @@ module Playwright
9
9
  # ```js
10
10
  # const backgroundPage = await context.waitForEvent('backgroundpage');
11
11
  # ```
12
+ #
13
+ # ```python async
14
+ # # FIXME
15
+ # background_page = await context.wait_for_event("backgroundpage")
16
+ # ```
17
+ #
18
+ # ```python sync
19
+ # # FIXME
20
+ # background_page = context.wait_for_event("backgroundpage")
21
+ # ```
12
22
  class ChromiumBrowserContext < BrowserContext
13
23
 
14
24
  # All existing background pages in the context.
@@ -28,20 +38,20 @@ module Playwright
28
38
 
29
39
  # -- inherited from EventEmitter --
30
40
  # @nodoc
31
- def off(event, callback)
32
- wrap_channel_owner(@channel_owner.off(event, callback))
41
+ def on(event, callback)
42
+ wrap_impl(@impl.on(event, callback))
33
43
  end
34
44
 
35
45
  # -- inherited from EventEmitter --
36
46
  # @nodoc
37
- def once(event, callback)
38
- wrap_channel_owner(@channel_owner.once(event, callback))
47
+ def off(event, callback)
48
+ wrap_impl(@impl.off(event, callback))
39
49
  end
40
50
 
41
51
  # -- inherited from EventEmitter --
42
52
  # @nodoc
43
- def on(event, callback)
44
- wrap_channel_owner(@channel_owner.on(event, callback))
53
+ def once(event, callback)
54
+ wrap_impl(@impl.once(event, callback))
45
55
  end
46
56
  end
47
57
  end
@@ -3,15 +3,15 @@ module Playwright
3
3
  class ConsoleMessage < PlaywrightApi
4
4
 
5
5
  def args
6
- wrap_channel_owner(@channel_owner.args)
6
+ wrap_impl(@impl.args)
7
7
  end
8
8
 
9
9
  def location
10
- wrap_channel_owner(@channel_owner.location)
10
+ wrap_impl(@impl.location)
11
11
  end
12
12
 
13
13
  def text
14
- wrap_channel_owner(@channel_owner.text)
14
+ wrap_impl(@impl.text)
15
15
  end
16
16
 
17
17
  # One of the following values: `'log'`, `'debug'`, `'info'`, `'error'`, `'warning'`, `'dir'`, `'dirxml'`, `'table'`,
@@ -23,25 +23,25 @@ module Playwright
23
23
 
24
24
  # @nodoc
25
25
  def type
26
- wrap_channel_owner(@channel_owner.type)
26
+ wrap_impl(@impl.type)
27
27
  end
28
28
 
29
29
  # -- inherited from EventEmitter --
30
30
  # @nodoc
31
- def off(event, callback)
32
- wrap_channel_owner(@channel_owner.off(event, callback))
31
+ def on(event, callback)
32
+ wrap_impl(@impl.on(event, callback))
33
33
  end
34
34
 
35
35
  # -- inherited from EventEmitter --
36
36
  # @nodoc
37
- def once(event, callback)
38
- wrap_channel_owner(@channel_owner.once(event, callback))
37
+ def off(event, callback)
38
+ wrap_impl(@impl.off(event, callback))
39
39
  end
40
40
 
41
41
  # -- inherited from EventEmitter --
42
42
  # @nodoc
43
- def on(event, callback)
44
- wrap_channel_owner(@channel_owner.on(event, callback))
43
+ def once(event, callback)
44
+ wrap_impl(@impl.once(event, callback))
45
45
  end
46
46
  end
47
47
  end
@@ -18,6 +18,48 @@ module Playwright
18
18
  # page.evaluate(() => alert('1'));
19
19
  # })();
20
20
  # ```
21
+ #
22
+ # ```python async
23
+ # import asyncio
24
+ # from playwright.async_api import async_playwright
25
+ #
26
+ # async def handle_dialog(dialog):
27
+ # print(dialog.message)
28
+ # await dialog.dismiss()
29
+ #
30
+ # async def run(playwright):
31
+ # chromium = playwright.chromium
32
+ # browser = await chromium.launch()
33
+ # page = await browser.new_page()
34
+ # page.on("dialog", handle_dialog)
35
+ # page.evaluate("alert('1')")
36
+ # await browser.close()
37
+ #
38
+ # async def main():
39
+ # async with async_playwright() as playwright:
40
+ # await run(playwright)
41
+ # asyncio.run(main())
42
+ # ```
43
+ #
44
+ # ```python sync
45
+ # # FIXME
46
+ # from playwright.sync_api import sync_playwright
47
+ #
48
+ # def handle_dialog(dialog):
49
+ # print(dialog.message)
50
+ # dialog.dismiss()
51
+ #
52
+ # def run(playwright):
53
+ # chromium = playwright.chromium
54
+ # browser = chromium.launch()
55
+ # page = browser.new_page()
56
+ # page.on("dialog", handle_dialog)
57
+ # page.evaluate("alert('1')")
58
+ # browser.close()
59
+ #
60
+ # with sync_playwright() as playwright:
61
+ # run(playwright)
62
+ # ```
21
63
  class Dialog < PlaywrightApi
22
64
 
23
65
  # Returns when the dialog has been accepted.
@@ -14,12 +14,27 @@ module Playwright
14
14
  # ]);
15
15
  # // wait for download to complete
16
16
  # const path = await download.path();
17
- # ...
18
17
  # ```
19
18
  #
20
- # > **NOTE** Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
21
- # downloaded content. If `acceptDownloads` is not set or set to `false`, download events are emitted, but the actual
22
- # download is not performed and user has no access to the downloaded files.
19
+ # ```python async
20
+ # async with page.expect_download() as download_info:
21
+ # await page.click("a")
22
+ # download = await download_info.value
23
+ # # waits for download to complete
24
+ # path = await download.path()
25
+ # ```
26
+ #
27
+ # ```python sync
28
+ # with page.expect_download() as download_info:
29
+ # page.click("a")
30
+ # download = download_info.value
31
+ # # wait for download to complete
32
+ # path = download.path()
33
+ # ```
34
+ #
35
+ # > NOTE: Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
36
+ # downloaded content. If `acceptDownloads` is not set, download events are emitted, but the actual download is not
37
+ # performed and user has no access to the downloaded files.
23
38
  class Download < PlaywrightApi
24
39
 
25
40
  # Returns readable stream for current download or `null` if download failed.
@@ -19,6 +19,41 @@ module Playwright
19
19
  # })();
20
20
  # ```
21
21
  #
22
+ # ```python async
23
+ # import asyncio
24
+ # from playwright.async_api import async_playwright
25
+ #
26
+ # async def run(playwright):
27
+ # chromium = playwright.chromium
28
+ # browser = await chromium.launch()
29
+ # page = await browser.new_page()
30
+ # await page.goto("https://example.com")
31
+ # href_element = await page.query_selector("a")
32
+ # await href_element.click()
33
+ # # ...
34
+ #
35
+ # async def main():
36
+ # async with async_playwright() as playwright:
37
+ # await run(playwright)
38
+ # asyncio.run(main())
39
+ # ```
40
+ #
41
+ # ```python sync
42
+ # from playwright.sync_api import sync_playwright
43
+ #
44
+ # def run(playwright):
45
+ # chromium = playwright.chromium
46
+ # browser = chromium.launch()
47
+ # page = browser.new_page()
48
+ # page.goto("https://example.com")
49
+ # href_element = page.query_selector("a")
50
+ # href_element.click()
51
+ # # ...
52
+ #
53
+ # with sync_playwright() as playwright:
54
+ # run(playwright)
55
+ # ```
56
+ #
22
57
  # ElementHandle prevents DOM element from garbage collection unless the handle is disposed with
23
58
  # [`method: JSHandle.dispose`]. ElementHandles are auto-disposed when their origin frame gets navigated.
24
59
  #
@@ -29,14 +64,14 @@ module Playwright
29
64
  # [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
30
65
  # returns `null`.
31
66
  def query_selector(selector)
32
- raise NotImplementedError.new('query_selector is not implemented yet.')
67
+ wrap_impl(@impl.query_selector(selector))
33
68
  end
34
69
 
35
70
  # The method finds all elements matching the specified selector in the `ElementHandle`s subtree. See
36
71
  # [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
37
72
  # returns empty array.
38
73
  def query_selector_all(selector)
39
- raise NotImplementedError.new('query_selector_all is not implemented yet.')
74
+ wrap_impl(@impl.query_selector_all(selector))
40
75
  end
41
76
 
42
77
  # Returns the return value of `pageFunction`
@@ -55,8 +90,20 @@ module Playwright
55
90
  # expect(await tweetHandle.$eval('.like', node => node.innerText)).toBe('100');
56
91
  # expect(await tweetHandle.$eval('.retweets', node => node.innerText)).toBe('10');
57
92
  # ```
93
+ #
94
+ # ```python async
95
+ # tweet_handle = await page.query_selector(".tweet")
96
+ # assert await tweet_handle.eval_on_selector(".like", "node => node.innerText") == "100"
97
+ # assert await tweet_handle.eval_on_selector(".retweets", "node => node.innerText") = "10"
98
+ # ```
99
+ #
100
+ # ```python sync
101
+ # tweet_handle = page.query_selector(".tweet")
102
+ # assert tweet_handle.eval_on_selector(".like", "node => node.innerText") == "100"
103
+ # assert tweet_handle.eval_on_selector(".retweets", "node => node.innerText") = "10"
104
+ # ```
58
105
  def eval_on_selector(selector, pageFunction, arg: nil)
59
- raise NotImplementedError.new('eval_on_selector is not implemented yet.')
106
+ wrap_impl(@impl.eval_on_selector(selector, pageFunction, arg: arg))
60
107
  end
61
108
 
62
109
  # Returns the return value of `pageFunction`
@@ -81,8 +128,19 @@ module Playwright
81
128
  # const feedHandle = await page.$('.feed');
82
129
  # expect(await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText))).toEqual(['Hello!', 'Hi!']);
83
130
  # ```
131
+ #
132
+ # ```python async
133
+ # # FIXME
134
+ # feed_handle = await page.query_selector(".feed")
135
+ # assert await feed_handle.eval_on_selector_all(".tweet", "nodes => nodes.map(n => n.innerText)") == ["hello!", "hi!"]
136
+ # ```
137
+ #
138
+ # ```python sync
139
+ # feed_handle = page.query_selector(".feed")
140
+ # assert feed_handle.eval_on_selector_all(".tweet", "nodes => nodes.map(n => n.innerText)") == ["hello!", "hi!"]
141
+ # ```
84
142
  def eval_on_selector_all(selector, pageFunction, arg: nil)
85
- raise NotImplementedError.new('eval_on_selector_all is not implemented yet.')
143
+ wrap_impl(@impl.eval_on_selector_all(selector, pageFunction, arg: arg))
86
144
  end
87
145
 
88
146
  # This method returns the bounding box of the element, or `null` if the element is not visible. The bounding box is
@@ -103,6 +161,16 @@ module Playwright
103
161
  # const box = await elementHandle.boundingBox();
104
162
  # await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2);
105
163
  # ```
164
+ #
165
+ # ```python async
166
+ # box = await element_handle.bounding_box()
167
+ # await page.mouse.click(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)
168
+ # ```
169
+ #
170
+ # ```python sync
171
+ # box = element_handle.bounding_box()
172
+ # page.mouse.click(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)
173
+ # ```
106
174
  def bounding_box
107
175
  raise NotImplementedError.new('bounding_box is not implemented yet.')
108
176
  end
@@ -143,7 +211,7 @@ module Playwright
143
211
  noWaitAfter: nil,
144
212
  position: nil,
145
213
  timeout: nil)
146
- raise NotImplementedError.new('click is not implemented yet.')
214
+ wrap_impl(@impl.click(button: button, clickCount: clickCount, delay: delay, force: force, modifiers: modifiers, noWaitAfter: noWaitAfter, position: position, timeout: timeout))
147
215
  end
148
216
 
149
217
  # Returns the content frame for element handles referencing iframe nodes, or `null` otherwise
@@ -163,7 +231,7 @@ module Playwright
163
231
  # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
164
232
  # Passing zero timeout disables this.
165
233
  #
166
- # > **NOTE** `elementHandle.dblclick()` dispatches two `click` events and a single `dblclick` event.
234
+ # > NOTE: `elementHandle.dblclick()` dispatches two `click` events and a single `dblclick` event.
167
235
  def dblclick(
168
236
  button: nil,
169
237
  delay: nil,
@@ -184,6 +252,14 @@ module Playwright
184
252
  # await elementHandle.dispatchEvent('click');
185
253
  # ```
186
254
  #
255
+ # ```python async
256
+ # await element_handle.dispatch_event("click")
257
+ # ```
258
+ #
259
+ # ```python sync
260
+ # element_handle.dispatch_event("click")
261
+ # ```
262
+ #
187
263
  # Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties
188
264
  # and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
189
265
  #
@@ -204,6 +280,18 @@ module Playwright
204
280
  # const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
205
281
  # await elementHandle.dispatchEvent('dragstart', { dataTransfer });
206
282
  # ```
283
+ #
284
+ # ```python async
285
+ # # note you can only create data_transfer in chromium and firefox
286
+ # data_transfer = await page.evaluate_handle("new DataTransfer()")
287
+ # await element_handle.dispatch_event("#source", "dragstart", {"dataTransfer": data_transfer})
288
+ # ```
289
+ #
290
+ # ```python sync
291
+ # # note you can only create data_transfer in chromium and firefox
292
+ # data_transfer = page.evaluate_handle("new DataTransfer()")
293
+ # element_handle.dispatch_event("#source", "dragstart", {"dataTransfer": data_transfer})
294
+ # ```
207
295
  def dispatch_event(type, eventInit: nil)
208
296
  raise NotImplementedError.new('dispatch_event is not implemented yet.')
209
297
  end
@@ -303,7 +391,7 @@ module Playwright
303
391
  # Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported as well. When speficied with the
304
392
  # modifier, modifier is pressed and being held while the subsequent key is being pressed.
305
393
  def press(key, delay: nil, noWaitAfter: nil, timeout: nil)
306
- raise NotImplementedError.new('press is not implemented yet.')
394
+ wrap_impl(@impl.press(key, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout))
307
395
  end
308
396
 
309
397
  # Returns the buffer with the captured screenshot.
@@ -321,7 +409,7 @@ module Playwright
321
409
 
322
410
  # This method waits for [actionability](./actionability.md) checks, then tries to scroll element into view, unless it is
323
411
  # completely visible as defined by
324
- # [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)'s ```ratio```.
412
+ # [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)'s `ratio`.
325
413
  #
326
414
  # Throws when `elementHandle` does not point to an element
327
415
  # [connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot.
@@ -334,19 +422,48 @@ module Playwright
334
422
  # Triggers a `change` and `input` event once all the provided options have been selected. If element is not a `<select>`
335
423
  # element, the method throws an error.
336
424
  #
425
+ # Will wait until all specified options are present in the `<select>` element.
426
+ #
337
427
  #
338
428
  # ```js
339
429
  # // single selection matching the value
340
430
  # handle.selectOption('blue');
341
431
  #
342
- # // single selection matching both the value and the label
432
+ # // single selection matching the label
343
433
  # handle.selectOption({ label: 'Blue' });
344
434
  #
345
435
  # // multiple selection
346
- # handle.selectOption('red', 'green', 'blue');
436
+ # handle.selectOption(['red', 'green', 'blue']);
437
+ # ```
347
438
  #
348
- # // multiple selection for blue, red and second option
349
- # handle.selectOption({ value: 'blue' }, { index: 2 }, 'red');
439
+ # ```python async
440
+ # # single selection matching the value
441
+ # await handle.select_option("blue")
442
+ # # single selection matching the label
443
+ # await handle.select_option(label="blue")
444
+ # # multiple selection
445
+ # await handle.select_option(value=["red", "green", "blue"])
446
+ # ```
447
+ #
448
+ # ```python sync
449
+ # # single selection matching the value
450
+ # handle.select_option("blue")
451
+ # # single selection matching both the label
452
+ # handle.select_option(label="blue")
453
+ # # multiple selection
454
+ # handle.select_option(value=["red", "green", "blue"])
455
+ # ```
456
+ #
457
+ # ```python sync
458
+ # # FIXME
459
+ # # single selection matching the value
460
+ # handle.select_option("blue")
461
+ # # single selection matching both the value and the label
462
+ # handle.select_option(label="blue")
463
+ # # multiple selection
464
+ # handle.select_option("red", "green", "blue")
465
+ # # multiple selection for blue, red and second option
466
+ # handle.select_option(value="blue", { index: 2 }, "red")
350
467
  # ```
351
468
  def select_option(values, noWaitAfter: nil, timeout: nil)
352
469
  raise NotImplementedError.new('select_option is not implemented yet.')
@@ -379,7 +496,7 @@ module Playwright
379
496
  # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
380
497
  # Passing zero timeout disables this.
381
498
  #
382
- # > **NOTE** `elementHandle.tap()` requires that the `hasTouch` option of the browser context be set to true.
499
+ # > NOTE: `elementHandle.tap()` requires that the `hasTouch` option of the browser context be set to true.
383
500
  def tap_point(
384
501
  force: nil,
385
502
  modifiers: nil,
@@ -404,6 +521,16 @@ module Playwright
404
521
  # await elementHandle.type('World', {delay: 100}); // Types slower, like a user
405
522
  # ```
406
523
  #
524
+ # ```python async
525
+ # await element_handle.type("hello") # types instantly
526
+ # await element_handle.type("world", delay=100) # types slower, like a user
527
+ # ```
528
+ #
529
+ # ```python sync
530
+ # element_handle.type("hello") # types instantly
531
+ # element_handle.type("world", delay=100) # types slower, like a user
532
+ # ```
533
+ #
407
534
  # An example of typing into a text field and then submitting the form:
408
535
  #
409
536
  #
@@ -412,8 +539,20 @@ module Playwright
412
539
  # await elementHandle.type('some text');
413
540
  # await elementHandle.press('Enter');
414
541
  # ```
542
+ #
543
+ # ```python async
544
+ # element_handle = await page.query_selector("input")
545
+ # await element_handle.type("some text")
546
+ # await element_handle.press("Enter")
547
+ # ```
548
+ #
549
+ # ```python sync
550
+ # element_handle = page.query_selector("input")
551
+ # element_handle.type("some text")
552
+ # element_handle.press("Enter")
553
+ # ```
415
554
  def type_text(text, delay: nil, noWaitAfter: nil, timeout: nil)
416
- raise NotImplementedError.new('type_text is not implemented yet.')
555
+ wrap_impl(@impl.type_text(text, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout))
417
556
  end
418
557
 
419
558
  # This method checks the element by performing the following steps:
@@ -467,27 +606,41 @@ module Playwright
467
606
  # const span = await div.waitForSelector('span', { state: 'attached' });
468
607
  # ```
469
608
  #
470
- # > **NOTE** This method does not work across navigations, use [`method: Page.waitForSelector`] instead.
609
+ # ```python async
610
+ # await page.set_content("<div><span></span></div>")
611
+ # div = await page.query_selector("div")
612
+ # # waiting for the "span" selector relative to the div.
613
+ # span = await div.wait_for_selector("span", state="attached")
614
+ # ```
615
+ #
616
+ # ```python sync
617
+ # page.set_content("<div><span></span></div>")
618
+ # div = page.query_selector("div")
619
+ # # waiting for the "span" selector relative to the div.
620
+ # span = div.wait_for_selector("span", state="attached")
621
+ # ```
622
+ #
623
+ # > NOTE: This method does not work across navigations, use [`method: Page.waitForSelector`] instead.
471
624
  def wait_for_selector(selector, state: nil, timeout: nil)
472
625
  raise NotImplementedError.new('wait_for_selector is not implemented yet.')
473
626
  end
474
627
 
475
628
  # -- inherited from EventEmitter --
476
629
  # @nodoc
477
- def off(event, callback)
478
- wrap_channel_owner(@channel_owner.off(event, callback))
630
+ def on(event, callback)
631
+ wrap_impl(@impl.on(event, callback))
479
632
  end
480
633
 
481
634
  # -- inherited from EventEmitter --
482
635
  # @nodoc
483
- def once(event, callback)
484
- wrap_channel_owner(@channel_owner.once(event, callback))
636
+ def off(event, callback)
637
+ wrap_impl(@impl.off(event, callback))
485
638
  end
486
639
 
487
640
  # -- inherited from EventEmitter --
488
641
  # @nodoc
489
- def on(event, callback)
490
- wrap_channel_owner(@channel_owner.on(event, callback))
642
+ def once(event, callback)
643
+ wrap_impl(@impl.once(event, callback))
491
644
  end
492
645
  end
493
646
  end