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
@@ -15,18 +15,46 @@ module Playwright
15
15
  # })();
16
16
  # ```
17
17
  #
18
- # By default, the `playwright` NPM package automatically downloads browser executables during installation. The
19
- # `playwright-core` NPM package can be used to skip automatic downloads.
18
+ # ```python async
19
+ # import asyncio
20
+ # from playwright.async_api import async_playwright
21
+ #
22
+ # async def run(playwright):
23
+ # chromium = playwright.chromium # or "firefox" or "webkit".
24
+ # browser = await chromium.launch()
25
+ # page = await browser.new_page()
26
+ # await page.goto("http://example.com")
27
+ # # other actions...
28
+ # await browser.close()
29
+ #
30
+ # async def main():
31
+ # async with async_playwright() as playwright:
32
+ # await run(playwright)
33
+ # asyncio.run(main())
34
+ # ```
35
+ #
36
+ # ```python sync
37
+ # from playwright.sync_api import sync_playwright
38
+ #
39
+ # def run(playwright):
40
+ # chromium = playwright.chromium # or "firefox" or "webkit".
41
+ # browser = chromium.launch()
42
+ # page = browser.new_page()
43
+ # page.goto("http://example.com")
44
+ # # other actions...
45
+ # browser.close()
46
+ #
47
+ # with sync_playwright() as playwright:
48
+ # run(playwright)
49
+ # ```
20
50
  class Playwright < PlaywrightApi
21
51
 
22
52
  # This object can be used to launch or connect to Chromium, returning instances of `ChromiumBrowser`.
23
53
  def chromium # property
24
- wrap_channel_owner(@channel_owner.chromium)
54
+ wrap_impl(@impl.chromium)
25
55
  end
26
56
 
27
- # Returns a list of devices to be used with [`method: Browser.newContext`] or [`method: Browser.newPage`]. Actual list of
28
- # devices can be found in
29
- # [src/server/deviceDescriptors.ts](https://github.com/Microsoft/playwright/blob/master/src/server/deviceDescriptors.ts).
57
+ # Returns a dictionary of devices to be used with [`method: Browser.newContext`] or [`method: Browser.newPage`].
30
58
  #
31
59
  #
32
60
  # ```js
@@ -44,8 +72,45 @@ module Playwright
44
72
  # await browser.close();
45
73
  # })();
46
74
  # ```
75
+ #
76
+ # ```python async
77
+ # import asyncio
78
+ # from playwright.async_api import async_playwright
79
+ #
80
+ # async def run(playwright):
81
+ # webkit = playwright.webkit
82
+ # iphone = playwright.devices["iPhone 6"]
83
+ # browser = await webkit.launch()
84
+ # context = await browser.new_context(**iphone)
85
+ # page = await context.new_page()
86
+ # await page.goto("http://example.com")
87
+ # # other actions...
88
+ # await browser.close()
89
+ #
90
+ # async def main():
91
+ # async with async_playwright() as playwright:
92
+ # await run(playwright)
93
+ # asyncio.run(main())
94
+ # ```
95
+ #
96
+ # ```python sync
97
+ # from playwright.sync_api import sync_playwright
98
+ #
99
+ # def run(playwright):
100
+ # webkit = playwright.webkit
101
+ # iphone = playwright.devices["iPhone 6"]
102
+ # browser = webkit.launch()
103
+ # context = browser.new_context(**iphone)
104
+ # page = context.new_page()
105
+ # page.goto("http://example.com")
106
+ # # other actions...
107
+ # browser.close()
108
+ #
109
+ # with sync_playwright() as playwright:
110
+ # run(playwright)
111
+ # ```
47
112
  def devices # property
48
- wrap_channel_owner(@channel_owner.devices)
113
+ wrap_impl(@impl.devices)
49
114
  end
50
115
 
51
116
  # Playwright methods might throw errors if they are unable to fulfill a request. For example,
@@ -66,13 +131,27 @@ module Playwright
66
131
  # }
67
132
  # }
68
133
  # ```
134
+ #
135
+ # ```python async
136
+ # try:
137
+ # await page.wait_for_selector(".foo")
138
+ # except TimeoutError as e:
139
+ # # do something if this is a timeout.
140
+ # ```
141
+ #
142
+ # ```python sync
143
+ # try:
144
+ # page.wait_for_selector(".foo")
145
+ # except TimeoutError as e:
146
+ # # do something if this is a timeout.
147
+ # ```
69
148
  def errors # property
70
149
  raise NotImplementedError.new('errors is not implemented yet.')
71
150
  end
72
151
 
