playwright-ruby-client 0.0.5 → 0.1.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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +114 -2
  3. data/docs/api_coverage.md +351 -0
  4. data/lib/playwright.rb +7 -1
  5. data/lib/playwright/android_input_impl.rb +23 -0
  6. data/lib/playwright/api_implementation.rb +18 -0
  7. data/lib/playwright/channel.rb +7 -0
  8. data/lib/playwright/channel_owner.rb +3 -2
  9. data/lib/playwright/channel_owners/android.rb +10 -1
  10. data/lib/playwright/channel_owners/android_device.rb +163 -0
  11. data/lib/playwright/channel_owners/browser.rb +13 -13
  12. data/lib/playwright/channel_owners/browser_context.rb +9 -1
  13. data/lib/playwright/channel_owners/download.rb +27 -0
  14. data/lib/playwright/channel_owners/element_handle.rb +306 -0
  15. data/lib/playwright/channel_owners/frame.rb +371 -19
  16. data/lib/playwright/channel_owners/js_handle.rb +51 -0
  17. data/lib/playwright/channel_owners/page.rb +416 -19
  18. data/lib/playwright/channel_owners/request.rb +98 -0
  19. data/lib/playwright/channel_owners/webkit_browser.rb +1 -1
  20. data/lib/playwright/connection.rb +9 -6
  21. data/lib/playwright/errors.rb +2 -2
  22. data/lib/playwright/event_emitter.rb +8 -1
  23. data/lib/playwright/event_emitter_proxy.rb +49 -0
  24. data/lib/playwright/file_chooser_impl.rb +23 -0
  25. data/lib/playwright/http_headers.rb +20 -0
  26. data/lib/playwright/input_files.rb +42 -0
  27. data/lib/playwright/javascript/expression.rb +37 -0
  28. data/lib/playwright/javascript/function.rb +37 -0
  29. data/lib/playwright/javascript/value_parser.rb +1 -1
  30. data/lib/playwright/javascript/value_serializer.rb +11 -11
  31. data/lib/playwright/keyboard_impl.rb +36 -0
  32. data/lib/playwright/mouse_impl.rb +7 -0
  33. data/lib/playwright/playwright_api.rb +84 -29
  34. data/lib/playwright/select_option_values.rb +32 -0
  35. data/lib/playwright/timeout_settings.rb +2 -2
  36. data/lib/playwright/touchscreen_impl.rb +7 -0
  37. data/lib/playwright/url_matcher.rb +19 -0
  38. data/lib/playwright/utils.rb +18 -0
  39. data/lib/playwright/version.rb +1 -1
  40. data/lib/playwright/wait_helper.rb +1 -1
  41. data/lib/playwright_api/accessibility.rb +46 -6
  42. data/lib/playwright_api/android.rb +37 -0
  43. data/lib/playwright_api/android_device.rb +82 -0
  44. data/lib/playwright_api/android_input.rb +25 -0
  45. data/lib/playwright_api/binding_call.rb +10 -6
  46. data/lib/playwright_api/browser.rb +85 -18
  47. data/lib/playwright_api/browser_context.rb +269 -37
  48. data/lib/playwright_api/browser_type.rb +60 -11
  49. data/lib/playwright_api/cdp_session.rb +23 -1
  50. data/lib/playwright_api/chromium_browser_context.rb +18 -6
  51. data/lib/playwright_api/console_message.rb +14 -15
  52. data/lib/playwright_api/dialog.rb +48 -2
  53. data/lib/playwright_api/download.rb +47 -10
  54. data/lib/playwright_api/element_handle.rb +269 -110
  55. data/lib/playwright_api/file_chooser.rb +23 -7
  56. data/lib/playwright_api/frame.rb +439 -154
  57. data/lib/playwright_api/js_handle.rb +69 -24
  58. data/lib/playwright_api/keyboard.rb +99 -9
  59. data/lib/playwright_api/mouse.rb +22 -0
  60. data/lib/playwright_api/page.rb +856 -229
  61. data/lib/playwright_api/playwright.rb +108 -20
  62. data/lib/playwright_api/request.rb +77 -29
  63. data/lib/playwright_api/response.rb +10 -13
  64. data/lib/playwright_api/route.rb +49 -0
  65. data/lib/playwright_api/selectors.rb +20 -8
  66. data/lib/playwright_api/video.rb +8 -0
  67. data/lib/playwright_api/web_socket.rb +0 -8
  68. data/lib/playwright_api/worker.rb +25 -13
  69. data/playwright.gemspec +1 -0
  70. metadata +33 -2
