playwright-ruby-client 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -15
  3. data/lib/playwright/channel_owners/browser.rb +2 -2
  4. data/lib/playwright/channel_owners/console_message.rb +25 -0
  5. data/lib/playwright/channel_owners/element_handle.rb +8 -0
  6. data/lib/playwright/channel_owners/js_handle.rb +4 -0
  7. data/lib/playwright/channel_owners/page.rb +14 -1
  8. data/lib/playwright/version.rb +1 -1
  9. data/lib/playwright_api/accessibility.rb +20 -6
  10. data/lib/playwright_api/browser.rb +52 -39
  11. data/lib/playwright_api/browser_context.rb +94 -44
  12. data/lib/playwright_api/browser_type.rb +72 -53
  13. data/lib/playwright_api/cdp_session.rb +10 -7
  14. data/lib/playwright_api/chromium_browser_context.rb +3 -0
  15. data/lib/playwright_api/console_message.rb +12 -5
  16. data/lib/playwright_api/dialog.rb +3 -1
  17. data/lib/playwright_api/download.rb +13 -4
  18. data/lib/playwright_api/element_handle.rb +226 -113
  19. data/lib/playwright_api/file_chooser.rb +4 -2
  20. data/lib/playwright_api/frame.rb +276 -128
  21. data/lib/playwright_api/js_handle.rb +30 -10
  22. data/lib/playwright_api/keyboard.rb +56 -18
  23. data/lib/playwright_api/mouse.rb +6 -3
  24. data/lib/playwright_api/page.rb +452 -237
  25. data/lib/playwright_api/playwright.rb +80 -16
  26. data/lib/playwright_api/request.rb +35 -15
  27. data/lib/playwright_api/response.rb +4 -3
  28. data/lib/playwright_api/route.rb +15 -4
  29. data/lib/playwright_api/selectors.rb +3 -7
  30. data/lib/playwright_api/touchscreen.rb +2 -1
  31. data/lib/playwright_api/video.rb +3 -1
  32. data/lib/playwright_api/web_socket.rb +4 -2
  33. data/lib/playwright_api/worker.rb +17 -5
  34. metadata +5 -2
@@ -1,5 +1,7 @@
1
1
  module Playwright
2
- # BrowserType provides methods to launch a specific browser instance or connect to an existing one. The following is a typical example of using Playwright to drive automation:
2
+ # BrowserType provides methods to launch a specific browser instance or connect to an existing one. The following is a
3
+ # typical example of using Playwright to drive automation:
4
+ #
3
5
  #
4
6
  # ```js
5
7
  # const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
@@ -25,7 +27,9 @@ module Playwright
25
27
  end
26
28
 
27
29
  # Returns the browser instance.
30
+ #
28
31
  # You can use `ignoreDefaultArgs` to filter out `--mute-audio` from default arguments:
32
+ #
29
33
  #
30
34
  # ```js
31
35
  # const browser = await chromium.launch({ // Or 'firefox' or 'webkit'.
@@ -33,76 +37,91 @@ module Playwright
33
37
  # });
34
38
  # ```
35
39
  #
36
- # **Chromium-only** Playwright can also be used to control the Chrome browser, but it works best with the version of Chromium it is bundled with. There is no guarantee it will work with any other version. Use `executablePath` option with extreme caution.
37
- # If Google Chrome (rather than Chromium) is preferred, a Chrome Canary or Dev Channel build is suggested.
38
- # In `browserType.launch([options])` above, any mention of Chromium also applies to Chrome.
39
- # See `this article` for a description of the differences between Chromium and Chrome. `This article` describes some differences for Linux users.
40
+ # > **Chromium-only** Playwright can also be used to control the Chrome browser, but it works best with the version of
41
+ # Chromium it is bundled with. There is no guarantee it will work with any other version. Use `executablePath` option with
42
+ # extreme caution.
43
+ # >
44
+ # > If Google Chrome (rather than Chromium) is preferred, a
45
+ # [Chrome Canary](https://www.google.com/chrome/browser/canary.html) or
46
+ # [Dev Channel](https://www.chromium.org/getting-involved/dev-channel) build is suggested.
47
+ # >
48
+ # > In [`method: BrowserType.launch`] above, any mention of Chromium also applies to Chrome.
49
+ # >
50
+ # > See [`this article`](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for
51
+ # a description of the differences between Chromium and Chrome.
52
+ # [`This article`](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md)
53
+ # describes some differences for Linux users.
40
54
  def launch(
41
- headless: nil,
42
- executablePath: nil,
43
55
  args: nil,
44
- ignoreDefaultArgs: nil,
45
- proxy: nil,
46
- downloadsPath: nil,
47
56
  chromiumSandbox: nil,
57
+ devtools: nil,
58
+ downloadsPath: nil,
59
+ env: nil,
60
+ executablePath: nil,
48
61
  firefoxUserPrefs: nil,
62
+ handleSIGHUP: nil,
49
63
  handleSIGINT: nil,
50
64
  handleSIGTERM: nil,
51
- handleSIGHUP: nil,
65
+ headless: nil,
66
+ ignoreDefaultArgs: nil,
52
67
  logger: nil,
53
- timeout: nil,
54
- env: nil,
55
- devtools: nil,
68
+ proxy: nil,
56
69
  slowMo: nil,
70
+ timeout: nil,
57
71
  &block)
