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
@@ -8,6 +8,16 @@ module Playwright
8
8
  # // ...
9
9
  # ```
10
10
  #
11
+ # ```python async
12
+ # window_handle = await page.evaluate_handle("window")
13
+ # # ...
14
+ # ```
15
+ #
16
+ # ```python sync
17
+ # window_handle = page.evaluate_handle("window")
18
+ # # ...
19
+ # ```
20
+ #
11
21
  # JSHandle prevents the referenced JavaScript object being garbage collected unless the handle is exposed with
12
22
  # [`method: JSHandle.dispose`]. JSHandles are auto-disposed when their origin frame gets navigated or the parent context
13
23
  # gets destroyed.
@@ -23,7 +33,7 @@ module Playwright
23
33
 
24
34
  # The `jsHandle.dispose` method stops referencing the element handle.
25
35
  def dispose
26
- wrap_channel_owner(@channel_owner.dispose)
36
+ wrap_impl(@impl.dispose)
27
37
  end
28
38
 
29
39
  # Returns the return value of `pageFunction`
@@ -38,7 +48,17 @@ module Playwright
38
48
  #
39
49
  # ```js
40
50
  # const tweetHandle = await page.$('.tweet .retweets');
41
- # expect(await tweetHandle.evaluate((node, suffix) => node.innerText, ' retweets')).toBe('10 retweets');
51
+ # expect(await tweetHandle.evaluate(node => node.innerText)).toBe('10 retweets');
52
+ # ```
53
+ #
54
+ # ```python async
55
+ # tweet_handle = await page.query_selector(".tweet .retweets")
56
+ # assert await tweet_handle.evaluate("node => node.innerText") == "10 retweets"
57
+ # ```
58
+ #
59
+ # ```python sync
60
+ # tweet_handle = page.query_selector(".tweet .retweets")
61
+ # assert tweet_handle.evaluate("node => node.innerText") == "10 retweets"
42
62
  # ```
43
63
  def evaluate(pageFunction, arg: nil)
44
64
  raise NotImplementedError.new('evaluate is not implemented yet.')
@@ -69,6 +89,22 @@ module Playwright
69
89
  # const documentHandle = properties.get('document');
70
90
  # await handle.dispose();
71
91
  # ```
92
+ #
93
+ # ```python async
94
+ # handle = await page.evaluate_handle("{window, document}")
95
+ # properties = await handle.get_properties()
96
+ # window_handle = properties.get("window")
97
+ # document_handle = properties.get("document")
98
+ # await handle.dispose()
99
+ # ```
100
+ #
101
+ # ```python sync
102
+ # handle = page.evaluate_handle("{window, document}")
103
+ # properties = handle.get_properties()
104
+ # window_handle = properties.get("window")
105
+ # document_handle = properties.get("document")
106
+ # handle.dispose()
107
+ # ```
72
108
  def get_properties
73
109
  raise NotImplementedError.new('get_properties is not implemented yet.')
74
110
  end
@@ -80,7 +116,7 @@ module Playwright
80
116
 
81
117
  # Returns a JSON representation of the object. If the object has a `toJSON` function, it **will not be called**.
82
118
  #
83
- # > **NOTE** The method will return an empty JSON object if the referenced object is not stringifiable. It will throw an
119
+ # > NOTE: The method will return an empty JSON object if the referenced object is not stringifiable. It will throw an
84
120
  # error if the object has circular references.
85
121
  def json_value
86
122
  raise NotImplementedError.new('json_value is not implemented yet.')
@@ -88,20 +124,20 @@ module Playwright
88
124
 
89
125
  # -- inherited from EventEmitter --
90
126
  # @nodoc
91
- def off(event, callback)
92
- wrap_channel_owner(@channel_owner.off(event, callback))
127
+ def on(event, callback)
128
+ wrap_impl(@impl.on(event, callback))
93
129
  end
94
130
 
95
131
  # -- inherited from EventEmitter --
96
132
  # @nodoc
97
- def once(event, callback)
98
- wrap_channel_owner(@channel_owner.once(event, callback))
133
+ def off(event, callback)
134
+ wrap_impl(@impl.off(event, callback))
99
135
  end
100
136
 
101
137
  # -- inherited from EventEmitter --
102
138
  # @nodoc
103
- def on(event, callback)
104
- wrap_channel_owner(@channel_owner.on(event, callback))
139
+ def once(event, callback)
140
+ wrap_impl(@impl.once(event, callback))
105
141
  end
106
142
  end
107
143
  end
@@ -21,6 +21,28 @@ module Playwright
21
21
  # // Result text will end up saying 'Hello!'
22
22
  # ```
23
23
  #
24
+ # ```python async
25
+ # await page.keyboard.type("Hello World!")
26
+ # await page.keyboard.press("ArrowLeft")
27
+ # await page.keyboard.down("Shift")
28
+ # for i in range(6):
29
+ # await page.keyboard.press("ArrowLeft")
30
+ # await page.keyboard.up("Shift")
31
+ # await page.keyboard.press("Backspace")
32
+ # # result text will end up saying "Hello!"
33
+ # ```
34
+ #
35
+ # ```python sync
36
+ # page.keyboard.type("Hello World!")
37
+ # page.keyboard.press("ArrowLeft")
38
+ # page.keyboard.down("Shift")
39
+ # for i in range(6):
40
+ # page.keyboard.press("ArrowLeft")
41
+ # page.keyboard.up("Shift")
42
+ # page.keyboard.press("Backspace")
43
+ # # result text will end up saying "Hello!"
44
+ # ```
45
+ #
24
46
  # An example of pressing uppercase `A`
25
47
  #
26
48
  #
@@ -30,6 +52,18 @@ module Playwright
30
52
  # await page.keyboard.press('Shift+A');
31
53
  # ```
32
54
  #
55
+ # ```python async
56
+ # await page.keyboard.press("Shift+KeyA")
57
+ # # or
58
+ # await page.keyboard.press("Shift+A")
59
+ # ```
60
+ #
61
+ # ```python sync
62
+ # page.keyboard.press("Shift+KeyA")
63
+ # # or
64
+ # page.keyboard.press("Shift+A")
65
+ # ```
66
+ #
33
67
  # An example to trigger select-all with the keyboard
34
68
  #
35
69
  #
@@ -39,6 +73,20 @@ module Playwright
39
73
  # // on macOS
40
74
  # await page.keyboard.press('Meta+A');
41
75
  # ```
76
+ #
77
+ # ```python async
78
+ # # on windows and linux
79
+ # await page.keyboard.press("Control+A")
80
+ # # on mac_os
81
+ # await page.keyboard.press("Meta+A")
82
+ # ```
83
+ #
84
+ # ```python sync
85
+ # # on windows and linux
86
+ # page.keyboard.press("Control+A")
87
+ # # on mac_os
88
+ # page.keyboard.press("Meta+A")
89
+ # ```
42
90
  class Keyboard < PlaywrightApi
43
91
 
44
92
  # Dispatches a `keydown` event.
@@ -64,9 +112,9 @@ module Playwright
64
112
  # [repeat](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat) set to true. To release the key, use
65
113
  # [`method: Keyboard.up`].
66
114
  #
67
- # > **NOTE** Modifier keys DO influence `keyboard.down`. Holding down `Shift` will type the text in upper case.
115
+ # > NOTE: Modifier keys DO influence `keyboard.down`. Holding down `Shift` will type the text in upper case.
68
116
  def down(key)
69
- raise NotImplementedError.new('down is not implemented yet.')
117
+ @impl.down(key)
70
118
  end
71
119
 
72
120
  # Dispatches only `input` event, does not emit the `keydown`, `keyup` or `keypress` events.
@@ -76,9 +124,17 @@ module Playwright
76
124
  # page.keyboard.insertText('嗨');
77
125
  # ```
78
126
  #
79
- # > **NOTE** Modifier keys DO NOT effect `keyboard.insertText`. Holding down `Shift` will not type the text in upper case.
127
+ # ```python async
128
+ # await page.keyboard.insert_text("嗨")
129
+ # ```
130
+ #
131
+ # ```python sync
132
+ # page.keyboard.insert_text("嗨")
133
+ # ```
134
+ #
135
+ # > NOTE: Modifier keys DO NOT effect `keyboard.insertText`. Holding down `Shift` will not type the text in upper case.
80
136
  def insert_text(text)
81
- raise NotImplementedError.new('insert_text is not implemented yet.')
137
+ @impl.insert_text(text)
82
138
  end
83
139
 
84
140
  # `key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)
@@ -111,9 +167,33 @@ module Playwright
111
167
  # await browser.close();
112
168
  # ```
113
169
  #
170
+ # ```python async
171
+ # page = await browser.new_page()
172
+ # await page.goto("https://keycode.info")
173
+ # await page.keyboard.press("a")
174
+ # await page.screenshot(path="a.png")
175
+ # await page.keyboard.press("ArrowLeft")
176
+ # await page.screenshot(path="arrow_left.png")
177
+ # await page.keyboard.press("Shift+O")
178
+ # await page.screenshot(path="o.png")
179
+ # await browser.close()
180
+ # ```
181
+ #
182
+ # ```python sync
183
+ # page = browser.new_page()
184
+ # page.goto("https://keycode.info")
185
+ # page.keyboard.press("a")
186
+ # page.screenshot(path="a.png")
187
+ # page.keyboard.press("ArrowLeft")
188
+ # page.screenshot(path="arrow_left.png")
189
+ # page.keyboard.press("Shift+O")
190
+ # page.screenshot(path="o.png")
191
+ # browser.close()
192
+ # ```
193
+ #
114
194
  # Shortcut for [`method: Keyboard.down`] and [`method: Keyboard.up`].