@@ -0,0 +1,25 @@
1
+ module Playwright
2
+ # @nodoc
3
+ class AndroidInput < PlaywrightApi
4
+
5
+ # @nodoc
6
+ def type(text)
7
+ wrap_impl(@impl.type(unwrap_impl(text)))
8
+ end
9
+
10
+ # @nodoc
11
+ def tap_point(point)
12
+ wrap_impl(@impl.tap_point(unwrap_impl(point)))
13
+ end
14
+
15
+ # @nodoc
16
+ def drag(from, to, steps)
17
+ wrap_impl(@impl.drag(unwrap_impl(from), unwrap_impl(to), unwrap_impl(steps)))
18
+ end
19
+
20
+ # @nodoc
21
+ def press(key)
22
+ wrap_impl(@impl.press(unwrap_impl(key)))
23
+ end
24
+ end
25
+ end
@@ -4,20 +4,24 @@ module Playwright
4
4
 
5
5
  # -- inherited from EventEmitter --
6
6
  # @nodoc
7
- def off(event, callback)
8
- wrap_channel_owner(@channel_owner.off(event, callback))
7
+ def once(event, callback)
8
+ event_emitter_proxy.once(event, callback)
9
9
  end
10
10
 
11
11
  # -- inherited from EventEmitter --
12
12
  # @nodoc
13
- def once(event, callback)
14
- wrap_channel_owner(@channel_owner.once(event, callback))
13
+ def on(event, callback)
14
+ event_emitter_proxy.on(event, callback)
15
15
  end
16
16
 
17
17
  # -- inherited from EventEmitter --
18
18
  # @nodoc
19
- def on(event, callback)
20
- wrap_channel_owner(@channel_owner.on(event, callback))
19
+ def off(event, callback)
20
+ event_emitter_proxy.off(event, callback)
21
+ end
22
+
23
+ private def event_emitter_proxy
24
+ @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
21
25
  end
22
26
  end
23
27
  end
@@ -1,7 +1,7 @@
1
1
  module Playwright
2
- # - extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
2
+ # - extends: [EventEmitter]
3
3
  #
4
- # A Browser is created via [`method: BrowserType.launch`]. An example of using a `Browser` to create a [Page]:
4
+ # A Browser is created via [`method: BrowserType.launch`]. An example of using a `Browser` to create a `Page`:
5
5
  #
6
6
  #
7
7
  # ```js
@@ -15,8 +15,36 @@ module Playwright
15
15
  # })();
16
16
  # ```
17
17
  #
18
- # See `ChromiumBrowser`, [FirefoxBrowser] and [WebKitBrowser] for browser-specific features. Note that
19
- # [`method: BrowserType.launch`] always returns a specific browser instance, based on the browser being launched.
18
+ # ```python async
19
+ # import asyncio
20
+ # from playwright.async_api import async_playwright
21
+ #
22
+ # async def run(playwright):
23
+ # firefox = playwright.firefox
24
+ # browser = await firefox.launch()
25
+ # page = await browser.new_page()
26
+ # await page.goto("https://example.com")
27
+ # await browser.close()
28
+ #
29
+ # async def main():
30
+ # async with async_playwright() as playwright:
31
+ # await run(playwright)
32
+ # asyncio.run(main())
33
+ # ```
34
+ #
35
+ # ```python sync
36
+ # from playwright.sync_api import sync_playwright
37
+ #
38
+ # def run(playwright):
39
+ # firefox = playwright.firefox
40
+ # browser = firefox.launch()
41
+ # page = browser.new_page()
42
+ # page.goto("https://example.com")
43
+ # browser.close()
44
+ #
45
+ # with sync_playwright() as playwright:
46
+ # run(playwright)
47
+ # ```
20
48
  class Browser < PlaywrightApi
21
49
 
22
50
  # In case this browser is obtained using [`method: BrowserType.launch`], closes the browser and all of its pages (if any
@@ -27,7 +55,7 @@ module Playwright
27
55
  #