58
- wrap_channel_owner(@channel_owner.launch(headless: headless, executablePath: executablePath, args: args, ignoreDefaultArgs: ignoreDefaultArgs, proxy: proxy, downloadsPath: downloadsPath, chromiumSandbox: chromiumSandbox, firefoxUserPrefs: firefoxUserPrefs, handleSIGINT: handleSIGINT, handleSIGTERM: handleSIGTERM, handleSIGHUP: handleSIGHUP, logger: logger, timeout: timeout, env: env, devtools: devtools, slowMo: slowMo, &wrap_block_call(block)))
72
+ wrap_channel_owner(@channel_owner.launch(args: args, chromiumSandbox: chromiumSandbox, devtools: devtools, downloadsPath: downloadsPath, env: env, executablePath: executablePath, firefoxUserPrefs: firefoxUserPrefs, handleSIGHUP: handleSIGHUP, handleSIGINT: handleSIGINT, handleSIGTERM: handleSIGTERM, headless: headless, ignoreDefaultArgs: ignoreDefaultArgs, logger: logger, proxy: proxy, slowMo: slowMo, timeout: timeout, &wrap_block_call(block)))
59
73
  end
60
74
 
61
75
  # Returns the persistent browser context instance.
62
- # Launches browser that uses persistent storage located at `userDataDir` and returns the only context. Closing this context will automatically close the browser.
76
+ #
77
+ # Launches browser that uses persistent storage located at `userDataDir` and returns the only context. Closing this
78
+ # context will automatically close the browser.
63
79
  def launch_persistent_context(
64
80
  userDataDir,
65
- headless: nil,
66
- executablePath: nil,
81
+ acceptDownloads: nil,
67
82
  args: nil,
68
- ignoreDefaultArgs: nil,
69
- proxy: nil,
70
- downloadsPath: nil,
83
+ bypassCSP: nil,
71
84
  chromiumSandbox: nil,
85
+ colorScheme: nil,
86
+ deviceScaleFactor: nil,
87
+ devtools: nil,
88
+ downloadsPath: nil,
89
+ env: nil,
90
+ executablePath: nil,
91
+ extraHTTPHeaders: nil,
92
+ geolocation: nil,
93
+ handleSIGHUP: nil,
72
94
  handleSIGINT: nil,
73
95
  handleSIGTERM: nil,
74
- handleSIGHUP: nil,
75
- timeout: nil,
76
- env: nil,
77
- devtools: nil,
78
- slowMo: nil,
79
- acceptDownloads: nil,
96
+ hasTouch: nil,
97
+ headless: nil,
98
+ httpCredentials: nil,
99
+ ignoreDefaultArgs: nil,
80
100
  ignoreHTTPSErrors: nil,
81
- bypassCSP: nil,
82
- viewport: nil,
83
- userAgent: nil,
84
- deviceScaleFactor: nil,
85
101
  isMobile: nil,
86
- hasTouch: nil,
87
102
  javaScriptEnabled: nil,
88
- timezoneId: nil,
89
- geolocation: nil,
90
103
  locale: nil,
91
- permissions: nil,
92
- extraHTTPHeaders: nil,
93
- offline: nil,
94
- httpCredentials: nil,
95
- colorScheme: nil,
96
104
  logger: nil,
97
- videosPath: nil,
98
- videoSize: nil,
105
+ offline: nil,
106
+ permissions: nil,
107
+ proxy: nil,
99
108
  recordHar: nil,
100
- recordVideo: nil)
109
+ recordVideo: nil,
110
+ slowMo: nil,
111
+ timeout: nil,
112
+ timezoneId: nil,
113
+ userAgent: nil,
114
+ videoSize: nil,
115
+ videosPath: nil,
116
+ viewport: nil)
101
117
  raise NotImplementedError.new('launch_persistent_context is not implemented yet.')
102
118
  end
103
119
 
104
120
  # Returns the browser app instance.
105
- # Launches browser server that client can connect to. An example of launching a browser executable and connecting to it later:
121
+ #
122
+ # Launches browser server that client can connect to. An example of launching a browser executable and connecting to it
123
+ # later:
124
+ #
106
125
  #
107
126
  # ```js
108
127
  # const { chromium } = require('playwright'); // Or 'webkit' or 'firefox'.
@@ -117,22 +136,22 @@ module Playwright
117
136
  # })();
118
137
  # ```
119
138
  def launch_server(
120
- headless: nil,
121
- port: nil,
122
- executablePath: nil,
123
139
  args: nil,
124
- ignoreDefaultArgs: nil,
125
- proxy: nil,
126
- downloadsPath: nil,
127
140
  chromiumSandbox: nil,
141
+ devtools: nil,
142
+ downloadsPath: nil,
143
+ env: nil,
144
+ executablePath: nil,
128
145
  firefoxUserPrefs: nil,
146
+ handleSIGHUP: nil,
129
147
  handleSIGINT: nil,
130
148
  handleSIGTERM: nil,
131
- handleSIGHUP: nil,
149
+ headless: nil,
150
+ ignoreDefaultArgs: nil,
132
151
  logger: nil,
133
- timeout: nil,
134
- env: nil,
135
- devtools: nil)
152
+ port: nil,
153
+ proxy: nil,
154
+ timeout: nil)
136
155
  raise NotImplementedError.new('launch_server is not implemented yet.')
137
156
  end
138
157
 
@@ -1,13 +1,15 @@
1
1
  module Playwright
2
- # The `CDPSession` instances are used to talk raw Chrome Devtools Protocol:
2
+ # - extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
3
3
  #