115
195
  def press(key, delay: nil)
116
- raise NotImplementedError.new('press is not implemented yet.')
196
+ @impl.press(key, delay: delay)
117
197
  end
118
198
 
119
199
  # Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
@@ -126,14 +206,24 @@ module Playwright
126
206
  # await page.keyboard.type('World', {delay: 100}); // Types slower, like a user
127
207
  # ```
128
208
  #
129
- # > **NOTE** Modifier keys DO NOT effect `keyboard.type`. Holding down `Shift` will not type the text in upper case.
209
+ # ```python async
210
+ # await page.keyboard.type("Hello") # types instantly
211
+ # await page.keyboard.type("World", delay=100) # types slower, like a user
212
+ # ```
213
+ #
214
+ # ```python sync
215
+ # page.keyboard.type("Hello") # types instantly
216
+ # page.keyboard.type("World", delay=100) # types slower, like a user
217
+ # ```
218
+ #
219
+ # > NOTE: Modifier keys DO NOT effect `keyboard.type`. Holding down `Shift` will not type the text in upper case.
130
220
  def type_text(text, delay: nil)
131
- raise NotImplementedError.new('type_text is not implemented yet.')
221
+ @impl.type_text(text, delay: delay)
132
222
  end
133
223
 
134
224
  # Dispatches a `keyup` event.
135
225
  def up(key)
136
- raise NotImplementedError.new('up is not implemented yet.')
226
+ @impl.up(key)
137
227
  end
138
228
  end
139
229
  end
@@ -14,6 +14,28 @@ module Playwright
14
14
  # await page.mouse.move(0, 0);
15
15
  # await page.mouse.up();
16
16
  # ```
17
+ #
18
+ # ```python async
19
+ # # using ‘page.mouse’ to trace a 100x100 square.
20
+ # await page.mouse.move(0, 0)
21
+ # await page.mouse.down()
22
+ # await page.mouse.move(0, 100)
23
+ # await page.mouse.move(100, 100)
24
+ # await page.mouse.move(100, 0)
25
+ # await page.mouse.move(0, 0)
26
+ # await page.mouse.up()
27
+ # ```
28
+ #
29
+ # ```python sync
30
+ # # using ‘page.mouse’ to trace a 100x100 square.
31
+ # page.mouse.move(0, 0)
32
+ # page.mouse.down()
33
+ # page.mouse.move(0, 100)
34
+ # page.mouse.move(100, 100)
35
+ # page.mouse.move(100, 0)
36
+ # page.mouse.move(0, 0)
37
+ # page.mouse.up()
38
+ # ```
17
39
  class Mouse < PlaywrightApi
18
40
 
19
41
  # Shortcut for [`method: Mouse.move`], [`method: Mouse.down`], [`method: Mouse.up`].
@@ -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
  # Page provides methods to interact with a single tab in a `Browser`, or an
5
5
  # [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium. One [Browser]
@@ -21,6 +21,41 @@ module Playwright
21
21
  # })();
22
22
  # ```
23
23
  #
24
+ # ```python async
25
+ # import asyncio
26
+ # from playwright.async_api import async_playwright
27
+ #
28
+ # async def run(playwright):
29
+ # webkit = playwright.webkit
30
+ # browser = await webkit.launch()
31
+ # context = await browser.new_context()
32
+ # page = await context.new_page()
33
+ # await page.goto("https://example.com")
34
+ # await page.screenshot(path="screenshot.png")
35
+ # await browser.close()
36
+ #
37
+ # async def main():
38
+ # async with async_playwright() as playwright:
39
+ # await run(playwright)
40
+ # asyncio.run(main())
41
+ # ```
42
+ #
43
+ # ```python sync
44
+ # from playwright.sync_api import sync_playwright
45
+ #
46
+ # def run(playwright):
47
+ # webkit = playwright.webkit
48
+ # browser = webkit.launch()
49
+ # context = browser.new_context()
50
+ # page = context.new_page()
51
+ # page.goto("https://example.com")
52
+ # page.screenshot(path="screenshot.png")
53
+ # browser.close()
54
+ #
55
+ # with sync_playwright() as playwright:
56
+ # run(playwright)
57
+ # ```
58
+ #
24
59
  # The Page class emits various events (described below) which can be handled using any of Node's native
25
60
  # [`EventEmitter`](https://nodejs.org/api/events.html#events_class_eventemitter) methods, such as `on`, `once` or
26
61
  # `removeListener`.
@@ -32,6 +67,10 @@ module Playwright
32
67
  # page.once('load', () => console.log('Page loaded!'));
33
68
  # ```
34
69
  #
70
+ # ```py
71
+ # page.once("load", lambda: print("page loaded!"))
72
+ # ```
73
+ #
35
74
  # To unsubscribe from events use the `removeListener` method:
36
75
  #
37
76
  #
@@ -43,10 +82,18 @@ module Playwright
43
82
  # // Sometime later...
44
83
  # page.removeListener('request', logRequest);
45
84
  # ```
85
+ #
86
+ # ```py
87
+ # def log_request(intercepted_request):
88
+ # print("a request was made:", intercepted_request.url)
89
+ # page.on("request", log_request)
90
+ # # sometime later...
91
+ # page.remove_listener("request", log_request)
92
+ # ```
46
93
  class Page < PlaywrightApi
47
94
 
48
95
  def accessibility # property
49
- wrap_channel_owner(@channel_owner.accessibility)
96
+ wrap_impl(@impl.accessibility)
50
97
  end
51
98
 
52
99
  # Browser-specific Coverage implementation, only available for Chromium atm. See
@@ -56,15 +103,15 @@ module Playwright
56
103
  end
57
104
 
58
105
  def keyboard # property
59
- wrap_channel_owner(@channel_owner.keyboard)
106
+ wrap_impl(@impl.keyboard)
60
107
  end
61
108
 
62
109
  def mouse # property
63
- wrap_channel_owner(@channel_owner.mouse)
110
+ wrap_impl(@impl.mouse)
64
111
  end
65
112
 
66
113
  def touchscreen # property
67
- wrap_channel_owner(@channel_owner.touchscreen)
114
+ wrap_impl(@impl.touchscreen)
68
115
  end
69
116
 
70
117
  # The method finds an element matching the specified selector within the page. If no elements match the selector, the
@@ -72,7 +119,7 @@ module Playwright
72
119
  #
73
120
  # Shortcut for main frame's [`method: Frame.$`].
74
121
  def query_selector(selector)
75
- raise NotImplementedError.new('query_selector is not implemented yet.')
122
+ wrap_impl(@impl.query_selector(selector))
76
123
  end
77
124
 
78
125
  # The method finds all elements matching the specified selector within the page. If no elements match the selector, the
@@ -80,7 +127,7 @@ module Playwright
80
127
  #
81
128
  # Shortcut for main frame's [`method: Frame.$$`].
82
129
  def query_selector_all(selector)
83
- raise NotImplementedError.new('query_selector_all is not implemented yet.')
130
+ wrap_impl(@impl.query_selector_all(selector))
84
131
  end
85
132
 
86
133
  # The method finds an element matching the specified selector within the page and passes it as a first argument to
@@ -98,9 +145,21 @@ module Playwright
98
145
  # const html = await page.$eval('.main-container', (e, suffix) => e.outerHTML + suffix, 'hello');
99
146
  # ```
100
147
  #
148
+ # ```python async
149
+ # search_value = await page.eval_on_selector("#search", "el => el.value")
150
+ # preload_href = await page.eval_on_selector("link[rel=preload]", "el => el.href")
151
+ # html = await page.eval_on_selector(".main-container", "(e, suffix) => e.outer_html + suffix", "hello")
152
+ # ```
153
+ #
154
+ # ```python sync
155
+ # search_value = page.eval_on_selector("#search", "el => el.value")
156
+ # preload_href = page.eval_on_selector("link[rel=preload]", "el => el.href")
157
+ # html = page.eval_on_selector(".main-container", "(e, suffix) => e.outer_html + suffix", "hello")
158
+ # ```
159
+ #
101
160
  # Shortcut for main frame's [`method: Frame.$eval`].
102
161
  def eval_on_selector(selector, pageFunction, arg: nil)
103
- raise NotImplementedError.new('eval_on_selector is not implemented yet.')
162
+ wrap_impl(@impl.eval_on_selector(selector, pageFunction, arg: arg))
104
163
  end
105
164
 
106
165
  # The method finds all elements matching the specified selector within the page and passes an array of matched elements as
@@ -113,10 +172,18 @@ module Playwright
113
172
  #
114
173
  #
115
174
  # ```js
116
- # const divsCounts = await page.$$eval('div', (divs, min) => divs.length >= min, 10);
175
+ # const divCounts = await page.$$eval('div', (divs, min) => divs.length >= min, 10);
176
+ # ```
177
+ #
178
+ # ```python async
179
+ # div_counts = await page.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
180
+ # ```
181
+ #
182
+ # ```python sync
183
+ # div_counts = page.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
117
184
  # ```
118
185
  def eval_on_selector_all(selector, pageFunction, arg: nil)
119
- raise NotImplementedError.new('eval_on_selector_all is not implemented yet.')
186
+ wrap_impl(@impl.eval_on_selector_all(selector, pageFunction, arg: arg))
120
187
  end
121
188
 
122
189
  # Adds a script which would be evaluated in one of the following scenarios:
@@ -130,16 +197,28 @@ module Playwright
130
197
  # An example of overriding `Math.random` before the page loads:
131
198
  #
132
199
  #
133
- # ```js
200
+ # ```js browser
134
201
  # // preload.js
135
202
  # Math.random = () => 42;
203
+ # ```
136
204
  #