73
152
  # This object can be used to launch or connect to Firefox, returning instances of `FirefoxBrowser`.
74
153
  def firefox # property
75
- wrap_channel_owner(@channel_owner.firefox)
154
+ wrap_impl(@impl.firefox)
76
155
  end
77
156
 
78
157
  # Selectors can be used to install custom selector engines. See
@@ -83,35 +162,35 @@ module Playwright
83
162
 
84
163
  # This object can be used to launch or connect to WebKit, returning instances of `WebKitBrowser`.
85
164
  def webkit # property
86
- wrap_channel_owner(@channel_owner.webkit)
165
+ wrap_impl(@impl.webkit)
87
166
  end
88
167
 
89
168
  # @nodoc
90
- def android
91
- wrap_channel_owner(@channel_owner.android)
169
+ def electron
170
+ wrap_impl(@impl.electron)
92
171
  end
93
172
 
94
173
  # @nodoc
95
- def electron
96
- wrap_channel_owner(@channel_owner.electron)
174
+ def android
175
+ wrap_impl(@impl.android)
97
176
  end
98
177
 
99
178
  # -- inherited from EventEmitter --
100
179
  # @nodoc
101
- def off(event, callback)
102
- wrap_channel_owner(@channel_owner.off(event, callback))
180
+ def on(event, callback)
181
+ wrap_impl(@impl.on(event, callback))
103
182
  end
104
183
 
105
184
  # -- inherited from EventEmitter --
106
185
  # @nodoc
107
- def once(event, callback)
108
- wrap_channel_owner(@channel_owner.once(event, callback))
186
+ def off(event, callback)
187
+ wrap_impl(@impl.off(event, callback))
109
188
  end
110
189
 
111
190
  # -- inherited from EventEmitter --
112
191
  # @nodoc
113
- def on(event, callback)
114
- wrap_channel_owner(@channel_owner.on(event, callback))
192
+ def once(event, callback)
193
+ wrap_impl(@impl.once(event, callback))
115
194
  end
116
195
  end
117
196
  end
@@ -7,8 +7,8 @@ module Playwright
7
7
  # If request fails at some point, then instead of `'requestfinished'` event (and possibly instead of 'response' event),
8
8
  # the [`event: Page.requestfailed`] event is emitted.
9
9
  #
10
- # > **NOTE** HTTP Error responses, such as 404 or 503, are still successful responses from HTTP standpoint, so request
11
- # will complete with `'requestfinished'` event.
10
+ # > NOTE: HTTP Error responses, such as 404 or 503, are still successful responses from HTTP standpoint, so request will
11
+ # complete with `'requestfinished'` event.
12
12
  #
13
13
  # If request gets a 'redirect' response, the request is successfully finished with the 'requestfinished' event, and a new
14
14
  # request is issued to a redirected url.
@@ -24,38 +24,42 @@ module Playwright
24
24
  # console.log(request.url() + ' ' + request.failure().errorText);
25
25
  # });
26
26
  # ```
27
+ #
28
+ # ```py
29
+ # page.on("requestfailed", lambda request: print(request.url + " " + request.failure))
30
+ # ```
27
31
  def failure
28
- raise NotImplementedError.new('failure is not implemented yet.')
32
+ wrap_impl(@impl.failure)
29
33
  end
30
34
 
31
35
  # Returns the `Frame` that initiated this request.
32
36
  def frame
33
- raise NotImplementedError.new('frame is not implemented yet.')
37
+ wrap_impl(@impl.frame)
34
38
  end
35
39
 
36
40
  # An object with HTTP headers associated with the request. All header names are lower-case.
37
41
  def headers
38
- raise NotImplementedError.new('headers is not implemented yet.')
42
+ wrap_impl(@impl.headers)
39
43
  end
40
44
 
41
45
  # Whether this request is driving frame's navigation.
42
46
  def navigation_request?
43
- raise NotImplementedError.new('navigation_request? is not implemented yet.')
47
+ wrap_impl(@impl.navigation_request?)
44
48
  end
45
49
 
46
50
  # Request's method (GET, POST, etc.)
47
51
  def method
48
- wrap_channel_owner(@channel_owner.method)
52
+ wrap_impl(@impl.method)
49
53
  end
50
54
 
51
55
  # Request's post body, if any.
52
56
  def post_data
53
- raise NotImplementedError.new('post_data is not implemented yet.')
57
+ wrap_impl(@impl.post_data)
54
58
  end
55
59
 
56
60
  # Request's post body in a binary form, if any.
57
61
  def post_data_buffer