4
- # protocol methods can be called with `session.send` method.
5
- # protocol events can be subscribed to with `session.on` method.
4
+ # The `CDPSession` instances are used to talk raw Chrome Devtools Protocol:
5
+ # - protocol methods can be called with `session.send` method.
6
+ # - protocol events can be subscribed to with `session.on` method.
6
7
  #
7
8
  # Useful links:
8
- #
9
- # Documentation on DevTools Protocol can be found here: DevTools Protocol Viewer.
10
- # Getting Started with DevTools Protocol: https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md
9
+ # - Documentation on DevTools Protocol can be found here:
10
+ # [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/).
11
+ # - Getting Started with DevTools Protocol:
12
+ # https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md
11
13
  #
12
14
  #
13
15
  # ```js
@@ -22,7 +24,8 @@ module Playwright
22
24
  # ```
23
25
  class CDPSession < PlaywrightApi
24
26
 
25
- # Detaches the CDPSession from the target. Once detached, the CDPSession object won't emit any events and can't be used to send messages.
27
+ # Detaches the CDPSession from the target. Once detached, the CDPSession object won't emit any events and can't be used to
28
+ # send messages.
26
29
  def detach
27
30
  raise NotImplementedError.new('detach is not implemented yet.')
28
31
  end
@@ -1,7 +1,10 @@
1
1
  require_relative './browser_context.rb'
2
2
 
3
3
  module Playwright
4
+ # - extends: `BrowserContext`
5
+ #
4
6
  # Chromium-specific features including background pages, service worker support, etc.
7
+ #
5
8
  #
6
9
  # ```js
7
10
  # const backgroundPage = await context.waitForEvent('backgroundpage');
@@ -1,22 +1,29 @@
1
1
  module Playwright
2
- # ConsoleMessage objects are dispatched by page via the page.on('console') event.
2
+ # `ConsoleMessage` objects are dispatched by page via the [`event: Page.console`] event.
3
3
  class ConsoleMessage < PlaywrightApi
4
4
 
5
5
  def args
6
- raise NotImplementedError.new('args is not implemented yet.')
6
+ wrap_channel_owner(@channel_owner.args)
7
7
  end
8
8
 
9
9
  def location
10
- raise NotImplementedError.new('location is not implemented yet.')
10
+ wrap_channel_owner(@channel_owner.location)
11
11
  end
12
12
 
13
13
  def text
14
- raise NotImplementedError.new('text is not implemented yet.')
14
+ wrap_channel_owner(@channel_owner.text)
15
15
  end
16
16
 
17
- # One of the following values: `'log'`, `'debug'`, `'info'`, `'error'`, `'warning'`, `'dir'`, `'dirxml'`, `'table'`, `'trace'`, `'clear'`, `'startGroup'`, `'startGroupCollapsed'`, `'endGroup'`, `'assert'`, `'profile'`, `'profileEnd'`, `'count'`, `'timeEnd'`.
17
+ # One of the following values: `'log'`, `'debug'`, `'info'`, `'error'`, `'warning'`, `'dir'`, `'dirxml'`, `'table'`,
18
+ # `'trace'`, `'clear'`, `'startGroup'`, `'startGroupCollapsed'`, `'endGroup'`, `'assert'`, `'profile'`, `'profileEnd'`,
19
+ # `'count'`, `'timeEnd'`.
18
20
  def type_text
19
21
  raise NotImplementedError.new('type_text is not implemented yet.')
20
22
  end
23
+
24
+ # @nodoc
25
+ def type
26
+ wrap_channel_owner(@channel_owner.type)
27
+ end
21
28
  end
22
29
  end
@@ -1,6 +1,8 @@
1
1
  module Playwright
2
- # Dialog objects are dispatched by page via the page.on('dialog') event.
2
+ # `Dialog` objects are dispatched by page via the [`event: Page.dialog`] event.
3
+ #
3
4
  # An example of using `Dialog` class:
5
+ #
4
6
  #
5
7
  # ```js
6
8
  # const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
@@ -1,7 +1,11 @@
1
1
  module Playwright
2
- # Download objects are dispatched by page via the page.on('download') event.
3
- # All the downloaded files belonging to the browser context are deleted when the browser context is closed. All downloaded files are deleted when the browser closes.
2
+ # `Download` objects are dispatched by page via the [`event: Page.download`] event.
3
+ #
4
+ # All the downloaded files belonging to the browser context are deleted when the browser context is closed. All downloaded
5
+ # files are deleted when the browser closes.
6
+ #
4
7
  # Download event is emitted once the download starts. Download path becomes available once download completes:
8
+ #
5
9
  #
6
10
  # ```js
7
11
  # const [ download ] = await Promise.all([
@@ -13,7 +17,9 @@ module Playwright
13
17
  # ...
14
18
  # ```
15
19
  #
16
- # **NOTE** Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the downloaded content. If `acceptDownloads` is not set or set to `false`, download events are emitted, but the actual download is not performed and user has no access to the downloaded files.
20
+ # > **NOTE** Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
21
+ # downloaded content. If `acceptDownloads` is not set or set to `false`, download events are emitted, but the actual
22
+ # download is not performed and user has no access to the downloaded files.
17
23
  class Download < PlaywrightApi
18
24
 
19
25
  # Returns readable stream for current download or `null` if download failed.
@@ -41,7 +47,10 @@ module Playwright
41
47
  raise NotImplementedError.new('save_as is not implemented yet.')
42
48
  end
43
49
 