205
+ #
206
+ # ```js
137
207
  # // In your playwright script, assuming the preload.js file is in same directory
138
- # const preloadFile = fs.readFileSync('./preload.js', 'utf8');
139
- # await page.addInitScript(preloadFile);
208
+ # await page.addInitScript({ path: './preload.js' });
209
+ # ```
210
+ #
211
+ # ```python async
212
+ # # in your playwright script, assuming the preload.js file is in same directory
213
+ # await page.add_init_script(path="./preload.js")
140
214
  # ```
141
215
  #
142
- # > **NOTE** The order of evaluation of multiple scripts installed via [`method: BrowserContext.addInitScript`] and
216
+ # ```python sync
217
+ # # in your playwright script, assuming the preload.js file is in same directory
218
+ # page.add_init_script(path="./preload.js")
219
+ # ```
220
+ #
221
+ # > NOTE: The order of evaluation of multiple scripts installed via [`method: BrowserContext.addInitScript`] and
143
222
  # [`method: Page.addInitScript`] is not defined.
144
223
  def add_init_script(script, arg: nil)
145
224
  raise NotImplementedError.new('add_init_script is not implemented yet.')
@@ -207,7 +286,7 @@ module Playwright
207
286
  noWaitAfter: nil,
208
287
  position: nil,
209
288
  timeout: nil)
210
- raise NotImplementedError.new('click is not implemented yet.')
289
+ wrap_impl(@impl.click(selector, button: button, clickCount: clickCount, delay: delay, force: force, modifiers: modifiers, noWaitAfter: noWaitAfter, position: position, timeout: timeout))
211
290
  end
212
291
 
213
292
  # If `runBeforeUnload` is `false`, does not run any unload handlers and waits for the page to be closed. If
@@ -215,20 +294,20 @@ module Playwright
215
294
  #
216
295
  # By default, `page.close()` **does not** run `beforeunload` handlers.
217
296
  #
218
- # > **NOTE** if `runBeforeUnload` is passed as true, a `beforeunload` dialog might be summoned
219
- # > and should be handled manually via [`event: Page.dialog`] event.
297
+ # > NOTE: if `runBeforeUnload` is passed as true, a `beforeunload` dialog might be summoned and should be handled manually
298
+ # via [`event: Page.dialog`] event.
220
299
  def close(runBeforeUnload: nil)
221
- wrap_channel_owner(@channel_owner.close(runBeforeUnload: runBeforeUnload))
300
+ wrap_impl(@impl.close(runBeforeUnload: runBeforeUnload))
222
301
  end
223
302
 
224
303
  # Gets the full HTML contents of the page, including the doctype.
225
304
  def content
226
- wrap_channel_owner(@channel_owner.content)
305
+ wrap_impl(@impl.content)
227
306
  end
228
307
 
229
308
  # Get the browser context that the page belongs to.
230
309
  def context
231
- wrap_channel_owner(@channel_owner.context)
310
+ wrap_impl(@impl.context)
232
311
  end
233
312
 
234
313
  # This method double clicks an element matching `selector` by performing the following steps:
@@ -243,7 +322,7 @@ module Playwright
243
322
  # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
244
323
  # Passing zero timeout disables this.
245
324
  #
246
- # > **NOTE** `page.dblclick()` dispatches two `click` events and a single `dblclick` event.
325
+ # > NOTE: `page.dblclick()` dispatches two `click` events and a single `dblclick` event.
247
326
  #
248
327
  # Shortcut for main frame's [`method: Frame.dblclick`].