58
- raise NotImplementedError.new('post_data_buffer is not implemented yet.')
62
+ wrap_impl(@impl.post_data_buffer)
59
63
  end
60
64
 
61
65
  # Returns parsed request's body for `form-urlencoded` and JSON as a fallback if any.
@@ -63,7 +67,7 @@ module Playwright
63
67
  # When the response is `application/x-www-form-urlencoded` then a key/value object of the values will be returned.
64
68
  # Otherwise it will be parsed as JSON.
65
69
  def post_data_json
66
- raise NotImplementedError.new('post_data_json is not implemented yet.')
70
+ wrap_impl(@impl.post_data_json)
67
71
  end
68
72
 
69
73
  # Request that was redirected by the server to this one, if any.
@@ -80,6 +84,16 @@ module Playwright
80
84
  # console.log(response.request().redirectedFrom().url()); // 'http://example.com'
81
85
  # ```
82
86
  #
87
+ # ```python async
88
+ # response = await page.goto("http://example.com")
89
+ # print(response.request.redirected_from.url) # "http://example.com"
90
+ # ```
91
+ #
92
+ # ```python sync
93
+ # response = page.goto("http://example.com")
94
+ # print(response.request.redirected_from.url) # "http://example.com"
95
+ # ```
96
+ #
83
97
  # If the website `https://google.com` has no redirects:
84
98
  #
85
99
  #
@@ -87,8 +101,18 @@ module Playwright
87
101
  # const response = await page.goto('https://google.com');
88
102
  # console.log(response.request().redirectedFrom()); // null
89
103
  # ```
104
+ #
105
+ # ```python async
106
+ # response = await page.goto("https://google.com")
107
+ # print(response.request.redirected_from) # None
108
+ # ```
109
+ #
110
+ # ```python sync
111
+ # response = page.goto("https://google.com")
112
+ # print(response.request.redirected_from) # None
113
+ # ```
90
114
  def redirected_from
91
- raise NotImplementedError.new('redirected_from is not implemented yet.')
115
+ wrap_impl(@impl.redirected_from)
92
116
  end
93
117
 
94
118
  # New request issued by the browser if the server responded with redirect.
@@ -99,20 +123,24 @@ module Playwright
99
123
  # ```js
100
124
  # console.log(request.redirectedFrom().redirectedTo() === request); // true
101
125
  # ```
126
+ #
127
+ # ```py
128
+ # assert request.redirected_from.redirected_to == request
129
+ # ```
102
130
  def redirected_to
103
- raise NotImplementedError.new('redirected_to is not implemented yet.')
131
+ wrap_impl(@impl.redirected_to)
104
132
  end
105
133
 
106
134
  # Contains the request's resource type as it was perceived by the rendering engine. ResourceType will be one of the
107
135
  # following: `document`, `stylesheet`, `image`, `media`, `font`, `script`, `texttrack`, `xhr`, `fetch`, `eventsource`,
108
136
  # `websocket`, `manifest`, `other`.
109
137
  def resource_type
110
- raise NotImplementedError.new('resource_type is not implemented yet.')
138
+ wrap_impl(@impl.resource_type)
111
139
  end
112
140
 
113
141
  # Returns the matching `Response` object, or `null` if the response was not received due to error.
114
142
  def response
115
- raise NotImplementedError.new('response is not implemented yet.')
143
+ wrap_impl(@impl.response)
116
144
  end
117
145
 
118
146
  # Returns resource timing information for given request. Most of the timing values become available upon the response,
@@ -123,35 +151,54 @@ module Playwright
123
151
  # ```js
124
152
  # const [request] = await Promise.all([
125
153
  # page.waitForEvent('requestfinished'),
126
- # page.goto(httpsServer.EMPTY_PAGE)
154
+ # page.goto('http://example.com')
127
155
  # ]);
128
156
  # console.log(request.timing());
129
157
  # ```
158
+ #
159
+ # ```python async
160
+ # async with page.expect_event("requestfinished") as request_info:
161
+ # await page.goto("http://example.com")
162
+ # request = await request_info.value
163
+ # print(request.timing)
164
+ # ```
165
+ #
166
+ # ```python sync
167
+ # with page.expect_event("requestfinished") as request_info:
168
+ # page.goto("http://example.com")
169
+ # request = request_info.value
170
+ # print(request.timing)
171
+ # ```
130
172
  def timing
131
- raise NotImplementedError.new('timing is not implemented yet.')
173
+ wrap_impl(@impl.timing)
132
174
  end
133
175
 
134
176
  # URL of the request.
135
177
  def url