44
- # Returns suggested filename for this download. It is typically computed by the browser from the `Content-Disposition` response header or the `download` attribute. See the spec on whatwg. Different browsers can use different logic for computing it.
50
+ # Returns suggested filename for this download. It is typically computed by the browser from the
51
+ # [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) response header
52
+ # or the `download` attribute. See the spec on [whatwg](https://html.spec.whatwg.org/#downloading-resources). Different
53
+ # browsers can use different logic for computing it.
45
54
  def suggested_filename
46
55
  raise NotImplementedError.new('suggested_filename is not implemented yet.')
47
56
  end
@@ -1,7 +1,10 @@
1
1
  require_relative './js_handle.rb'
2
2
 
3
3
  module Playwright
4
- # ElementHandle represents an in-page DOM element. ElementHandles can be created with the `page.$(selector)` method.
4
+ # - extends: `JSHandle`
5
+ #
6
+ # ElementHandle represents an in-page DOM element. ElementHandles can be created with the [`method: Page.$`] method.
7
+ #
5
8
  #
6
9
  # ```js
7
10
  # const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
@@ -15,57 +18,86 @@ module Playwright
15
18
  # // ...
16
19
  # })();
17
20
  # ```
18
- # ElementHandle prevents DOM element from garbage collection unless the handle is disposed with `jsHandle.dispose()`. ElementHandles are auto-disposed when their origin frame gets navigated.
19
- # ElementHandle instances can be used as an argument in `page.$eval(selector, pageFunction[, arg])` and `page.evaluate(pageFunction[, arg])` methods.
21
+ #
22
+ # ElementHandle prevents DOM element from garbage collection unless the handle is disposed with
23
+ # [`method: JSHandle.dispose`]. ElementHandles are auto-disposed when their origin frame gets navigated.
24
+ #
25
+ # ElementHandle instances can be used as an argument in [`method: Page.$eval`] and [`method: Page.evaluate`] methods.
20
26
  class ElementHandle < JSHandle
21
27
 
22
- # The method finds an element matching the specified selector in the `ElementHandle`'s subtree. See Working with selectors for more details. If no elements match the selector, returns `null`.
23
- def S(selector)
24
- raise NotImplementedError.new('S is not implemented yet.')
28
+ # The method finds an element matching the specified selector in the `ElementHandle`'s subtree. See
29
+ # [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
30
+ # returns `null`.
31
+ def query_selector(selector)
32
+ raise NotImplementedError.new('query_selector is not implemented yet.')
25
33
  end
26
34
 
27
- # The method finds all elements matching the specified selector in the `ElementHandle`s subtree. See Working with selectors for more details. If no elements match the selector, returns empty array.
28
- def SS(selector)
29
- raise NotImplementedError.new('SS is not implemented yet.')
35
+ # The method finds all elements matching the specified selector in the `ElementHandle`s subtree. See
36
+ # [Working with selectors](./selectors.md#working-with-selectors) for more details. If no elements match the selector,
37
+ # returns empty array.
38
+ def query_selector_all(selector)
39
+ raise NotImplementedError.new('query_selector_all is not implemented yet.')
30
40
  end
31
41
 
32
42
  # Returns the return value of `pageFunction`
33
- # The method finds an element matching the specified selector in the `ElementHandle`s subtree and passes it as a first argument to `pageFunction`. See Working with selectors for more details. If no elements match the selector, the method throws an error.
34
- # If `pageFunction` returns a Promise, then `frame.$eval` would wait for the promise to resolve and return its value.
43
+ #
44
+ # The method finds an element matching the specified selector in the `ElementHandle`s subtree and passes it as a first
45
+ # argument to `pageFunction`. See [Working with selectors](./selectors.md#working-with-selectors) for more details. If no
46
+ # elements match the selector, the method throws an error.
47
+ #
48
+ # If `pageFunction` returns a [Promise], then `frame.$eval` would wait for the promise to resolve and return its value.
49
+ #
35
50
  # Examples:
51
+ #
36
52
  #
37
53
  # ```js
38
54
  # const tweetHandle = await page.$('.tweet');
39
55
  # expect(await tweetHandle.$eval('.like', node => node.innerText)).toBe('100');
40
56
  # expect(await tweetHandle.$eval('.retweets', node => node.innerText)).toBe('10');
41
57
  # ```
42
- def Seval(selector, pageFunction, arg: nil)
43
- raise NotImplementedError.new('Seval is not implemented yet.')
58
+ def eval_on_selector(selector, pageFunction, arg: nil)
59
+ raise NotImplementedError.new('eval_on_selector is not implemented yet.')
44
60
  end
45
61
 
46
62
  # Returns the return value of `pageFunction`
47
- # The method finds all elements matching the specified selector in the `ElementHandle`'s subtree and passes an array of matched elements as a first argument to `pageFunction`. See Working with selectors for more details.
48
- # If `pageFunction` returns a Promise, then `frame.$$eval` would wait for the promise to resolve and return its value.
63
+ #
64
+ # The method finds all elements matching the specified selector in the `ElementHandle`'s subtree and passes an array of
65
+ # matched elements as a first argument to `pageFunction`. See
66
+ # [Working with selectors](./selectors.md#working-with-selectors) for more details.
67
+ #
68
+ # If `pageFunction` returns a [Promise], then `frame.$$eval` would wait for the promise to resolve and return its value.
69
+ #
49
70
  # Examples:
71
+ #
50
72
  # ```html
51
73
  # <div class="feed">