28
56
  # The `Browser` object itself is considered to be disposed and cannot be used anymore.
29
57
  def close
30
- wrap_channel_owner(@channel_owner.close)
58
+ wrap_impl(@impl.close)
31
59
  end
32
60
 
33
61
  # Returns an array of all open browser contexts. In a newly created browser, this will return zero browser contexts.
@@ -40,13 +68,27 @@ module Playwright
40
68
  # const context = await browser.newContext();
41
69
  # console.log(browser.contexts().length); // prints `1`
42
70
  # ```
71
+ #
72
+ # ```python async
73
+ # browser = await pw.webkit.launch()
74
+ # print(len(browser.contexts())) # prints `0`
75
+ # context = await browser.new_context()
76
+ # print(len(browser.contexts())) # prints `1`
77
+ # ```
78
+ #
79
+ # ```python sync
80
+ # browser = pw.webkit.launch()
81
+ # print(len(browser.contexts())) # prints `0`
82
+ # context = browser.new_context()
83
+ # print(len(browser.contexts())) # prints `1`
84
+ # ```
43
85
  def contexts
44
- wrap_channel_owner(@channel_owner.contexts)
86
+ wrap_impl(@impl.contexts)
45
87
  end
46
88
 
47
89
  # Indicates that the browser is connected.
48
90
  def connected?
49
- wrap_channel_owner(@channel_owner.connected?)
91
+ wrap_impl(@impl.connected?)
50
92
  end
51
93
 
52
94
  # Creates a new browser context. It won't share cookies/cache with other browser contexts.
@@ -62,6 +104,24 @@ module Playwright
62
104
  # await page.goto('https://example.com');
63
105
  # })();
64
106
  # ```
107
+ #
108
+ # ```python async
109
+ # browser = await playwright.firefox.launch() # or "chromium" or "webkit".
110
+ # # create a new incognito browser context.
111
+ # context = await browser.new_context()
112
+ # # create a new page in a pristine context.
113
+ # page = await context.new_page()
114
+ # await page.goto("https://example.com")
115
+ # ```
116
+ #
117
+ # ```python sync
118
+ # browser = playwright.firefox.launch() # or "chromium" or "webkit".
119
+ # # create a new incognito browser context.
120
+ # context = browser.new_context()
121
+ # # create a new page in a pristine context.
122
+ # page = context.new_page()
123
+ # page.goto("https://example.com")
124
+ # ```
65
125
  def new_context(
66
126
  acceptDownloads: nil,
67
127
  bypassCSP: nil,
@@ -82,12 +142,14 @@ module Playwright
82
142
  recordHar: nil,
83
143
  recordVideo: nil,
84
144
  storageState: nil,
145
+ storageStatePath: nil,
85
146
  timezoneId: nil,
86
147
  userAgent: nil,
87
148
  videoSize: nil,
88
149
  videosPath: nil,
89
- viewport: nil)
90
- wrap_channel_owner(@channel_owner.new_context(acceptDownloads: acceptDownloads, bypassCSP: bypassCSP, colorScheme: colorScheme, deviceScaleFactor: deviceScaleFactor, extraHTTPHeaders: extraHTTPHeaders, geolocation: geolocation, hasTouch: hasTouch, httpCredentials: httpCredentials, ignoreHTTPSErrors: ignoreHTTPSErrors, isMobile: isMobile, javaScriptEnabled: javaScriptEnabled, locale: locale, logger: logger, offline: offline, permissions: permissions, proxy: proxy, recordHar: recordHar, recordVideo: recordVideo, storageState: storageState, timezoneId: timezoneId, userAgent: userAgent, videoSize: videoSize, videosPath: videosPath, viewport: viewport))
150
+ viewport: nil,
151
+ &block)
152
+ wrap_impl(@impl.new_context(acceptDownloads: unwrap_impl(acceptDownloads), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), logger: unwrap_impl(logger), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), recordHar: unwrap_impl(recordHar), recordVideo: unwrap_impl(recordVideo), storageState: unwrap_impl(storageState), storageStatePath: unwrap_impl(storageStatePath), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), videoSize: unwrap_impl(videoSize), videosPath: unwrap_impl(videosPath), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
91
153
  end
92
154
 
93
155
  # Creates a new page in a new browser context. Closing this page will close the context as well.