136
- raise NotImplementedError.new('url is not implemented yet.')
178
+ wrap_impl(@impl.url)
179
+ end
180
+
181
+ # @nodoc
182
+ def after_initialize
183
+ wrap_impl(@impl.after_initialize)
137
184
  end
138
185
 
139
186
  # -- inherited from EventEmitter --
140
187
  # @nodoc
141
- def off(event, callback)
142
- wrap_channel_owner(@channel_owner.off(event, callback))
188
+ def on(event, callback)
189
+ wrap_impl(@impl.on(event, callback))
143
190
  end
144
191
 
145
192
  # -- inherited from EventEmitter --
146
193
  # @nodoc
147
- def once(event, callback)
148
- wrap_channel_owner(@channel_owner.once(event, callback))
194
+ def off(event, callback)
195
+ wrap_impl(@impl.off(event, callback))
149
196
  end
150
197
 
151
198
  # -- inherited from EventEmitter --
152
199
  # @nodoc
153
- def on(event, callback)
154
- wrap_channel_owner(@channel_owner.on(event, callback))
200
+ def once(event, callback)
201
+ wrap_impl(@impl.once(event, callback))
155
202
  end
156
203
  end
157
204
  end
@@ -61,20 +61,20 @@ module Playwright
61
61
 
62
62
  # -- inherited from EventEmitter --
63
63
  # @nodoc
64
- def off(event, callback)
65
- wrap_channel_owner(@channel_owner.off(event, callback))
64
+ def on(event, callback)
65
+ wrap_impl(@impl.on(event, callback))
66
66
  end
67
67
 
68
68
  # -- inherited from EventEmitter --
69
69
  # @nodoc
70
- def once(event, callback)
71
- wrap_channel_owner(@channel_owner.once(event, callback))
70
+ def off(event, callback)
71
+ wrap_impl(@impl.off(event, callback))
72
72
  end
73
73
 
74
74
  # -- inherited from EventEmitter --
75
75
  # @nodoc
76
- def on(event, callback)
77
- wrap_channel_owner(@channel_owner.on(event, callback))
76
+ def once(event, callback)
77
+ wrap_impl(@impl.once(event, callback))
78
78
  end
79
79
  end
80
80
  end
@@ -22,6 +22,32 @@ module Playwright
22
22
  # route.continue({headers});
23
23
  # });
24
24
  # ```
25
+ #
26
+ # ```python async
27
+ # async def handle(route, request):
28
+ # # override headers
29
+ # headers = {
30
+ # **request.headers,
31
+ # "foo": "bar" # set "foo" header
32
+ # "origin": None # remove "origin" header
33
+ # }
34
+ # await route.continue(headers=headers)
35
+ # }
36
+ # await page.route("**/*", handle)
37
+ # ```
38
+ #
39
+ # ```python sync
40
+ # def handle(route, request):
41
+ # # override headers
42
+ # headers = {
43
+ # **request.headers,
44
+ # "foo": "bar" # set "foo" header
45
+ # "origin": None # remove "origin" header
46
+ # }
47
+ # route.continue(headers=headers)
48
+ # }
49
+ # page.route("**/*", handle)
50
+ # ```
25
51
  def continue_(headers: nil, method: nil, postData: nil, url: nil)
26
52
  raise NotImplementedError.new('continue_ is not implemented yet.')
27
53
  end
@@ -41,12 +67,34 @@ module Playwright
41
67
  # });
42
68
  # ```
43
69
  #
70
+ # ```python async
71
+ # await page.route("**/*", lambda route: route.fulfill(
72
+ # status=404,
73
+ # content_type="text/plain",
74
+ # body="not found!"))
75
+ # ```
76
+ #
77
+ # ```python sync
78
+ # page.route("**/*", lambda route: route.fulfill(
79
+ # status=404,
80
+ # content_type="text/plain",
81
+ # body="not found!"))
82
+ # ```
83
+ #
44
84
  # An example of serving static file:
45
85
  #
46
86
  #
47
87
  # ```js
48
88
  # await page.route('**/xhr_endpoint', route => route.fulfill({ path: 'mock_data.json' }));
49
89
  # ```
90
+ #
91
+ # ```python async
92
+ # await page.route("**/xhr_endpoint", lambda route: route.fulfill(path="mock_data.json"))
93
+ # ```
94
+ #
95
+ # ```python sync
96
+ # page.route("**/xhr_endpoint", lambda route: route.fulfill(path="mock_data.json"))
97
+ # ```
50
98
  def fulfill(
51
99
  body: nil,
52
100
  contentType: nil,