playwright-ruby-client 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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,