@@ -115,40 +177,45 @@ module Playwright
115
177
  recordHar: nil,
116
178
  recordVideo: nil,
117
179
  storageState: nil,
180
+ storageStatePath: nil,
118
181
  timezoneId: nil,
119
182
  userAgent: nil,
120
183
  videoSize: nil,
121
184
  videosPath: nil,
122
185
  viewport: nil)
123
- wrap_channel_owner(@channel_owner.new_page(acceptDownloads: acceptDownloads, bypassCSP: bypassCSP, colorScheme: colorScheme, deviceScaleFactor: deviceScaleFactor, extraHTTPHeaders: extraHTTPHeaders, geolocation: geolocation, hasTouch: hasTouch, httpCredentials: httpCredentials, ignoreHTTPSErrors: ignoreHTTPSErrors, isMobile: isMobile, javaScriptEnabled: javaScriptEnabled, locale: locale, logger: logger, offline: offline, permissions: permissions, proxy: proxy, recordHar: recordHar, recordVideo: recordVideo, storageState: storageState, timezoneId: timezoneId, userAgent: userAgent, videoSize: videoSize, videosPath: videosPath, viewport: viewport))
186
+ wrap_impl(@impl.new_page(acceptDownloads: unwrap_impl(acceptDownloads), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), logger: unwrap_impl(logger), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), proxy: unwrap_impl(proxy), recordHar: unwrap_impl(recordHar), recordVideo: unwrap_impl(recordVideo), storageState: unwrap_impl(storageState), storageStatePath: unwrap_impl(storageStatePath), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), videoSize: unwrap_impl(videoSize), videosPath: unwrap_impl(videosPath), viewport: unwrap_impl(viewport)))
124
187
  end
125
188
 
126
189
  # Returns the browser version.
127
190
  def version
128
- wrap_channel_owner(@channel_owner.version)
191
+ wrap_impl(@impl.version)
129
192
  end
130
193
 
131
194
  # @nodoc
132
195
  def after_initialize
133
- wrap_channel_owner(@channel_owner.after_initialize)
196
+ wrap_impl(@impl.after_initialize)
134
197
  end
135
198
 
136
199
  # -- inherited from EventEmitter --
137
200
  # @nodoc
138
- def off(event, callback)
139
- wrap_channel_owner(@channel_owner.off(event, callback))
201
+ def once(event, callback)
202
+ event_emitter_proxy.once(event, callback)
140
203
  end
141
204
 
142
205
  # -- inherited from EventEmitter --
143
206
  # @nodoc
144
- def once(event, callback)
145
- wrap_channel_owner(@channel_owner.once(event, callback))
207
+ def on(event, callback)
208
+ event_emitter_proxy.on(event, callback)
146
209
  end
147
210
 
148
211
  # -- inherited from EventEmitter --
149
212
  # @nodoc
150
- def on(event, callback)
151
- wrap_channel_owner(@channel_owner.on(event, callback))
213
+ def off(event, callback)
214
+ event_emitter_proxy.off(event, callback)
215
+ end
216
+
217
+ private def event_emitter_proxy
218
+ @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
152
219
  end
153
220
  end
154
221
  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
  # BrowserContexts provide a way to operate multiple independent browser sessions.
5
5
  #
@@ -19,6 +19,26 @@ module Playwright
19
19
  # // Dispose context once it's no longer needed.
20
20
  # await context.close();
21
21
  # ```
22
+ #
23
+ # ```python async
24
+ # # create a new incognito browser context
25
+ # context = await browser.new_context()
26
+ # # create a new page inside context.
27
+ # page = await context.new_page()
28
+ # await page.goto("https://example.com")
29
+ # # dispose context once it"s no longer needed.
30
+ # await context.close()
31
+ # ```
32
+ #
33
+ # ```python sync
34
+ # # create a new incognito browser context
35
+ # context = browser.new_context()
36
+ # # create a new page inside context.
37
+ # page = context.new_page()
38
+ # page.goto("https://example.com")
39
+ # # dispose context once it"s no longer needed.
40
+ # context.close()
41
+ # ```
22
42
  class BrowserContext < PlaywrightApi
23
43
 
24
44
  # Adds cookies into this browser context. All pages within this context will have these cookies installed. Cookies can be