52
74
  # <div class="tweet">Hello!</div>
53
75
  # <div class="tweet">Hi!</div>
54
76
  # </div>
55
77
  # ```
78
+ #
56
79
  #
57
80
  # ```js
58
81
  # const feedHandle = await page.$('.feed');
59
82
  # expect(await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText))).toEqual(['Hello!', 'Hi!']);
60
83
  # ```
61
- def SSeval(selector, pageFunction, arg: nil)
62
- raise NotImplementedError.new('SSeval is not implemented yet.')
84
+ def eval_on_selector_all(selector, pageFunction, arg: nil)
85
+ raise NotImplementedError.new('eval_on_selector_all is not implemented yet.')
63
86
  end
64
87
 
65
- # This method returns the bounding box of the element, or `null` if the element is not visible. The bounding box is calculated relative to the main frame viewport - which is usually the same as the browser window.
66
- # Scrolling affects the returned bonding box, similarly to Element.getBoundingClientRect. That means `x` and/or `y` may be negative.
67
- # Elements from child frames return the bounding box relative to the main frame, unlike the Element.getBoundingClientRect.
68
- # Assuming the page is static, it is safe to use bounding box coordinates to perform input. For example, the following snippet should click the center of the element.
88
+ # This method returns the bounding box of the element, or `null` if the element is not visible. The bounding box is
89
+ # calculated relative to the main frame viewport - which is usually the same as the browser window.
90
+ #
91
+ # Scrolling affects the returned bonding box, similarly to
92
+ # [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect). That
93
+ # means `x` and/or `y` may be negative.
94
+ #
95
+ # Elements from child frames return the bounding box relative to the main frame, unlike the
96
+ # [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect).
97
+ #
98
+ # Assuming the page is static, it is safe to use bounding box coordinates to perform input. For example, the following
99
+ # snippet should click the center of the element.
100
+ #
69
101
  #
70
102
  # ```js
71
103
  # const box = await elementHandle.boundingBox();
@@ -76,37 +108,40 @@ module Playwright
76
108
  end
77
109
 
78
110
  # This method checks the element by performing the following steps:
79
- #
80
- # Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already checked, this method returns immediately.
81
- # Wait for actionability checks on the element, unless `force` option is set.
82
- # Scroll the element into view if needed.
83
- # Use page.mouse to click in the center of the element.
84
- # Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
85
- # Ensure that the element is now checked. If not, this method rejects.
111
+ # 1. Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already
112
+ # checked, this method returns immediately.
113
+ # 1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
114
+ # 1. Scroll the element into view if needed.
115
+ # 1. Use [`property: Page.mouse`] to click in the center of the element.
116
+ # 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
117
+ # 1. Ensure that the element is now checked. If not, this method rejects.
86
118
  #
87
119
  # If the element is detached from the DOM at any moment during the action, this method rejects.
88
- # When all steps combined have not finished during the specified `timeout`, this method rejects with a TimeoutError. Passing zero timeout disables this.
120
+ #
121
+ # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
122
+ # Passing zero timeout disables this.
89
123
  def check(force: nil, noWaitAfter: nil, timeout: nil)
90
124
  raise NotImplementedError.new('check is not implemented yet.')
91
125
  end
92
126
 
93
127
  # This method clicks the element by performing the following steps:
94
- #
95
- # Wait for actionability checks on the element, unless `force` option is set.
96
- # Scroll the element into view if needed.
97
- # Use page.mouse to click in the center of the element, or the specified `position`.
98
- # Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
128
+ # 1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
129
+ # 1. Scroll the element into view if needed.
130
+ # 1. Use [`property: Page.mouse`] to click in the center of the element, or the specified `position`.
131
+ # 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
99
132
  #
100
133
  # If the element is detached from the DOM at any moment during the action, this method rejects.
101
- # When all steps combined have not finished during the specified `timeout`, this method rejects with a TimeoutError. Passing zero timeout disables this.
134
+ #
135
+ # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
136
+ # Passing zero timeout disables this.
102
137
  def click(
103
138
  button: nil,
104
139
  clickCount: nil,
105
140
  delay: nil,
106
- position: nil,
107
- modifiers: nil,
108
141
  force: nil,
142
+ modifiers: nil,
109
143
  noWaitAfter: nil,
144
+ position: nil,
110
145
  timeout: nil)
111
146
  raise NotImplementedError.new('click is not implemented yet.')
112
147
  end
@@ -117,44 +152,52 @@ module Playwright
117
152
  end
118
153
 
119
154
  # This method double clicks the element by performing the following steps:
120
- #
121
- # Wait for actionability checks on the element, unless `force` option is set.
122
- # Scroll the element into view if needed.
123
- # Use page.mouse to double click in the center of the element, or the specified `position`.
124
- # Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will reject.
155
+ # 1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
156
+ # 1. Scroll the element into view if needed.
157
+ # 1. Use [`property: Page.mouse`] to double click in the center of the element, or the specified `position`.
158
+ # 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. Note that if the
159
+ # first click of the `dblclick()` triggers a navigation event, this method will reject.
125
160
  #
126
161
  # If the element is detached from the DOM at any moment during the action, this method rejects.
127
- # When all steps combined have not finished during the specified `timeout`, this method rejects with a TimeoutError. Passing zero timeout disables this.
128
162
  #