249
328
  def dblclick(
@@ -267,6 +346,14 @@ module Playwright
267
346
  # await page.dispatchEvent('button#submit', 'click');
268
347
  # ```
269
348
  #
349
+ # ```python async
350
+ # await page.dispatch_event("button#submit", "click")
351
+ # ```
352
+ #
353
+ # ```python sync
354
+ # page.dispatch_event("button#submit", "click")
355
+ # ```
356
+ #
270
357
  # Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties
271
358
  # and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
272
359
  #
@@ -287,6 +374,18 @@ module Playwright
287
374
  # const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
288
375
  # await page.dispatchEvent('#source', 'dragstart', { dataTransfer });
289
376
  # ```
377
+ #
378
+ # ```python async
379
+ # # note you can only create data_transfer in chromium and firefox
380
+ # data_transfer = await page.evaluate_handle("new DataTransfer()")
381
+ # await page.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
382
+ # ```
383
+ #
384
+ # ```python sync
385
+ # # note you can only create data_transfer in chromium and firefox
386
+ # data_transfer = page.evaluate_handle("new DataTransfer()")
387
+ # page.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
388
+ # ```
290
389
  def dispatch_event(selector, type, eventInit: nil, timeout: nil)
291
390
  raise NotImplementedError.new('dispatch_event is not implemented yet.')
292
391
  end
@@ -312,6 +411,44 @@ module Playwright
312
411
  # // → false
313
412
  # ```
314
413
  #
414
+ # ```python async
415
+ # await page.evaluate("matchMedia('screen').matches")
416
+ # # → True
417
+ # await page.evaluate("matchMedia('print').matches")
418
+ # # → False
419
+ #
420
+ # await page.emulate_media(media="print")
421
+ # await page.evaluate("matchMedia('screen').matches")
422
+ # # → False
423
+ # await page.evaluate("matchMedia('print').matches")
424
+ # # → True
425
+ #
426
+ # await page.emulate_media()
427
+ # await page.evaluate("matchMedia('screen').matches")
428
+ # # → True
429
+ # await page.evaluate("matchMedia('print').matches")
430
+ # # → False
431
+ # ```
432
+ #
433
+ # ```python sync
434
+ # page.evaluate("matchMedia('screen').matches")
435
+ # # → True
436
+ # page.evaluate("matchMedia('print').matches")
437
+ # # → False
438
+ #
439
+ # page.emulate_media(media="print")
440
+ # page.evaluate("matchMedia('screen').matches")
441
+ # # → False
442
+ # page.evaluate("matchMedia('print').matches")
443
+ # # → True
444
+ #
445
+ # page.emulate_media()
446
+ # page.evaluate("matchMedia('screen').matches")
447
+ # # → True
448
+ # page.evaluate("matchMedia('print').matches")
449
+ # # → False
450
+ # ```
451
+ #
315
452
  #
316
453
  # ```js
317
454
  # await page.emulateMedia({ colorScheme: 'dark' });
@@ -322,18 +459,37 @@ module Playwright
322
459
  # await page.evaluate(() => matchMedia('(prefers-color-scheme: no-preference)').matches);
323
460
  # // → false
324
461
  # ```
462
+ #
463
+ # ```python async
464
+ # await page.emulate_media(color_scheme="dark")
465
+ # await page.evaluate("matchMedia('(prefers-color-scheme: dark)').matches")
466
+ # # → True
467
+ # await page.evaluate("matchMedia('(prefers-color-scheme: light)').matches")
468
+ # # → False
469
+ # await page.evaluate("matchMedia('(prefers-color-scheme: no-preference)').matches")
470
+ # # → False
471
+ # ```
472
+ #
473
+ # ```python sync
474
+ # page.emulate_media(color_scheme="dark")
475
+ # page.evaluate("matchMedia('(prefers-color-scheme: dark)').matches")
476
+ # # → True
477
+ # page.evaluate("matchMedia('(prefers-color-scheme: light)').matches")
478
+ # # → False
479
+ # page.evaluate("matchMedia('(prefers-color-scheme: no-preference)').matches")
480
+ # ```
325
481
  def emulate_media(params)
326
482
  raise NotImplementedError.new('emulate_media is not implemented yet.')
327
483
  end
328
484
 
329
485
  # Returns the value of the `pageFunction` invocation.
330
486
  #
331
- # If the function passed to the `page.evaluate` returns a [Promise], then `page.evaluate` would wait for the promise to
332
- # resolve and return its value.
487
+ # If the function passed to the [`method: Page.evaluate`] returns a [Promise], then [`method: Page.evaluate`] would wait
488
+ # for the promise to resolve and return its value.
333
489
  #
334
- # If the function passed to the `page.evaluate` returns a non-[Serializable] value, then `page.evaluate` resolves to
335
- # `undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`:
336
- # `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
490
+ # If the function passed to the [`method: Page.evaluate`] returns a non-[Serializable] value,
491
+ # then[ method: `Page.evaluate`] resolves to `undefined`. DevTools Protocol also supports transferring some additional
492
+ # values that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
337
493
  #
338
494
  # Passing argument to `pageFunction`:
339
495
  #
@@ -345,6 +501,16 @@ module Playwright
345
501
  # console.log(result); // prints "56"
346
502
  # ```
347
503
  #
504
+ # ```python async
505
+ # result = await page.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
506
+ # print(result) # prints "56"
507
+ # ```
508
+ #
509
+ # ```python sync
510
+ # result = page.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
511
+ # print(result) # prints "56"
512
+ # ```
513
+ #
348
514
  # A string can also be passed in instead of a function:
349
515
  #
350
516
  #
@@ -354,7 +520,19 @@ module Playwright
354
520
  # console.log(await page.evaluate(`1 + ${x}`)); // prints "11"
355
521
  # ```
356
522
  #
357
- # `ElementHandle` instances can be passed as an argument to the `page.evaluate`:
523
+ # ```python async
524
+ # print(await page.evaluate("1 + 2")) # prints "3"
525
+ # x = 10
526
+ # print(await page.evaluate(f"1 + {x}")) # prints "11"
527
+ # ```
528
+ #
529
+ # ```python sync
530
+ # print(page.evaluate("1 + 2")) # prints "3"
531
+ # x = 10
532
+ # print(page.evaluate(f"1 + {x}")) # prints "11"
533
+ # ```
534
+ #
535
+ # `ElementHandle` instances can be passed as an argument to the [`method: Page.evaluate`]:
358
536
  #
359
537
  #
360
538
  # ```js
@@ -363,18 +541,47 @@ module Playwright
363
541
  # await bodyHandle.dispose();
364
542
  # ```
365
543
  #
544
+ # ```python async
545
+ # body_handle = await page.query_selector("body")
546
+ # html = await page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
547
+ # await body_handle.dispose()
548
+ # ```
549
+ #
550
+ # ```python sync
551
+ # body_handle = page.query_selector("body")
552
+ # html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
553
+ # body_handle.dispose()
554
+ # ```
555
+ #
366
556
  # Shortcut for main frame's [`method: Frame.evaluate`].
367
557
  def evaluate(pageFunction, arg: nil)
368
- wrap_channel_owner(@channel_owner.evaluate(pageFunction, arg: arg))
558
+ wrap_impl(@impl.evaluate(pageFunction, arg: arg))
369
559
  end
370
560
 
371
561
  # Returns the value of the `pageFunction` invocation as in-page object (JSHandle).
372
562
  #
373
- # The only difference between `page.evaluate` and `page.evaluateHandle` is that `page.evaluateHandle` returns in-page
374
- # object (JSHandle).
563
+ # The only difference between [`method: Page.evaluate`] and [`method: Page.evaluateHandle`] is that
564
+ # [`method: Page.evaluateHandle`] returns in-page object (JSHandle).
565
+ #
566
+ # If the function passed to the [`method: Page.evaluateHandle`] returns a [Promise], then [`method: Page.evaluateHandle`]
567
+ # would wait for the promise to resolve and return its value.
375
568
  #
376
- # If the function passed to the `page.evaluateHandle` returns a [Promise], then `page.evaluateHandle` would wait for the
377
- # promise to resolve and return its value.
569
+ #
570
+ # ```js
571
+ # const aWindowHandle = await page.evaluateHandle(() => Promise.resolve(window));
572
+ # aWindowHandle; // Handle for the window object.
573
+ # ```
574
+ #
575
+ # ```python async
576
+ # # FIXME
577
+ # a_window_handle = await page.evaluate_handle("Promise.resolve(window)")
578
+ # a_window_handle # handle for the window object.
579
+ # ```
580
+ #
581
+ # ```python sync
582
+ # a_window_handle = page.evaluate_handle("Promise.resolve(window)")
583
+ # a_window_handle # handle for the window object.
584
+ # ```
378
585
  #
379
586
  # A string can also be passed in instead of a function:
380
587
  #
@@ -383,7 +590,15 @@ module Playwright
383
590
  # const aHandle = await page.evaluateHandle('document'); // Handle for the 'document'
384
591
  # ```
385
592
  #
386
- # `JSHandle` instances can be passed as an argument to the `page.evaluateHandle`:
593
+ # ```python async
594
+ # a_handle = await page.evaluate_handle("document") # handle for the "document"
595
+ # ```
596
+ #
597
+ # ```python sync
598
+ # a_handle = page.evaluate_handle("document") # handle for the "document"
599
+ # ```
600
+ #
601
+ # `JSHandle` instances can be passed as an argument to the [`method: Page.evaluateHandle`]:
387
602
  #
388
603
  #
389
604
  # ```js
@@ -392,8 +607,22 @@ module Playwright
392
607
  # console.log(await resultHandle.jsonValue());
393
608
  # await resultHandle.dispose();
394
609
  # ```
610
+ #
611
+ # ```python async
612
+ # a_handle = await page.evaluate_handle("document.body")
613
+ # result_handle = await page.evaluate_handle("body => body.innerHTML", a_handle)
614
+ # print(await result_handle.json_value())
615
+ # await result_handle.dispose()
616
+ # ```
617
+ #
618
+ # ```python sync
619
+ # a_handle = page.evaluate_handle("document.body")
620
+ # result_handle = page.evaluate_handle("body => body.innerHTML", a_handle)
621
+ # print(result_handle.json_value())
622
+ # result_handle.dispose()
623
+ # ```
395
624
  def evaluate_handle(pageFunction, arg: nil)
396
- wrap_channel_owner(@channel_owner.evaluate_handle(pageFunction, arg: arg))
625
+ wrap_impl(@impl.evaluate_handle(pageFunction, arg: arg))
397
626
  end
398
627
 
399
628
  # The method adds a function called `name` on the `window` object of every frame in this page. When called, the function
@@ -405,7 +634,7 @@ module Playwright
405
634
  #
406
635
  # See [`method: BrowserContext.exposeBinding`] for the context-wide version.
407
636
  #
408
- # > **NOTE** Functions installed via `page.exposeBinding` survive navigations.
637
+ # > NOTE: Functions installed via [`method: Page.exposeBinding`] survive navigations.
409
638
  #
410
639
  # An example of exposing page URL to all frames in a page:
411
640
  #
@@ -431,6 +660,57 @@ module Playwright
431
660
  # })();
432
661
  # ```
433
662
  #
663
+ # ```python async
664
+ # import asyncio
665
+ # from playwright.async_api import async_playwright
666
+ #
667
+ # async def run(playwright):
668
+ # webkit = playwright.webkit
669
+ # browser = await webkit.launch(headless=false)
670
+ # context = await browser.new_context()
671
+ # page = await context.new_page()
672
+ # await page.expose_binding("pageURL", lambda source: source["page"].url)
673
+ # await page.set_content("""
674
+ # <script>
675
+ # async function onClick() {
676
+ # document.querySelector('div').textContent = await window.pageURL();
677
+ # }
678
+ # </script>
679
+ # <button onclick="onClick()">Click me</button>
680
+ # <div></div>
681
+ # """)
682
+ # await page.click("button")
683
+ #
684
+ # async def main():
685
+ # async with async_playwright() as playwright:
686
+ # await run(playwright)
687
+ # asyncio.run(main())
688
+ # ```
689
+ #
690
+ # ```python sync
691
+ # from playwright.sync_api import sync_playwright
692
+ #
693
+ # def run(playwright):
694
+ # webkit = playwright.webkit
695
+ # browser = webkit.launch(headless=false)
696
+ # context = browser.new_context()
697
+ # page = context.new_page()
698
+ # page.expose_binding("pageURL", lambda source: source["page"].url)
699
+ # page.set_content("""
700
+ # <script>
701
+ # async function onClick() {
702
+ # document.querySelector('div').textContent = await window.pageURL();
703
+ # }
704
+ # </script>
705
+ # <button onclick="onClick()">Click me</button>
706
+ # <div></div>
707
+ # """)
708
+ # page.click("button")
709
+ #
710
+ # with sync_playwright() as playwright:
711
+ # run(playwright)
712
+ # ```
713
+ #
434
714
  # An example of passing an element handle:
435
715
  #
436
716
  #
@@ -446,6 +726,34 @@ module Playwright
446
726
  # <div>Or click me</div>
447
727
  # `);
448
728
  # ```
729
+ #
730
+ # ```python async
731
+ # async def print(source, element):
732
+ # print(await element.text_content())
733
+ #
734
+ # await page.expose_binding("clicked", print, handle=true)
735
+ # await page.set_content("""
736
+ # <script>
737
+ # document.addEventListener('click', event => window.clicked(event.target));
738
+ # </script>
739
+ # <div>Click me</div>
740
+ # <div>Or click me</div>
741
+ # """)
742
+ # ```
743
+ #
744
+ # ```python sync
745
+ # def print(source, element):
746
+ # print(element.text_content())
747
+ #
748
+ # page.expose_binding("clicked", print, handle=true)
749
+ # page.set_content("""
750
+ # <script>
751
+ # document.addEventListener('click', event => window.clicked(event.target));
752
+ # </script>
753
+ # <div>Click me</div>
754
+ # <div>Or click me</div>
755
+ # """)
756
+ # ```
449
757
  def expose_binding(name, callback, handle: nil)
450
758
  raise NotImplementedError.new('expose_binding is not implemented yet.')
451
759
  end
@@ -457,9 +765,9 @@ module Playwright
457
765
  #
458
766
  # See [`method: BrowserContext.exposeFunction`] for context-wide exposed function.
459
767
  #
460
- # > **NOTE** Functions installed via `page.exposeFunction` survive navigations.
768
+ # > NOTE: Functions installed via [`method: Page.exposeFunction`] survive navigations.
461
769
  #
462
- # An example of adding an `md5` function to the page:
770
+ # An example of adding an `sha1` function to the page:
463
771
  #
464
772
  #
465
773
  # ```js
@@ -469,11 +777,11 @@ module Playwright
469
777
  # (async () => {
470
778
  # const browser = await webkit.launch({ headless: false });
471
779
  # const page = await browser.newPage();
472
- # await page.exposeFunction('md5', text => crypto.createHash('md5').update(text).digest('hex'));
780
+ # await page.exposeFunction('sha1', text => crypto.createHash('sha1').update(text).digest('hex'));
473
781
  # await page.setContent(`
474
782
  # <script>
475
783
  # async function onClick() {
476
- # document.querySelector('div').textContent = await window.md5('PLAYWRIGHT');
784
+ # document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');
477
785
  # }
478
786
  # </script>
479
787
  # <button onclick="onClick()">Click me</button>
@@ -483,34 +791,67 @@ module Playwright
483
791
  # })();
484
792
  # ```
485
793
  #
486
- # An example of adding a `window.readfile` function to the page:
487
- #
488
- #
489
- # ```js
490
- # const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
491
- # const fs = require('fs');
794
+ # ```python async
795
+ # import asyncio
796
+ # import hashlib
797
+ # from playwright.async_api import async_playwright
798
+ #
799
+ # async def sha1(text):
800
+ # m = hashlib.sha1()
801
+ # m.update(bytes(text, "utf8"))
802
+ # return m.hexdigest()
803
+ #
804
+ #
805
+ # async def run(playwright):
806
+ # webkit = playwright.webkit
807
+ # browser = await webkit.launch(headless=False)
808
+ # page = await browser.new_page()
809
+ # await page.expose_function("sha1", sha1)
810
+ # await page.set_content("""
811
+ # <script>
812
+ # async function onClick() {
813
+ # document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');
814
+ # }
815
+ # </script>
816
+ # <button onclick="onClick()">Click me</button>
817
+ # <div></div>
818
+ # """)
819
+ # await page.click("button")
820
+ #
821
+ # async def main():
822
+ # async with async_playwright() as playwright:
823
+ # await run(playwright)
824
+ # asyncio.run(main())
825
+ # ```
492
826
  #
493
- # (async () => {
494
- # const browser = await chromium.launch();
495
- # const page = await browser.newPage();
496
- # page.on('console', msg => console.log(msg.text()));
497
- # await page.exposeFunction('readfile', async filePath => {
498
- # return new Promise((resolve, reject) => {
499
- # fs.readFile(filePath, 'utf8', (err, text) => {
500
- # if (err)
501
- # reject(err);
502
- # else
503
- # resolve(text);
504
- # });
505
- # });
506
- # });
507
- # await page.evaluate(async () => {
508
- # // use window.readfile to read contents of a file
509
- # const content = await window.readfile('/etc/hosts');
510
- # console.log(content);
511
- # });
512
- # await browser.close();
513
- # })();
827
+ # ```python sync
828
+ # import hashlib
829
+ # from playwright.sync_api import sync_playwright
830
+ #
831
+ # def sha1(text):
832
+ # m = hashlib.sha1()
833
+ # m.update(bytes(text, "utf8"))
834
+ # return m.hexdigest()
835
+ #
836
+ #
837
+ # def run(playwright):
838
+ # webkit = playwright.webkit
839
+ # browser = webkit.launch(headless=False)
840
+ # page = browser.new_page()
841
+ # page.expose_function("sha1", sha1)
842
+ # page.set_content("""
843
+ # <script>
844
+ # async function onClick() {
845
+ # document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');
846
+ # }
847
+ # </script>
848
+ # <button onclick="onClick()">Click me</button>
849
+ # <div></div>
850
+ # """)
851
+ # page.click("button")
852
+ #
853
+ # with sync_playwright() as playwright:
854
+ # run(playwright)
514
855
  # ```
515
856
  def expose_function(name, callback)
516
857
  raise NotImplementedError.new('expose_function is not implemented yet.')
@@ -533,7 +874,7 @@ module Playwright
533
874
  #
534
875
  # Shortcut for main frame's [`method: Frame.focus`].
535
876
  def focus(selector, timeout: nil)
536
- wrap_channel_owner(@channel_owner.focus(selector, timeout: timeout))
877
+ wrap_impl(@impl.focus(selector, timeout: timeout))
537
878
  end
538
879
 
539
880
  # Returns frame matching the specified criteria. Either `name` or `url` must be specified.
@@ -543,17 +884,25 @@ module Playwright
543
884
  # const frame = page.frame('frame-name');
544
885
  # ```
545
886
  #
887
+ # ```py
888
+ # frame = page.frame(name="frame-name")
889
+ # ```
890
+ #
546
891
  #
547
892
  # ```js
548
893
  # const frame = page.frame({ url: /.*domain.*/ });
549
894
  # ```
895
+ #
896
+ # ```py
897
+ # frame = page.frame(url=r".*domain.*")
898
+ # ```
550
899
  def frame(frameSelector)
551
- wrap_channel_owner(@channel_owner.frame(frameSelector))
900
+ wrap_impl(@impl.frame(frameSelector))
552
901
  end
553
902
 
554
903
  # An array of all frames attached to the page.
555
904
  def frames
556
- wrap_channel_owner(@channel_owner.frames)
905
+ wrap_impl(@impl.frames)
557
906
  end
558
907
 
559
908
  # Returns element attribute value.
@@ -591,14 +940,14 @@ module Playwright
591
940
  # Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling
592
941
  # [`method: Response.status`].
593
942
  #
594
- # > **NOTE** `page.goto` either throws an error or returns a main resource response. The only exceptions are navigation to
943
+ # > NOTE: `page.goto` either throws an error or returns a main resource response. The only exceptions are navigation to
595
944
  # `about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.
596
- # > **NOTE** Headless mode doesn't support navigation to a PDF document. See the
945
+ # > NOTE: Headless mode doesn't support navigation to a PDF document. See the
597
946
  # [upstream issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
598
947
  #
599
948
  # Shortcut for main frame's [`method: Frame.goto`]
600
949
  def goto(url, referer: nil, timeout: nil, waitUntil: nil)
601
- wrap_channel_owner(@channel_owner.goto(url, referer: referer, timeout: timeout, waitUntil: waitUntil))
950
+ wrap_impl(@impl.goto(url, referer: referer, timeout: timeout, waitUntil: waitUntil))
602
951
  end
603
952
 
604
953
  # This method hovers over an element matching `selector` by performing the following steps:
@@ -639,7 +988,7 @@ module Playwright
639
988
 
640
989
  # Indicates that the page has been closed.
641
990
  def closed?
642
- wrap_channel_owner(@channel_owner.closed?)
991
+ wrap_impl(@impl.closed?)
643
992
  end
644
993
 
645
994
  # Returns whether the element is disabled, the opposite of [enabled](./actionability.md#enabled).
@@ -669,22 +1018,22 @@ module Playwright
669
1018
 
670
1019
  # The page's main frame. Page is guaranteed to have a main frame which persists during navigations.
671
1020
  def main_frame
672
- wrap_channel_owner(@channel_owner.main_frame)
1021
+ wrap_impl(@impl.main_frame)
673
1022
  end
674
1023
 
675
1024
  # Returns the opener for popup pages and `null` for others. If the opener has been closed already the returns `null`.
676
1025
  def opener
677
- wrap_channel_owner(@channel_owner.opener)
1026
+ wrap_impl(@impl.opener)
678
1027
  end
679
1028
 
680
1029
  # Returns the PDF buffer.
681
1030
  #
682
- # > **NOTE** Generating a pdf is currently only supported in Chromium headless.
1031
+ # > NOTE: Generating a pdf is currently only supported in Chromium headless.
683
1032
  #
684
1033
  # `page.pdf()` generates a pdf of the page with `print` css media. To generate a pdf with `screen` media, call
685
1034
  # [`method: Page.emulateMedia`] before calling `page.pdf()`:
686
1035
  #
687
- # > **NOTE** By default, `page.pdf()` generates a pdf with modified colors for printing. Use the
1036
+ # > NOTE: By default, `page.pdf()` generates a pdf with modified colors for printing. Use the
688
1037
  # [`-webkit-print-color-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-print-color-adjust) property to
689
1038
  # force rendering of exact colors.
690
1039
  #
@@ -695,6 +1044,18 @@ module Playwright
695
1044
  # await page.pdf({path: 'page.pdf'});
696
1045
  # ```
697
1046
  #
1047
+ # ```python async
1048
+ # # generates a pdf with "screen" media type.
1049
+ # await page.emulate_media(media="screen")
1050
+ # await page.pdf(path="page.pdf")
1051
+ # ```
1052
+ #
1053
+ # ```python sync
1054
+ # # generates a pdf with "screen" media type.
1055
+ # page.emulate_media(media="screen")
1056
+ # page.pdf(path="page.pdf")
1057
+ # ```
1058
+ #
698
1059
  # The `width`, `height`, and `margin` options accept values labeled with units. Unlabeled values are treated as pixels.
699
1060
  #
700
1061
  # A few examples:
@@ -721,9 +1082,8 @@ module Playwright
721
1082
  # - `A5`: 5.83in x 8.27in
722
1083
  # - `A6`: 4.13in x 5.83in
723
1084
  #
724
- # > **NOTE** `headerTemplate` and `footerTemplate` markup have the following limitations:
725
- # > 1. Script tags inside templates are not evaluated.
726
- # > 2. Page styles are not visible inside templates.
1085
+ # > NOTE: `headerTemplate` and `footerTemplate` markup have the following limitations: > 1. Script tags inside templates
1086
+ # are not evaluated. > 2. Page styles are not visible inside templates.
727
1087
  def pdf(
728
1088
  displayHeaderFooter: nil,
729
1089
  footerTemplate: nil,
@@ -772,13 +1132,37 @@ module Playwright
772
1132
  # await page.screenshot({ path: 'O.png' });
773
1133
  # await browser.close();
774
1134
  # ```
1135
+ #
1136
+ # ```python async
1137
+ # page = await browser.new_page()
1138
+ # await page.goto("https://keycode.info")
1139
+ # await page.press("body", "A")
1140
+ # await page.screenshot(path="a.png")
1141
+ # await page.press("body", "ArrowLeft")
1142
+ # await page.screenshot(path="arrow_left.png")
1143
+ # await page.press("body", "Shift+O")
1144
+ # await page.screenshot(path="o.png")
1145
+ # await browser.close()
1146
+ # ```
1147
+ #
1148
+ # ```python sync
1149
+ # page = browser.new_page()
1150
+ # page.goto("https://keycode.info")
1151
+ # page.press("body", "A")
1152
+ # page.screenshot(path="a.png")
1153
+ # page.press("body", "ArrowLeft")
1154
+ # page.screenshot(path="arrow_left.png")
1155
+ # page.press("body", "Shift+O")
1156
+ # page.screenshot(path="o.png")
1157
+ # browser.close()
1158
+ # ```
775
1159
  def press(
776
1160
  selector,
777
1161
  key,
778
1162
  delay: nil,
779
1163
  noWaitAfter: nil,
780
1164
  timeout: nil)
781
- wrap_channel_owner(@channel_owner.press(selector, key, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout))
1165
+ wrap_impl(@impl.press(selector, key, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout))
782
1166
  end
783
1167
 
784
1168
  # Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
@@ -791,7 +1175,7 @@ module Playwright
791
1175
  #
792
1176
  # Once routing is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted.
793
1177
  #
794
- # > **NOTE** The handler will only be called for the first url if the response is a redirect.
1178
+ # > NOTE: The handler will only be called for the first url if the response is a redirect.
795
1179
  #
796
1180
  # An example of a naïve handler that aborts all image requests:
797
1181
  #
@@ -803,6 +1187,20 @@ module Playwright
803
1187
  # await browser.close();
804
1188
  # ```
805
1189
  #
1190
+ # ```python async
1191
+ # page = await browser.new_page()
1192
+ # await page.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
1193
+ # await page.goto("https://example.com")
1194
+ # await browser.close()
1195
+ # ```
1196
+ #
1197
+ # ```python sync
1198
+ # page = browser.new_page()
1199
+ # page.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
1200
+ # page.goto("https://example.com")
1201
+ # browser.close()
1202
+ # ```
1203
+ #
806
1204
  # or the same snippet using a regex pattern instead:
807
1205
  #
808
1206
  #
@@ -813,17 +1211,31 @@ module Playwright
813
1211
  # await browser.close();
814
1212
  # ```
815
1213
  #
1214
+ # ```python async
1215
+ # page = await browser.new_page()
1216
+ # await page.route(re.compile(r"(\.png$)|(\.jpg$)"), lambda route: route.abort())
1217
+ # await page.goto("https://example.com")
1218
+ # await browser.close()
1219
+ # ```
1220
+ #
1221
+ # ```python sync
1222
+ # page = browser.new_page()
1223
+ # page.route(re.compile(r"(\.png$)|(\.jpg$)"), lambda route: route.abort())
1224
+ # page.goto("https://example.com")
1225
+ # browser.close()
1226
+ # ```
1227
+ #
816
1228
  # Page routes take precedence over browser context routes (set up with [`method: BrowserContext.route`]) when request
817
1229
  # matches both handlers.
818
1230
  #
819
- # > **NOTE** Enabling routing disables http cache.
1231
+ # > NOTE: Enabling routing disables http cache.
820
1232
  def route(url, handler)
821
1233
  raise NotImplementedError.new('route is not implemented yet.')
822
1234
  end
823
1235
 
824
1236
  # Returns the buffer with the captured screenshot.
825
1237
  #
826
- # > **NOTE** Screenshots take at least 1/6 second on Chromium OS X and Chromium Windows. See https://crbug.com/741689 for
1238
+ # > NOTE: Screenshots take at least 1/6 second on Chromium OS X and Chromium Windows. See https://crbug.com/741689 for
827
1239
  # discussion.
828
1240
  def screenshot(
829
1241
  clip: nil,
@@ -833,7 +1245,7 @@ module Playwright
833
1245
  quality: nil,
834
1246
  timeout: nil,
835
1247
  type: nil)
836
- wrap_channel_owner(@channel_owner.screenshot(clip: clip, fullPage: fullPage, omitBackground: omitBackground, path: path, quality: quality, timeout: timeout, type: type))
1248
+ wrap_impl(@impl.screenshot(clip: clip, fullPage: fullPage, omitBackground: omitBackground, path: path, quality: quality, timeout: timeout, type: type))
837
1249
  end
838
1250
 
839
1251
  # Returns the array of option values that have been successfully selected.
@@ -841,12 +1253,14 @@ module Playwright
841
1253
  # Triggers a `change` and `input` event once all the provided options have been selected. If there's no `<select>` element
842
1254
  # matching `selector`, the method throws an error.
843
1255
  #
1256
+ # Will wait until all specified options are present in the `<select>` element.
1257
+ #
844
1258
  #
845
1259
  # ```js
846
1260
  # // single selection matching the value
847
1261
  # page.selectOption('select#colors', 'blue');
848
1262
  #
849
- # // single selection matching both the value and the label
1263
+ # // single selection matching the label
850
1264
  # page.selectOption('select#colors', { label: 'Blue' });
851
1265
  #
852
1266
  # // multiple selection
@@ -854,13 +1268,31 @@ module Playwright
854
1268
  #
855
1269
  # ```
856
1270
  #
1271
+ # ```python async
1272
+ # # single selection matching the value
1273
+ # await page.select_option("select#colors", "blue")
1274
+ # # single selection matching the label
1275
+ # await page.select_option("select#colors", label="blue")
1276
+ # # multiple selection
1277
+ # await page.select_option("select#colors", value=["red", "green", "blue"])
1278
+ # ```
1279
+ #
1280
+ # ```python sync
1281
+ # # single selection matching the value
1282
+ # page.select_option("select#colors", "blue")
1283
+ # # single selection matching both the label
1284
+ # page.select_option("select#colors", label="blue")
1285
+ # # multiple selection
1286
+ # page.select_option("select#colors", value=["red", "green", "blue"])
1287
+ # ```
1288
+ #
857
1289
  # Shortcut for main frame's [`method: Frame.selectOption`]
858
1290
  def select_option(selector, values, noWaitAfter: nil, timeout: nil)
859
1291
  raise NotImplementedError.new('select_option is not implemented yet.')
860
1292
  end
861
1293
 
862
1294
  def set_content(html, timeout: nil, waitUntil: nil)
863
- wrap_channel_owner(@channel_owner.set_content(html, timeout: timeout, waitUntil: waitUntil))
1295
+ wrap_impl(@impl.set_content(html, timeout: timeout, waitUntil: waitUntil))
864
1296
  end
865
1297
  alias_method :content=, :set_content
866
1298
 
@@ -872,7 +1304,7 @@ module Playwright
872
1304
  # - [`method: Page.setContent`]
873
1305
  # - [`method: Page.waitForNavigation`]
874
1306
  #
875
- # > **NOTE** [`method: Page.setDefaultNavigationTimeout`] takes priority over [`method: Page.setDefaultTimeout`],
1307
+ # > NOTE: [`method: Page.setDefaultNavigationTimeout`] takes priority over [`method: Page.setDefaultTimeout`],
876
1308
  # [`method: BrowserContext.setDefaultTimeout`] and [`method: BrowserContext.setDefaultNavigationTimeout`].
877
1309
  def set_default_navigation_timeout(timeout)
878
1310
  raise NotImplementedError.new('set_default_navigation_timeout is not implemented yet.')
@@ -881,7 +1313,7 @@ module Playwright
881
1313
 
882
1314
  # This setting will change the default maximum time for all the methods accepting `timeout` option.
883
1315
  #
884
- # > **NOTE** [`method: Page.setDefaultNavigationTimeout`] takes priority over [`method: Page.setDefaultTimeout`].
1316
+ # > NOTE: [`method: Page.setDefaultNavigationTimeout`] takes priority over [`method: Page.setDefaultTimeout`].
885
1317
  def set_default_timeout(timeout)
886
1318
  raise NotImplementedError.new('set_default_timeout is not implemented yet.')
887
1319
  end
@@ -889,7 +1321,7 @@ module Playwright
889
1321
 
890
1322
  # The extra HTTP headers will be sent with every request the page initiates.
891
1323
  #
892
- # > **NOTE** page.setExtraHTTPHeaders does not guarantee the order of headers in the outgoing requests.
1324
+ # > NOTE: [`method: Page.setExtraHTTPHeaders`] does not guarantee the order of headers in the outgoing requests.
893
1325
  def set_extra_http_headers(headers)
894
1326
  raise NotImplementedError.new('set_extra_http_headers is not implemented yet.')
895
1327
  end
@@ -919,8 +1351,20 @@ module Playwright
919
1351
  # });
920
1352
  # await page.goto('https://example.com');
921
1353
  # ```
1354
+ #
1355
+ # ```python async
1356
+ # page = await browser.new_page()
1357
+ # await page.set_viewport_size({"width": 640, "height": 480})
1358
+ # await page.goto("https://example.com")
1359
+ # ```
1360
+ #
1361
+ # ```python sync
1362
+ # page = browser.new_page()
1363
+ # page.set_viewport_size({"width": 640, "height": 480})
1364
+ # page.goto("https://example.com")
1365
+ # ```
922
1366
  def set_viewport_size(viewportSize)
923
- wrap_channel_owner(@channel_owner.set_viewport_size(viewportSize))
1367
+ wrap_impl(@impl.set_viewport_size(viewportSize))
924
1368
  end
925
1369
  alias_method :viewport_size=, :set_viewport_size
926
1370
 
@@ -935,7 +1379,7 @@ module Playwright
935
1379
  # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
936
1380
  # Passing zero timeout disables this.
937
1381
  #
938
- # > **NOTE** `page.tap()` requires that the `hasTouch` option of the browser context be set to true.
1382
+ # > NOTE: [`method: Page.tap`] requires that the `hasTouch` option of the browser context be set to true.
939
1383
  #
940
1384
  # Shortcut for main frame's [`method: Frame.tap`].
941
1385
  def tap_point(
@@ -955,7 +1399,7 @@ module Playwright
955
1399
 
956
1400
  # Returns the page's title. Shortcut for main frame's [`method: Frame.title`].
957
1401
  def title
958
- wrap_channel_owner(@channel_owner.title)
1402
+ wrap_impl(@impl.title)
959
1403
  end
960
1404
 
961
1405
  # Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. `page.type` can be used to send
@@ -969,6 +1413,16 @@ module Playwright
969
1413
  # await page.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
970
1414
  # ```
971
1415
  #
1416
+ # ```python async
1417
+ # await page.type("#mytextarea", "hello") # types instantly
1418
+ # await page.type("#mytextarea", "world", delay=100) # types slower, like a user
1419
+ # ```
1420
+ #
1421
+ # ```python sync
1422
+ # page.type("#mytextarea", "hello") # types instantly
1423
+ # page.type("#mytextarea", "world", delay=100) # types slower, like a user
1424
+ # ```
1425
+ #
972
1426
  # Shortcut for main frame's [`method: Frame.type`].
973
1427
  def type_text(
974
1428
  selector,
@@ -976,7 +1430,7 @@ module Playwright
976
1430
  delay: nil,
977
1431
  noWaitAfter: nil,
978
1432
  timeout: nil)
979
- wrap_channel_owner(@channel_owner.type_text(selector, text, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout))
1433
+ wrap_impl(@impl.type_text(selector, text, delay: delay, noWaitAfter: noWaitAfter, timeout: timeout))
980
1434
  end
981
1435
 
982
1436
  # This method unchecks an element matching `selector` by performing the following steps:
@@ -1005,7 +1459,7 @@ module Playwright
1005
1459
 
1006
1460
  # Shortcut for main frame's [`method: Frame.url`].
1007
1461
  def url
1008
- wrap_channel_owner(@channel_owner.url)
1462
+ wrap_impl(@impl.url)
1009
1463
  end
1010
1464
 
1011
1465
  # Video object associated with this page.
@@ -1014,15 +1468,33 @@ module Playwright
1014
1468
  end
1015
1469
 
1016
1470
  def viewport_size
1017
- wrap_channel_owner(@channel_owner.viewport_size)
1471
+ wrap_impl(@impl.viewport_size)
1018
1472
  end
1019
1473
 
1020
- # Returns the event data value.
1021
- #
1022
1474
  # Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
1023
- # value. Will throw an error if the page is closed before the event is fired.
1024
- def wait_for_event(event, optionsOrPredicate: nil, &block)
1025
- wrap_channel_owner(@channel_owner.wait_for_event(event, optionsOrPredicate: optionsOrPredicate, &wrap_block_call(block)))
1475
+ # value. Will throw an error if the page is closed before the event is fired. Returns the event data value.
1476
+ #
1477
+ #
1478
+ # ```js
1479
+ # const [frame, _] = await Promise.all([
1480
+ # page.waitForEvent('framenavigated'),
1481
+ # page.click('button')
1482
+ # ]);
1483
+ # ```
1484
+ #
1485
+ # ```python async
1486
+ # async with page.expect_event("framenavigated") as event_info:
1487
+ # await page.click("button")
1488
+ # frame = await event_info.value
1489
+ # ```
1490
+ #
1491
+ # ```python sync
1492
+ # with page.expect_event("framenavigated") as event_info:
1493
+ # page.click("button")
1494
+ # frame = event_info.value
1495
+ # ```
1496
+ def expect_event(event, optionsOrPredicate: nil)
1497
+ raise NotImplementedError.new('expect_event is not implemented yet.')
1026
1498
  end
1027
1499
 
1028
1500
  # Returns when the `pageFunction` returns a truthy value. It resolves to a JSHandle of the truthy value.
@@ -1036,14 +1508,47 @@ module Playwright
1036
1508
  # (async () => {
1037
1509
  # const browser = await webkit.launch();
1038
1510
  # const page = await browser.newPage();
1039
- # const watchDog = page.waitForFunction('window.innerWidth < 100');
1511
+ # const watchDog = page.waitForFunction(() => window.innerWidth < 100);
1040
1512
  # await page.setViewportSize({width: 50, height: 50});
1041
1513
  # await watchDog;
1042
1514
  # await browser.close();
1043
1515
  # })();
1044
1516
  # ```
1045
1517
  #
1046
- # To pass an argument to the predicate of `page.waitForFunction` function:
1518
+ # ```python async
1519
+ # import asyncio
1520
+ # from playwright.async_api import async_playwright
1521
+ #
1522
+ # async def run(playwright):
1523
+ # webkit = playwright.webkit
1524
+ # browser = await webkit.launch()
1525
+ # page = await browser.new_page()
1526
+ # await page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);", force_expr=True)
1527
+ # await page.wait_for_function("() => window.x > 0")
1528
+ # await browser.close()
1529
+ #
1530
+ # async def main():
1531
+ # async with async_playwright() as playwright:
1532
+ # await run(playwright)
1533
+ # asyncio.run(main())
1534
+ # ```
1535
+ #
1536
+ # ```python sync
1537
+ # from playwright.sync_api import sync_playwright
1538
+ #
1539
+ # def run(playwright):
1540
+ # webkit = playwright.webkit
1541
+ # browser = webkit.launch()
1542
+ # page = browser.new_page()
1543
+ # page.evaluate("window.x = 0; setTimeout(() => { window.x = 100 }, 1000);", force_expr=True)
1544
+ # page.wait_for_function("() => window.x > 0")
1545
+ # browser.close()
1546
+ #
1547
+ # with sync_playwright() as playwright:
1548
+ # run(playwright)
1549
+ # ```
1550
+ #
1551
+ # To pass an argument to the predicate of [`method: Page.waitForFunction`] function:
1047
1552
  #
1048
1553
  #
1049
1554
  # ```js
@@ -1051,6 +1556,16 @@ module Playwright
1051
1556
  # await page.waitForFunction(selector => !!document.querySelector(selector), selector);
1052
1557
  # ```
1053
1558
  #
1559
+ # ```python async
1560
+ # selector = ".foo"
1561
+ # await page.wait_for_function("selector => !!document.querySelector(selector)", selector)
1562
+ # ```
1563
+ #
1564
+ # ```python sync
1565
+ # selector = ".foo"
1566
+ # page.wait_for_function("selector => !!document.querySelector(selector)", selector)
1567
+ # ```
1568
+ #
1054
1569
  # Shortcut for main frame's [`method: Frame.waitForFunction`].
1055
1570
  def wait_for_function(pageFunction, arg: nil, polling: nil, timeout: nil)
1056
1571
  raise NotImplementedError.new('wait_for_function is not implemented yet.')
@@ -1067,6 +1582,16 @@ module Playwright
1067
1582
  # await page.waitForLoadState(); // The promise resolves after 'load' event.
1068
1583
  # ```
1069
1584
  #
1585
+ # ```python async
1586
+ # await page.click("button") # click triggers navigation.
1587
+ # await page.wait_for_load_state() # the promise resolves after "load" event.
1588
+ # ```
1589
+ #
1590
+ # ```python sync
1591
+ # page.click("button") # click triggers navigation.
1592
+ # page.wait_for_load_state() # the promise resolves after "load" event.
1593
+ # ```
1594
+ #
1070
1595
  #
1071
1596
  # ```js
1072
1597
  # const [popup] = await Promise.all([
@@ -1077,14 +1602,32 @@ module Playwright
1077
1602
  # console.log(await popup.title()); // Popup is ready to use.
1078
1603
  # ```
1079
1604
  #
1605
+ # ```python async
1606
+ # async with page.expect_popup() as page_info:
1607
+ # await page.click("button") # click triggers a popup.
1608
+ # popup = await page_info.value
1609
+ # # Following resolves after "domcontentloaded" event.
1610
+ # await popup.wait_for_load_state("domcontentloaded")
1611
+ # print(await popup.title()) # popup is ready to use.
1612
+ # ```
1613
+ #
1614
+ # ```python sync
1615
+ # with page.expect_popup() as page_info:
1616
+ # page.click("button") # click triggers a popup.
1617
+ # popup = page_info.value
1618
+ # # Following resolves after "domcontentloaded" event.
1619
+ # popup.wait_for_load_state("domcontentloaded")
1620
+ # print(popup.title()) # popup is ready to use.
1621
+ # ```
1622
+ #
1080
1623
  # Shortcut for main frame's [`method: Frame.waitForLoadState`].
1081
1624
  def wait_for_load_state(state: nil, timeout: nil)
1082
1625
  raise NotImplementedError.new('wait_for_load_state is not implemented yet.')
1083
1626
  end
1084
1627
 
1085
- # Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the
1086
- # last redirect. In case of navigation to a different anchor or navigation due to History API usage, the navigation will
1087
- # resolve with `null`.
1628
+ # Waits for the main frame navigation and returns the main resource response. In case of multiple redirects, the
1629
+ # navigation will resolve with the response of the last redirect. In case of navigation to a different anchor or
1630
+ # navigation due to History API usage, the navigation will resolve with `null`.
1088
1631
  #
1089
1632
  # This resolves when the page navigates to a new URL or reloads. It is useful for when you run code which will indirectly
1090
1633
  # cause the page to navigate. e.g. The click target has an `onclick` handler that triggers navigation from a `setTimeout`.
@@ -1098,12 +1641,24 @@ module Playwright
1098
1641
  # ]);
1099
1642
  # ```
1100
1643
  #
1101
- # **NOTE** Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is
1644
+ # ```python async
1645
+ # async with page.expect_navigation():
1646
+ # await page.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
1647
+ # # Resolves after navigation has finished
1648
+ # ```
1649
+ #
1650
+ # ```python sync
1651
+ # with page.expect_navigation():
1652
+ # page.click("a.delayed-navigation") # clicking the link will indirectly cause a navigation
1653
+ # # Resolves after navigation has finished
1654
+ # ```
1655
+ #
1656
+ # > NOTE: Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is
1102
1657
  # considered a navigation.
1103
1658
  #
1104
1659
  # Shortcut for main frame's [`method: Frame.waitForNavigation`].
1105
- def wait_for_navigation(timeout: nil, url: nil, waitUntil: nil)
1106
- raise NotImplementedError.new('wait_for_navigation is not implemented yet.')
1660
+ def expect_navigation(timeout: nil, url: nil, waitUntil: nil)
1661
+ raise NotImplementedError.new('expect_navigation is not implemented yet.')
1107
1662
  end
1108
1663
 
1109
1664
  # Waits for the matching request and returns it.
@@ -1115,12 +1670,32 @@ module Playwright
1115
1670
  # return firstRequest.url();
1116
1671
  # ```
1117
1672
  #
1673
+ # ```python async
1674
+ # async with page.expect_request("http://example.com/resource") as first:
1675
+ # await page.click('button')
1676
+ # first_request = await first.value
1677
+ #
1678
+ # async with page.expect_request(lambda request: request.url == "http://example.com" and request.method == "get") as second:
1679
+ # await page.click('img')
1680
+ # second_request = await second.value
1681
+ # ```
1682
+ #
1683
+ # ```python sync
1684
+ # with page.expect_request("http://example.com/resource") as first:
1685
+ # page.click('button')
1686
+ # first_request = first.value
1687
+ #
1688
+ # with page.expect_request(lambda request: request.url == "http://example.com" and request.method == "get") as second:
1689
+ # page.click('img')
1690
+ # second_request = second.value
1691
+ # ```
1692
+ #
1118
1693
  #
1119
1694
  # ```js
1120
1695
  # await page.waitForRequest(request => request.url().searchParams.get('foo') === 'bar' && request.url().searchParams.get('foo2') === 'bar2');
1121
1696
  # ```
1122
- def wait_for_request(urlOrPredicate, timeout: nil)
1123
- wrap_channel_owner(@channel_owner.wait_for_request(urlOrPredicate, timeout: timeout))
1697
+ def expect_request(urlOrPredicate, timeout: nil)
1698
+ raise NotImplementedError.new('expect_request is not implemented yet.')
1124
1699
  end
1125
1700
 
1126
1701
  # Returns the matched response.
@@ -1131,8 +1706,20 @@ module Playwright
1131
1706
  # const finalResponse = await page.waitForResponse(response => response.url() === 'https://example.com' && response.status() === 200);
1132
1707
  # return finalResponse.ok();
1133
1708
  # ```
1134
- def wait_for_response(urlOrPredicate, timeout: nil)
1135
- wrap_channel_owner(@channel_owner.wait_for_response(urlOrPredicate, timeout: timeout))
1709
+ #
1710
+ # ```python async
1711
+ # first_response = await page.wait_for_response("https://example.com/resource")
1712
+ # final_response = await page.wait_for_response(lambda response: response.url == "https://example.com" and response.status === 200)
1713
+ # return final_response.ok
1714
+ # ```
1715
+ #
1716
+ # ```python sync
1717
+ # first_response = page.wait_for_response("https://example.com/resource")
1718
+ # final_response = page.wait_for_response(lambda response: response.url == "https://example.com" and response.status === 200)
1719
+ # return final_response.ok
1720
+ # ```
1721
+ def expect_response(urlOrPredicate, timeout: nil)
1722
+ raise NotImplementedError.new('expect_response is not implemented yet.')
1136
1723
  end
1137
1724
 
1138
1725
  # Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
@@ -1151,16 +1738,51 @@ module Playwright
1151
1738
  # (async () => {
1152
1739
  # const browser = await chromium.launch();
1153
1740
  # const page = await browser.newPage();
1154
- # let currentURL;
1155
- # page
1156
- # .waitForSelector('img')
1157
- # .then(() => console.log('First URL with image: ' + currentURL));
1158
- # for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com']) {
1741
+ # for (let currentURL of ['https://google.com', 'https://bbc.com']) {
1159
1742
  # await page.goto(currentURL);
1743
+ # const element = await page.waitForSelector('img');
1744
+ # console.log('Loaded image: ' + await element.getAttribute('src'));
1160
1745
  # }
1161
1746
  # await browser.close();
1162
1747
  # })();
1163
1748
  # ```
1749
+ #
1750
+ # ```python async
1751
+ # import asyncio
1752
+ # from playwright.async_api import async_playwright
1753
+ #
1754
+ # async def run(playwright):
1755
+ # chromium = playwright.chromium
1756
+ # browser = await chromium.launch()
1757
+ # page = await browser.new_page()
1758
+ # for current_url in ["https://google.com", "https://bbc.com"]:
1759
+ # await page.goto(current_url, wait_until="domcontentloaded")
1760
+ # element = await page.wait_for_selector("img")
1761
+ # print("Loaded image: " + str(await element.get_attribute("src")))
1762
+ # await browser.close()
1763
+ #
1764
+ # async def main():
1765
+ # async with async_playwright() as playwright:
1766
+ # await run(playwright)
1767
+ # asyncio.run(main())
1768
+ # ```
1769
+ #
1770
+ # ```python sync
1771
+ # from playwright.sync_api import sync_playwright
1772
+ #
1773
+ # def run(playwright):
1774
+ # chromium = playwright.chromium
1775
+ # browser = chromium.launch()
1776
+ # page = browser.new_page()
1777
+ # for current_url in ["https://google.com", "https://bbc.com"]:
1778
+ # page.goto(current_url, wait_until="domcontentloaded")
1779
+ # element = page.wait_for_selector("img")
1780
+ # print("Loaded image: " + str(element.get_attribute("src")))
1781
+ # browser.close()
1782
+ #
1783
+ # with sync_playwright() as playwright:
1784
+ # run(playwright)
1785
+ # ```
1164
1786
  def wait_for_selector(selector, state: nil, timeout: nil)
1165
1787
  raise NotImplementedError.new('wait_for_selector is not implemented yet.')
1166
1788
  end
@@ -1176,6 +1798,16 @@ module Playwright
1176
1798
  # await page.waitForTimeout(1000);
1177
1799
  # ```
1178
1800
  #
1801
+ # ```python async
1802
+ # # wait for 1 second
1803
+ # await page.wait_for_timeout(1000)
1804
+ # ```
1805
+ #
1806
+ # ```python sync
1807
+ # # wait for 1 second
1808
+ # page.wait_for_timeout(1000)
1809
+ # ```
1810
+ #
1179
1811
  # Shortcut for main frame's [`method: Frame.waitForTimeout`].
1180
1812
  def wait_for_timeout(timeout)
1181
1813
  raise NotImplementedError.new('wait_for_timeout is not implemented yet.')
@@ -1184,37 +1816,57 @@ module Playwright
1184
1816
  # This method returns all of the dedicated [WebWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)
1185
1817
  # associated with the page.
1186
1818
  #
1187
- # > **NOTE** This does not contain ServiceWorkers
1819
+ # > NOTE: This does not contain ServiceWorkers
1188
1820
  def workers
1189
1821
  raise NotImplementedError.new('workers is not implemented yet.')
1190
1822
  end
1191
1823
 
1192
1824
  # @nodoc
1193
1825
  def owned_context=(req)
1194
- wrap_channel_owner(@channel_owner.owned_context=(req))
1826
+ wrap_impl(@impl.owned_context=(req))
1827
+ end
1828
+
1829
+ # @nodoc
1830
+ def wait_for_navigation(timeout: nil, url: nil, waitUntil: nil, &block)
1831
+ wrap_impl(@impl.wait_for_navigation(timeout: timeout, url: url, waitUntil: waitUntil, &wrap_block_call(block)))
1832
+ end
1833
+
1834
+ # @nodoc
1835
+ def wait_for_request(urlOrPredicate, timeout: nil)
1836
+ wrap_impl(@impl.wait_for_request(urlOrPredicate, timeout: timeout))
1837
+ end
1838
+
1839
+ # @nodoc
1840
+ def wait_for_event(event, optionsOrPredicate: nil, &block)
1841
+ wrap_impl(@impl.wait_for_event(event, optionsOrPredicate: optionsOrPredicate, &wrap_block_call(block)))
1842
+ end
1843
+
1844
+ # @nodoc
1845
+ def wait_for_response(urlOrPredicate, timeout: nil)
1846
+ wrap_impl(@impl.wait_for_response(urlOrPredicate, timeout: timeout))
1195
1847
  end
1196
1848
 
1197
1849
  # @nodoc
1198
1850
  def after_initialize
1199
- wrap_channel_owner(@channel_owner.after_initialize)
1851
+ wrap_impl(@impl.after_initialize)
1200
1852
  end
1201
1853
 
1202
1854
  # -- inherited from EventEmitter --
1203
1855
  # @nodoc
1204
- def off(event, callback)
1205
- wrap_channel_owner(@channel_owner.off(event, callback))
1856
+ def on(event, callback)
1857
+ wrap_impl(@impl.on(event, callback))
1206
1858
  end
1207
1859
 
1208
1860
  # -- inherited from EventEmitter --
1209
1861
  # @nodoc
1210
- def once(event, callback)
1211
- wrap_channel_owner(@channel_owner.once(event, callback))
1862
+ def off(event, callback)
1863
+ wrap_impl(@impl.off(event, callback))
1212
1864
  end
1213
1865
 
1214
1866
  # -- inherited from EventEmitter --
1215
1867
  # @nodoc
1216
- def on(event, callback)
1217
- wrap_channel_owner(@channel_owner.on(event, callback))
1868
+ def once(event, callback)
1869
+ wrap_impl(@impl.once(event, callback))
1218
1870
  end
1219
1871
  end
1220
1872
  end