@@ -28,6 +48,14 @@ module Playwright
28
48
  # ```js
29
49
  # await browserContext.addCookies([cookieObject1, cookieObject2]);
30
50
  # ```
51
+ #
52
+ # ```python async
53
+ # await browser_context.add_cookies([cookie_object1, cookie_object2])
54
+ # ```
55
+ #
56
+ # ```python sync
57
+ # browser_context.add_cookies([cookie_object1, cookie_object2])
58
+ # ```
31
59
  def add_cookies(cookies)
32
60
  raise NotImplementedError.new('add_cookies is not implemented yet.')
33
61
  end
@@ -43,7 +71,7 @@ module Playwright
43
71
  # An example of overriding `Math.random` before the page loads:
44
72
  #
45
73
  #
46
- # ```js
74
+ # ```js browser
47
75
  # // preload.js
48
76
  # Math.random = () => 42;
49
77
  # ```
@@ -56,7 +84,17 @@ module Playwright
56
84
  # });
57
85
  # ```
58
86
  #
59
- # > **NOTE** The order of evaluation of multiple scripts installed via [`method: BrowserContext.addInitScript`] and
87
+ # ```python async
88
+ # # in your playwright script, assuming the preload.js file is in same directory.
89
+ # await browser_context.add_init_script(path="preload.js")
90
+ # ```
91
+ #
92
+ # ```python sync
93
+ # # in your playwright script, assuming the preload.js file is in same directory.
94
+ # browser_context.add_init_script(path="preload.js")
95
+ # ```
96
+ #
97
+ # > NOTE: The order of evaluation of multiple scripts installed via [`method: BrowserContext.addInitScript`] and
60
98
  # [`method: Page.addInitScript`] is not defined.
61
99
  def add_init_script(script, arg: nil)
62
100
  raise NotImplementedError.new('add_init_script is not implemented yet.')
@@ -81,15 +119,29 @@ module Playwright
81
119
  # // do stuff ..
82
120
  # context.clearPermissions();
83
121
  # ```
122
+ #
123
+ # ```python async
124
+ # context = await browser.new_context()
125
+ # await context.grant_permissions(["clipboard-read"])
126
+ # # do stuff ..
127
+ # context.clear_permissions()
128
+ # ```
129
+ #
130
+ # ```python sync
131
+ # context = browser.new_context()
132
+ # context.grant_permissions(["clipboard-read"])
133
+ # # do stuff ..
134
+ # context.clear_permissions()
135
+ # ```
84
136
  def clear_permissions
85
137
  raise NotImplementedError.new('clear_permissions is not implemented yet.')
86
138
  end
87
139
 
88
140
  # Closes the browser context. All the pages that belong to the browser context will be closed.
89
141
  #
90
- # > **NOTE** the default browser context cannot be closed.
142
+ # > NOTE: The default browser context cannot be closed.
91
143
  def close
92
- wrap_channel_owner(@channel_owner.close)
144
+ wrap_impl(@impl.close)
93
145
  end
94
146
 
95
147
  # If no URLs are specified, this method returns all cookies. If URLs are specified, only cookies that affect those URLs
@@ -131,6 +183,57 @@ module Playwright
131
183
  # })();
132
184
  # ```
133
185
  #
186
+ # ```python async
187
+ # import asyncio
188
+ # from playwright.async_api import async_playwright
189
+ #
190
+ # async def run(playwright):
191
+ # webkit = playwright.webkit
192
+ # browser = await webkit.launch(headless=false)
193
+ # context = await browser.new_context()
194
+ # await context.expose_binding("pageURL", lambda source: source["page"].url)
195
+ # page = await context.new_page()
196
+ # await page.set_content("""
197
+ # <script>
198
+ # async function onClick() {
199
+ # document.querySelector('div').textContent = await window.pageURL();
200
+ # }
201
+ # </script>
202
+ # <button onclick="onClick()">Click me</button>
203
+ # <div></div>
204
+ # """)
205
+ # await page.click("button")
206
+ #
207
+ # async def main():
208
+ # async with async_playwright() as playwright:
209
+ # await run(playwright)
210
+ # asyncio.run(main())
211
+ # ```
212
+ #
213
+ # ```python sync
214
+ # from playwright.sync_api import sync_playwright
215
+ #
216
+ # def run(playwright):
217
+ # webkit = playwright.webkit
218
+ # browser = webkit.launch(headless=false)
219
+ # context = browser.new_context()
220
+ # context.expose_binding("pageURL", lambda source: source["page"].url)
221
+ # page = context.new_page()
222
+ # page.set_content("""
223
+ # <script>
224
+ # async function onClick() {
225
+ # document.querySelector('div').textContent = await window.pageURL();
226
+ # }
227
+ # </script>
228
+ # <button onclick="onClick()">Click me</button>
229
+ # <div></div>
230
+ # """)
231
+ # page.click("button")
232
+ #
233
+ # with sync_playwright() as playwright:
234
+ # run(playwright)
235
+ # ```
236
+ #
134
237
  # An example of passing an element handle:
135
238
  #
136
239
  #
@@ -146,6 +249,34 @@ module Playwright
146
249
  # <div>Or click me</div>
147
250
  # `);
148
251
  # ```
252
+ #
253
+ # ```python async
254
+ # async def print(source, element):
255
+ # print(await element.text_content())
256
+ #
257
+ # await context.expose_binding("clicked", print, handle=true)
258
+ # await page.set_content("""
259
+ # <script>
260
+ # document.addEventListener('click', event => window.clicked(event.target));
261
+ # </script>
262
+ # <div>Click me</div>
263
+ # <div>Or click me</div>
264
+ # """)
265
+ # ```
266
+ #
267
+ # ```python sync
268
+ # def print(source, element):
269
+ # print(element.text_content())
270
+ #
271
+ # context.expose_binding("clicked", print, handle=true)
272
+ # page.set_content("""
273
+ # <script>
274
+ # document.addEventListener('click', event => window.clicked(event.target));
275
+ # </script>
276
+ # <div>Click me</div>
277
+ # <div>Or click me</div>
278
+ # """)
279
+ # ```
149
280
  def expose_binding(name, callback, handle: nil)
150
281
  raise NotImplementedError.new('expose_binding is not implemented yet.')
151
282
  end
@@ -181,6 +312,72 @@ module Playwright
181
312
  # await page.click('button');
182
313
  # })();
183
314
  # ```
315
+ #
316
+ # ```python async
317
+ # import asyncio
318
+ # import hashlib
319
+ # from playwright.async_api import async_playwright
320
+ #
321
+ # async def sha1(text):
322
+ # m = hashlib.sha1()
323
+ # m.update(bytes(text, "utf8"))
324
+ # return m.hexdigest()
325
+ #
326
+ #
327
+ # async def run(playwright):
328
+ # webkit = playwright.webkit
329
+ # browser = await webkit.launch(headless=False)
330
+ # context = await browser.new_context()
331
+ # await context.expose_function("sha1", sha1)
332
+ # page = await context.new_page()
333
+ # await page.set_content("""
334
+ # <script>
335
+ # async function onClick() {
336
+ # document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');
337
+ # }
338
+ # </script>
339
+ # <button onclick="onClick()">Click me</button>
340
+ # <div></div>
341
+ # """)
342
+ # await page.click("button")
343
+ #
344
+ # async def main():
345
+ # async with async_playwright() as playwright:
346
+ # await run(playwright)
347
+ # asyncio.run(main())
348
+ # ```
349
+ #
350
+ # ```python sync
351
+ # import hashlib
352
+ # from playwright.sync_api import sync_playwright
353
+ #
354
+ # def sha1(text):
355
+ # m = hashlib.sha1()
356
+ # m.update(bytes(text, "utf8"))
357
+ # return m.hexdigest()
358
+ #
359
+ #
360
+ # def run(playwright):
361
+ # webkit = playwright.webkit
362
+ # browser = webkit.launch(headless=False)
363
+ # context = browser.new_context()
364
+ # context.expose_function("sha1", sha1)
365
+ # page = context.new_page()
366
+ # page.expose_function("sha1", sha1)
367
+ # page.set_content("""
368
+ # <script>
369
+ # async function onClick() {
370
+ # document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');
371
+ # }
372
+ # </script>
373
+ # <button onclick="onClick()">Click me</button>
374
+ # <div></div>
375
+ # """)
376
+ # page.click("button")
377
+ #
378
+ # with sync_playwright() as playwright:
379
+ # run(playwright)
380
+ # ```
184
381
  def expose_function(name, callback)