129
- # **NOTE** `elementHandle.dblclick()` dispatches two `click` events and a single `dblclick` event.
163
+ # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
164
+ # Passing zero timeout disables this.
165
+ #
166
+ # > **NOTE** `elementHandle.dblclick()` dispatches two `click` events and a single `dblclick` event.
130
167
  def dblclick(
131
168
  button: nil,
132
169
  delay: nil,
133
- position: nil,
134
- modifiers: nil,
135
170
  force: nil,
171
+ modifiers: nil,
136
172
  noWaitAfter: nil,
173
+ position: nil,
137
174
  timeout: nil)
138
175
  raise NotImplementedError.new('dblclick is not implemented yet.')
139
176
  end
140
177
 
141
- # The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the elment, `click` is dispatched. This is equivalend to calling element.click().
178
+ # The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the elment, `click`
179
+ # is dispatched. This is equivalend to calling
180
+ # [element.click()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click).
181
+ #
142
182
  #
143
183
  # ```js
144
184
  # await elementHandle.dispatchEvent('click');
145
185
  # ```
146
- # Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
147
- # Since `eventInit` is event-specific, please refer to the events documentation for the lists of initial properties:
148
186
  #
149
- # DragEvent
150
- # FocusEvent
151
- # KeyboardEvent
152
- # MouseEvent
153
- # PointerEvent
154
- # TouchEvent
155
- # Event
187
+ # Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties
188
+ # and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
189
+ #
190
+ # Since `eventInit` is event-specific, please refer to the events documentation for the lists of initial properties:
191
+ # - [DragEvent](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/DragEvent)
192
+ # - [FocusEvent](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/FocusEvent)
193
+ # - [KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent)
194
+ # - [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent)
195
+ # - [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/PointerEvent)
196
+ # - [TouchEvent](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/TouchEvent)
197
+ # - [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event/Event)
156
198
  #
157
199
  # You can also specify `JSHandle` as the property value if you want live objects to be passed into the event:
200
+ #
158
201
  #
159
202
  # ```js
160
203
  # // Note you can only create DataTransfer in Chromium and Firefox
@@ -165,12 +208,14 @@ module Playwright
165
208
  raise NotImplementedError.new('dispatch_event is not implemented yet.')
166
209
  end
167
210
 
168
- # This method waits for actionability checks, focuses the element, fills it and triggers an `input` event after filling. If the element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws an error. Note that you can pass an empty string to clear the input field.
211
+ # This method waits for [actionability](./actionability.md) checks, focuses the element, fills it and triggers an `input`
212
+ # event after filling. If the element is not an `<input>`, `<textarea>` or `[contenteditable]` element, this method throws
213
+ # an error. Note that you can pass an empty string to clear the input field.
169
214
  def fill(value, noWaitAfter: nil, timeout: nil)
170
215
  raise NotImplementedError.new('fill is not implemented yet.')
171
216
  end
172
217
 
173
- # Calls focus on the element.
218
+ # Calls [focus](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on the element.
174
219
  def focus
175
220
  raise NotImplementedError.new('focus is not implemented yet.')
176
221
  end
@@ -181,15 +226,16 @@ module Playwright
181
226
  end
182
227
 
183
228
  # This method hovers over the element by performing the following steps:
184
- #
185
- # Wait for actionability checks on the element, unless `force` option is set.
186
- # Scroll the element into view if needed.
187
- # Use page.mouse to hover over the center of the element, or the specified `position`.
188
- # Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
229
+ # 1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
230
+ # 1. Scroll the element into view if needed.
231
+ # 1. Use [`property: Page.mouse`] to hover over the center of the element, or the specified `position`.
232
+ # 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
189
233
  #
190
234
  # If the element is detached from the DOM at any moment during the action, this method rejects.
191
- # When all steps combined have not finished during the specified `timeout`, this method rejects with a TimeoutError. Passing zero timeout disables this.
192
- def hover(position: nil, modifiers: nil, force: nil, timeout: nil)
235
+ #
236
+ # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
237
+ # Passing zero timeout disables this.
238
+ def hover(force: nil, modifiers: nil, position: nil, timeout: nil)
193
239
  raise NotImplementedError.new('hover is not implemented yet.')
194
240
  end
195
241
 
@@ -203,41 +249,91 @@ module Playwright
203
249
  raise NotImplementedError.new('inner_text is not implemented yet.')
204
250
  end
205
251
 
252
+ # Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
253
+ def checked?
254
+ raise NotImplementedError.new('checked? is not implemented yet.')
255
+ end
256
+
257
+ # Returns whether the element is disabled, the opposite of [enabled](./actionability.md#enabled).
258
+ def disabled?
259
+ raise NotImplementedError.new('disabled? is not implemented yet.')
260
+ end
261
+
262
+ # Returns whether the element is [editable](./actionability.md#editable).
263
+ def editable?
264
+ raise NotImplementedError.new('editable? is not implemented yet.')
265
+ end
266
+
267
+ # Returns whether the element is [enabled](./actionability.md#enabled).
268
+ def enabled?
269
+ raise NotImplementedError.new('enabled? is not implemented yet.')
270
+ end
271
+
272
+ # Returns whether the element is hidden, the opposite of [visible](./actionability.md#visible).
273
+ def hidden?
274
+ raise NotImplementedError.new('hidden? is not implemented yet.')
275
+ end
276
+
277
+ # Returns whether the element is [visible](./actionability.md#visible).
278
+ def visible?
279
+ raise NotImplementedError.new('visible? is not implemented yet.')
280
+ end
281
+
206
282
  # Returns the frame containing the given element.
207
283
  def owner_frame
208
284
  raise NotImplementedError.new('owner_frame is not implemented yet.')
209
285
  end
210
286
 
211
- # Focuses the element, and then uses `keyboard.down(key)` and `keyboard.up(key)`.
212
- # `key` can specify the intended keyboardEvent.key value or a single character to generate the text for. A superset of the `key` values can be found here. Examples of the keys are:
213
- # `F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
214
- # Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
287
+ # Focuses the element, and then uses [`method: Keyboard.down`] and [`method: Keyboard.up`].
288
+ #
289
+ # `key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)
290
+ # value or a single character to generate the text for. A superset of the `key` values can be found
291
+ # [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are:
292
+ #
293
+ # `F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`,
294
+ # `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
295
+ #
296
+ # Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
297
+ #
215
298
  # Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
216
- # If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
217
- # Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported as well. When speficied with the modifier, modifier is pressed and being held while the subsequent key is being pressed.
299
+ #
300
+ # If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective
301
+ # texts.
302
+ #
303
+ # Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported as well. When speficied with the
304
+ # modifier, modifier is pressed and being held while the subsequent key is being pressed.
218
305
  def press(key, delay: nil, noWaitAfter: nil, timeout: nil)
219
306
  raise NotImplementedError.new('press is not implemented yet.')
220
307
  end
221
308
 
222
309
  # Returns the buffer with the captured screenshot.
223
- # This method waits for the actionability checks, then scrolls element into view before taking a screenshot. If the element is detached from DOM, the method throws an error.
310
+ #
311
+ # This method waits for the [actionability](./actionability.md) checks, then scrolls element into view before taking a
312
+ # screenshot. If the element is detached from DOM, the method throws an error.
224
313
  def screenshot(
314
+ omitBackground: nil,
225
315
  path: nil,
226
- type: nil,
227
316
  quality: nil,
228
- omitBackground: nil,
229
- timeout: nil)
317
+ timeout: nil,
318
+ type: nil)
230
319
  raise NotImplementedError.new('screenshot is not implemented yet.')
231
320
  end
232
321
 
233
- # This method waits for actionability checks, then tries to scroll element into view, unless it is completely visible as defined by IntersectionObserver's `ratio`.
234
- # Throws when `elementHandle` does not point to an element connected to a Document or a ShadowRoot.
322
+ # This method waits for [actionability](./actionability.md) checks, then tries to scroll element into view, unless it is
323
+ # completely visible as defined by
324
+ # [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)'s ```ratio```.
325
+ #
326
+ # Throws when `elementHandle` does not point to an element
327
+ # [connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot.
235
328
  def scroll_into_view_if_needed(timeout: nil)
236
329
  raise NotImplementedError.new('scroll_into_view_if_needed is not implemented yet.')
237
330
  end
238
331
 
239
332
  # Returns the array of option values that have been successfully selected.
240
- # Triggers a `change` and `input` event once all the provided options have been selected. If element is not a `<select>` element, the method throws an error.
333
+ #
334
+ # Triggers a `change` and `input` event once all the provided options have been selected. If element is not a `<select>`
335
+ # element, the method throws an error.
336
+ #
241
337
  #
242
338
  # ```js
243
339
  # // single selection matching the value
@@ -256,33 +352,38 @@ module Playwright
256
352
  raise NotImplementedError.new('select_option is not implemented yet.')
257
353
  end
258
354
 
259
- # This method waits for actionability checks, then focuses the element and selects all its text content.
355
+ # This method waits for [actionability](./actionability.md) checks, then focuses the element and selects all its text
356
+ # content.
260
357
  def select_text(timeout: nil)
261
358
  raise NotImplementedError.new('select_text is not implemented yet.')
262
359
  end
263
360
 
264
- # This method expects `elementHandle` to point to an input element.
265
- # Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they are resolved relative to the the current working directory. For empty array, clears the selected files.
361
+ # This method expects `elementHandle` to point to an
362
+ # [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
363
+ #
364
+ # Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
365
+ # are resolved relative to the the current working directory. For empty array, clears the selected files.
266
366
  def set_input_files(files, noWaitAfter: nil, timeout: nil)
267
367
  raise NotImplementedError.new('set_input_files is not implemented yet.')
268
368
  end
269
369
 
270
370
  # This method taps the element by performing the following steps:
271
- #
272
- # Wait for actionability checks on the element, unless `force` option is set.
273
- # Scroll the element into view if needed.
274
- # Use page.touchscreen to tap in the center of the element, or the specified `position`.
275
- # Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
371
+ # 1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
372
+ # 1. Scroll the element into view if needed.
373
+ # 1. Use [`property: Page.touchscreen`] to tap the center of the element, or the specified `position`.
374
+ # 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
276
375
  #
277
376
  # If the element is detached from the DOM at any moment during the action, this method rejects.
278
- # When all steps combined have not finished during the specified `timeout`, this method rejects with a TimeoutError. Passing zero timeout disables this.
279
377
  #
280
- # **NOTE** `elementHandle.tap()` requires that the `hasTouch` option of the browser context be set to true.
378
+ # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
379
+ # Passing zero timeout disables this.
380
+ #
381
+ # > **NOTE** `elementHandle.tap()` requires that the `hasTouch` option of the browser context be set to true.
281
382
  def tap_point(
282
- position: nil,
283
- modifiers: nil,
284
383
  force: nil,
384
+ modifiers: nil,
285
385
  noWaitAfter: nil,
386
+ position: nil,
286
387
  timeout: nil)