185
382
  raise NotImplementedError.new('expose_function is not implemented yet.')
186
383
  end
@@ -193,13 +390,13 @@ module Playwright
193
390
 
194
391
  # Creates a new page in the browser context.
195
392
  def new_page
196
- wrap_channel_owner(@channel_owner.new_page)
393
+ wrap_impl(@impl.new_page)
197
394
  end
198
395
 
199
396
  # Returns all open pages in the context. Non visible pages, such as `"background_page"`, will not be listed here. You can
200
397
  # find them using [`method: ChromiumBrowserContext.backgroundPages`].
201
398
  def pages
202
- wrap_channel_owner(@channel_owner.pages)
399
+ wrap_impl(@impl.pages)
203
400
  end
204
401
 
205
402
  # Routing provides the capability to modify network requests that are made by any page in the browser context. Once route
@@ -216,6 +413,22 @@ module Playwright
216
413
  # await browser.close();
217
414
  # ```
218
415
  #
416
+ # ```python async
417
+ # context = await browser.new_context()
418
+ # page = await context.new_page()
419
+ # await context.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
420
+ # await page.goto("https://example.com")
421
+ # await browser.close()
422
+ # ```
423
+ #
424
+ # ```python sync
425
+ # context = browser.new_context()
426
+ # page = context.new_page()
427
+ # context.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
428
+ # page.goto("https://example.com")
429
+ # browser.close()
430
+ # ```
431
+ #
219
432
  # or the same snippet using a regex pattern instead:
220
433
  #
221
434
  #
@@ -227,10 +440,29 @@ module Playwright
227
440
  # await browser.close();
228
441
  # ```
229
442
  #
443
+ # ```python async
444
+ # context = await browser.new_context()
445
+ # page = await context.new_page()
446
+ # await context.route(re.compile(r"(\.png$)|(\.jpg$)"), lambda route: route.abort())
447
+ # page = await context.new_page()
448
+ # await page.goto("https://example.com")
449
+ # await browser.close()
450
+ # ```
451
+ #
452
+ # ```python sync
453
+ # context = browser.new_context()
454
+ # page = context.new_page()
455
+ # context.route(re.compile(r"(\.png$)|(\.jpg$)"), lambda route: route.abort())
456
+ # page = await context.new_page()
457
+ # page = context.new_page()
458
+ # page.goto("https://example.com")
459
+ # browser.close()
460
+ # ```
461
+ #
230
462
  # Page routes (set up with [`method: Page.route`]) take precedence over browser context routes when request matches both
231
463
  # handlers.
232
464
  #
233
- # > **NOTE** Enabling routing disables http cache.
465
+ # > NOTE: Enabling routing disables http cache.
234
466
  def route(url, handler)
235
467
  raise NotImplementedError.new('route is not implemented yet.')
236
468
  end
@@ -243,7 +475,7 @@ module Playwright
243
475
  # - [`method: Page.setContent`]
244
476
  # - [`method: Page.waitForNavigation`]
245
477
  #
246
- # > **NOTE** [`method: Page.setDefaultNavigationTimeout`] and [`method: Page.setDefaultTimeout`] take priority over
478
+ # > NOTE: [`method: Page.setDefaultNavigationTimeout`] and [`method: Page.setDefaultTimeout`] take priority over
247
479
  # [`method: BrowserContext.setDefaultNavigationTimeout`].
248
480
  def set_default_navigation_timeout(timeout)
249
481
  raise NotImplementedError.new('set_default_navigation_timeout is not implemented yet.')
@@ -252,7 +484,7 @@ module Playwright
252
484
 
253
485
  # This setting will change the default maximum time for all the methods accepting `timeout` option.
254
486
  #
255
- # > **NOTE** [`method: Page.setDefaultNavigationTimeout`], [`method: Page.setDefaultTimeout`] and
487
+ # > NOTE: [`method: Page.setDefaultNavigationTimeout`], [`method: Page.setDefaultTimeout`] and
256
488
  # [`method: BrowserContext.setDefaultNavigationTimeout`] take priority over [`method: BrowserContext.setDefaultTimeout`].
257
489
  def set_default_timeout(timeout)
258
490
  raise NotImplementedError.new('set_default_timeout is not implemented yet.')