287
388
  raise NotImplementedError.new('tap_point is not implemented yet.')
288
389
  end
@@ -292,18 +393,18 @@ module Playwright
292
393
  raise NotImplementedError.new('text_content is not implemented yet.')
293
394
  end
294
395
 
295
- def to_string
296
- raise NotImplementedError.new('to_string is not implemented yet.')
297
- end
298
-
299
396
  # Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text.
300
- # To press a special key, like `Control` or `ArrowDown`, use `elementHandle.press(key[, options])`.
397
+ #
398
+ # To press a special key, like `Control` or `ArrowDown`, use [`method: ElementHandle.press`].
399
+ #
301
400
  #
302
401
  # ```js
303
402
  # await elementHandle.type('Hello'); // Types instantly
304
403
  # await elementHandle.type('World', {delay: 100}); // Types slower, like a user
305
404
  # ```
405
+ #
306
406
  # An example of typing into a text field and then submitting the form:
407
+ #
307
408
  #
308
409
  # ```js
309
410
  # const elementHandle = await page.$('input');
@@ -315,36 +416,48 @@ module Playwright
315
416
  end
316
417
 
317
418
  # This method checks the element by performing the following steps:
318
- #
319
- # Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already unchecked, this method returns immediately.
320
- # Wait for actionability checks on the element, unless `force` option is set.
321
- # Scroll the element into view if needed.
322
- # Use page.mouse to click in the center of the element.
323
- # Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
324
- # Ensure that the element is now unchecked. If not, this method rejects.
419
+ # 1. Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already
420
+ # unchecked, this method returns immediately.
421
+ # 1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
422
+ # 1. Scroll the element into view if needed.
423
+ # 1. Use [`property: Page.mouse`] to click in the center of the element.
424
+ # 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
425
+ # 1. Ensure that the element is now unchecked. If not, this method rejects.
325
426
  #
326
427
  # If the element is detached from the DOM at any moment during the action, this method rejects.
327
- # When all steps combined have not finished during the specified `timeout`, this method rejects with a TimeoutError. Passing zero timeout disables this.
428
+ #
429
+ # When all steps combined have not finished during the specified `timeout`, this method rejects with a `TimeoutError`.
430
+ # Passing zero timeout disables this.
328
431
  def uncheck(force: nil, noWaitAfter: nil, timeout: nil)
329
432
  raise NotImplementedError.new('uncheck is not implemented yet.')
330
433
  end
331
434
 
332
- # Returns the element satisfies the `state`.
333
- # Depending on the `state` parameter, this method waits for one of the actionability checks to pass. This method throws when the element is detached while waiting, unless waiting for the `"hidden"` state.
435
+ # Returns when the element satisfies the `state`.
334
436
  #
335
- # `"visible"` Wait until the element is visible.
336
- # `"hidden"` Wait until the element is not visible or not attached. Note that waiting for hidden does not throw when the element detaches.
337
- # `"stable"` Wait until the element is both visible and stable.
338
- # `"enabled"` Wait until the element is enabled.
339
- # `"disabled"` Wait until the element is not enabled.
437
+ # Depending on the `state` parameter, this method waits for one of the [actionability](./actionability.md) checks to pass.
438
+ # This method throws when the element is detached while waiting, unless waiting for the `"hidden"` state.
439
+ # - `"visible"` Wait until the element is [visible](./actionability.md#visible).
440
+ # - `"hidden"` Wait until the element is [not visible](./actionability.md#visible) or
441
+ # [not attached](./actionability.md#attached). Note that waiting for hidden does not throw when the element detaches.
442
+ # - `"stable"` Wait until the element is both [visible](./actionability.md#visible) and
443
+ # [stable](./actionability.md#stable).
444
+ # - `"enabled"` Wait until the element is [enabled](./actionability.md#enabled).
445
+ # - `"disabled"` Wait until the element is [not enabled](./actionability.md#enabled).
446
+ # - `"editable"` Wait until the element is [editable](./actionability.md#editable).
340
447
  #
341
448
  # If the element does not satisfy the condition for the `timeout` milliseconds, this method will throw.
342
449
  def wait_for_element_state(state, timeout: nil)
343
450
  raise NotImplementedError.new('wait_for_element_state is not implemented yet.')
344
451
  end
345
452
 
346
- # Returns element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or `detached`.
347
- # Wait for the `selector` relative to the element handle to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
453
+ # Returns element specified by selector when it satisfies `state` option. Returns `null` if waiting for `hidden` or
454
+ # `detached`.
455
+ #
456
+ # Wait for the `selector` relative to the element handle to satisfy `state` option (either appear/disappear from dom, or
457
+ # become visible/hidden). If at the moment of calling the method `selector` already satisfies the condition, the method
458
+ # will return immediately. If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will
459
+ # throw.
460
+ #
348
461
  #
349
462
  # ```js
350
463
  # await page.setContent(`<div><span></span></div>`);
@@ -353,7 +466,7 @@ module Playwright
353
466
  # const span = await div.waitForSelector('span', { state: 'attached' });
354
467
  # ```
355
468
  #
356
- # **NOTE** This method does not work across navigations, use `page.waitForSelector(selector[, options])` instead.
469
+ # > **NOTE** This method does not work across navigations, use [`method: Page.waitForSelector`] instead.
357
470
  def wait_for_selector(selector, state: nil, timeout: nil)
358
471
  raise NotImplementedError.new('wait_for_selector is not implemented yet.')
359
472
  end