@@ -263,7 +495,7 @@ module Playwright
263
495
  # with page-specific extra HTTP headers set with [`method: Page.setExtraHTTPHeaders`]. If page overrides a particular
264
496
  # header, page-specific header value will be used instead of the browser context header value.
265
497
  #
266
- # > **NOTE** `browserContext.setExtraHTTPHeaders` does not guarantee the order of headers in the outgoing requests.
498
+ # > NOTE: [`method: BrowserContext.setExtraHTTPHeaders`] does not guarantee the order of headers in the outgoing requests.
267
499
  def set_extra_http_headers(headers)
268
500
  raise NotImplementedError.new('set_extra_http_headers is not implemented yet.')
269
501
  end
@@ -276,8 +508,16 @@ module Playwright
276
508
  # await browserContext.setGeolocation({latitude: 59.95, longitude: 30.31667});
277
509
  # ```
278
510
  #
279
- # > **NOTE** Consider using [`method: BrowserContext.grantPermissions`] to grant permissions for the browser context pages
280
- # to read its geolocation.
511
+ # ```python async
512
+ # await browser_context.set_geolocation({"latitude": 59.95, "longitude": 30.31667})
513
+ # ```
514
+ #
515
+ # ```python sync
516
+ # browser_context.set_geolocation({"latitude": 59.95, "longitude": 30.31667})
517
+ # ```
518
+ #
519
+ # > NOTE: Consider using [`method: BrowserContext.grantPermissions`] to grant permissions for the browser context pages to
520
+ # read its geolocation.
281
521
  def set_geolocation(geolocation)
282
522
  raise NotImplementedError.new('set_geolocation is not implemented yet.')
283
523
  end
@@ -305,54 +545,46 @@ module Playwright
305
545
  raise NotImplementedError.new('unroute is not implemented yet.')
306
546
  end
307
547
 
308
- # Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
309
- # value. Will throw an error if the context closes before the event is fired. Returns the event data value.
310
- #
311
- #
312
- # ```js
313
- # const context = await browser.newContext();
314
- # await context.grantPermissions(['geolocation']);
315
- # ```
316
- def wait_for_event(event, optionsOrPredicate: nil)
317
- raise NotImplementedError.new('wait_for_event is not implemented yet.')
548
+ # @nodoc
549
+ def after_initialize
550
+ wrap_impl(@impl.after_initialize)
318
551
  end
319
552
 
320
553
  # @nodoc
321
554
  def browser=(req)
322
- wrap_channel_owner(@channel_owner.browser=(req))
555
+ wrap_impl(@impl.browser=(unwrap_impl(req)))
323
556
  end
324
557
 
325
558
  # @nodoc
326
559
  def owner_page=(req)
327
- wrap_channel_owner(@channel_owner.owner_page=(req))
328
- end
329
-
330
- # @nodoc
331
- def after_initialize
332
- wrap_channel_owner(@channel_owner.after_initialize)
560
+ wrap_impl(@impl.owner_page=(unwrap_impl(req)))
333
561
  end
334
562
 
335
563
  # @nodoc
336
564
  def options=(req)
337
- wrap_channel_owner(@channel_owner.options=(req))
565
+ wrap_impl(@impl.options=(unwrap_impl(req)))
338
566
  end
339
567
 
340
568
  # -- inherited from EventEmitter --
341
569
  # @nodoc
342
- def off(event, callback)
343
- wrap_channel_owner(@channel_owner.off(event, callback))
570
+ def once(event, callback)
571
+ event_emitter_proxy.once(event, callback)
344
572
  end
345
573
 
346
574
  # -- inherited from EventEmitter --
347
575
  # @nodoc
348
- def once(event, callback)
349
- wrap_channel_owner(@channel_owner.once(event, callback))
576
+ def on(event, callback)
577
+ event_emitter_proxy.on(event, callback)
350
578
  end
351
579
 
352
580
  # -- inherited from EventEmitter --
353
581
  # @nodoc
354
- def on(event, callback)
355
- wrap_channel_owner(@channel_owner.on(event, callback))
582
+ def off(event, callback)
583
+ event_emitter_proxy.off(event, callback)
584
+ end
585
+
586
+ private def event_emitter_proxy
587
+ @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
356
588
  end
357
589
  end
358
590
  end