playwright-ruby-client 0.1.0 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +20 -8
  3. data/docs/api_coverage.md +123 -73
  4. data/lib/playwright.rb +48 -9
  5. data/lib/playwright/channel.rb +12 -2
  6. data/lib/playwright/channel_owner.rb +3 -5
  7. data/lib/playwright/channel_owners/android.rb +1 -1
  8. data/lib/playwright/channel_owners/android_device.rb +11 -11
  9. data/lib/playwright/channel_owners/artifact.rb +30 -0
  10. data/lib/playwright/channel_owners/binding_call.rb +3 -0
  11. data/lib/playwright/channel_owners/browser.rb +22 -1
  12. data/lib/playwright/channel_owners/browser_context.rb +155 -4
  13. data/lib/playwright/channel_owners/browser_type.rb +28 -0
  14. data/lib/playwright/channel_owners/dialog.rb +28 -0
  15. data/lib/playwright/channel_owners/element_handle.rb +18 -5
  16. data/lib/playwright/channel_owners/frame.rb +40 -5
  17. data/lib/playwright/channel_owners/js_handle.rb +3 -3
  18. data/lib/playwright/channel_owners/page.rb +172 -51
  19. data/lib/playwright/channel_owners/playwright.rb +24 -27
  20. data/lib/playwright/channel_owners/request.rb +27 -3
  21. data/lib/playwright/channel_owners/response.rb +60 -0
  22. data/lib/playwright/channel_owners/route.rb +78 -0
  23. data/lib/playwright/channel_owners/selectors.rb +19 -1
  24. data/lib/playwright/channel_owners/stream.rb +15 -0
  25. data/lib/playwright/connection.rb +11 -32
  26. data/lib/playwright/download.rb +27 -0
  27. data/lib/playwright/errors.rb +6 -0
  28. data/lib/playwright/events.rb +2 -5
  29. data/lib/playwright/keyboard_impl.rb +1 -1
  30. data/lib/playwright/mouse_impl.rb +41 -0
  31. data/lib/playwright/playwright_api.rb +3 -1
  32. data/lib/playwright/route_handler_entry.rb +28 -0
  33. data/lib/playwright/select_option_values.rb +14 -4
  34. data/lib/playwright/transport.rb +28 -7
  35. data/lib/playwright/url_matcher.rb +1 -1
  36. data/lib/playwright/utils.rb +11 -2
  37. data/lib/playwright/version.rb +1 -1
  38. data/lib/playwright/video.rb +51 -0
  39. data/lib/playwright/wait_helper.rb +2 -2
  40. data/lib/playwright_api/accessibility.rb +39 -1
  41. data/lib/playwright_api/android.rb +72 -5
  42. data/lib/playwright_api/android_device.rb +139 -26
  43. data/lib/playwright_api/android_input.rb +17 -13
  44. data/lib/playwright_api/android_socket.rb +16 -0
  45. data/lib/playwright_api/android_web_view.rb +21 -0
  46. data/lib/playwright_api/browser.rb +87 -19
  47. data/lib/playwright_api/browser_context.rb +216 -32
  48. data/lib/playwright_api/browser_type.rb +45 -58
  49. data/lib/playwright_api/dialog.rb +54 -7
  50. data/lib/playwright_api/element_handle.rb +113 -33
  51. data/lib/playwright_api/file_chooser.rb +6 -1
  52. data/lib/playwright_api/frame.rb +238 -43
  53. data/lib/playwright_api/js_handle.rb +20 -2
  54. data/lib/playwright_api/keyboard.rb +48 -1
  55. data/lib/playwright_api/mouse.rb +26 -5
  56. data/lib/playwright_api/page.rb +534 -63
  57. data/lib/playwright_api/playwright.rb +43 -47
  58. data/lib/playwright_api/request.rb +38 -12
  59. data/lib/playwright_api/response.rb +27 -10
  60. data/lib/playwright_api/route.rb +51 -6
  61. data/lib/playwright_api/selectors.rb +28 -2
  62. data/lib/playwright_api/touchscreen.rb +1 -1
  63. data/lib/playwright_api/web_socket.rb +15 -0
  64. data/lib/playwright_api/worker.rb +25 -1
  65. data/playwright.gemspec +4 -2
  66. metadata +42 -14
  67. data/lib/playwright/channel_owners/chromium_browser.rb +0 -8
  68. data/lib/playwright/channel_owners/chromium_browser_context.rb +0 -8
  69. data/lib/playwright/channel_owners/download.rb +0 -27
  70. data/lib/playwright/channel_owners/firefox_browser.rb +0 -8
  71. data/lib/playwright/channel_owners/webkit_browser.rb +0 -8
  72. data/lib/playwright_api/binding_call.rb +0 -27
  73. data/lib/playwright_api/chromium_browser_context.rb +0 -59
  74. data/lib/playwright_api/download.rb +0 -100
  75. data/lib/playwright_api/video.rb +0 -24
@@ -15,6 +15,23 @@ module Playwright
15
15
  # })();
16
16
  # ```
17
17
  #
18
+ # ```java
19
+ # import com.microsoft.playwright.*;
20
+ #
21
+ # public class Example {
22
+ # public static void main(String[] args) {
23
+ # try (Playwright playwright = Playwright.create()) {
24
+ # BrowserType chromium = playwright.chromium();
25
+ # Browser browser = chromium.launch();
26
+ # Page page = browser.newPage();
27
+ # page.navigate("http://example.com");
28
+ # // other actions...
29
+ # browser.close();
30
+ # }
31
+ # }
32
+ # }
33
+ # ```
34
+ #
18
35
  # ```python async
19
36
  # import asyncio
20
37
  # from playwright.async_api import async_playwright
@@ -49,7 +66,7 @@ module Playwright
49
66
  # ```
50
67
  class Playwright < PlaywrightApi
51
68
 
52
- # This object can be used to launch or connect to Chromium, returning instances of `ChromiumBrowser`.
69
+ # This object can be used to launch or connect to Chromium, returning instances of `Browser`.
53
70
  def chromium # property
54
71
  wrap_impl(@impl.chromium)
55
72
  end
@@ -113,43 +130,7 @@ module Playwright
113
130
  wrap_impl(@impl.devices)
114
131
  end
115
132
 
116
- # Playwright methods might throw errors if they are unable to fulfill a request. For example,
117
- # [`method: Page.waitForSelector`] might fail if the selector doesn't match any nodes during the given timeframe.
118
- #
119
- # For certain types of errors Playwright uses specific error classes. These classes are available via
120
- # [`playwright.errors`](#playwrighterrors).
121
- #
122
- # An example of handling a timeout error:
123
- #
124
- #
125
- # ```js
126
- # try {
127
- # await page.waitForSelector('.foo');
128
- # } catch (e) {
129
- # if (e instanceof playwright.errors.TimeoutError) {
130
- # // Do something if this is a timeout.
131
- # }
132
- # }
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
- # ```
148
- def errors # property
149
- raise NotImplementedError.new('errors is not implemented yet.')
150
- end
151
-
152
- # This object can be used to launch or connect to Firefox, returning instances of `FirefoxBrowser`.
133
+ # This object can be used to launch or connect to Firefox, returning instances of `Browser`.
153
134
  def firefox # property
154
135
  wrap_impl(@impl.firefox)
155
136
  end
@@ -157,27 +138,42 @@ module Playwright
157
138
  # Selectors can be used to install custom selector engines. See [Working with selectors](./selectors.md) for more
158
139
  # information.
159
140
  def selectors # property
160
- raise NotImplementedError.new('selectors is not implemented yet.')
141
+ wrap_impl(@impl.selectors)
161
142
  end
162
143
 
163
- # This object can be used to launch or connect to WebKit, returning instances of `WebKitBrowser`.
144
+ # This object can be used to launch or connect to WebKit, returning instances of `Browser`.
164
145
  def webkit # property
165
146
  wrap_impl(@impl.webkit)
166
147
  end
167
148
 
168
- # Terminates this instance of Playwright, will also close all created browsers if they are still running.
169
- def close
170
- raise NotImplementedError.new('close is not implemented yet.')
149
+ # Terminates this instance of Playwright in case it was created bypassing the Python context manager. This is useful in
150
+ # REPL applications.
151
+ #
152
+ # ```py
153
+ # >>> from playwright.sync_api import sync_playwright
154
+ #
155
+ # >>> playwright = sync_playwright().start()
156
+ #
157
+ # >>> browser = playwright.chromium.launch()
158
+ # >>> page = browser.new_page()
159
+ # >>> page.goto("http://whatsmyuseragent.org/")
160
+ # >>> page.screenshot(path="example.png")
161
+ # >>> browser.close()
162
+ #
163
+ # >>> playwright.stop()
164
+ # ```
165
+ def stop
166
+ raise NotImplementedError.new('stop is not implemented yet.')
171
167
  end
172
168
 
173
169
  # @nodoc
174
- def electron
175
- wrap_impl(@impl.electron)
170
+ def android
171
+ wrap_impl(@impl.android)
176
172
  end
177
173
 
178
174
  # @nodoc
179
- def android
180
- wrap_impl(@impl.android)
175
+ def electron
176
+ wrap_impl(@impl.electron)
181
177
  end
182
178
 
183
179
  # -- inherited from EventEmitter --
@@ -2,10 +2,10 @@ module Playwright
2
2
  # Whenever the page sends a request for a network resource the following sequence of events are emitted by `Page`:
3
3
  # - [`event: Page.request`] emitted when the request is issued by the page.
4
4
  # - [`event: Page.response`] emitted when/if the response status and headers are received for the request.
5
- # - [`event: Page.requestfinished`] emitted when the response body is downloaded and the request is complete.
5
+ # - [`event: Page.requestFinished`] emitted when the response body is downloaded and the request is complete.
6
6
  #
7
7
  # If request fails at some point, then instead of `'requestfinished'` event (and possibly instead of 'response' event),
8
- # the [`event: Page.requestfailed`] event is emitted.
8
+ # the [`event: Page.requestFailed`] event is emitted.
9
9
  #
10
10
  # > NOTE: HTTP Error responses, such as 404 or 503, are still successful responses from HTTP standpoint, so request will
11
11
  # complete with `'requestfinished'` event.
@@ -25,6 +25,12 @@ module Playwright
25
25
  # });
26
26
  # ```
27
27
  #
28
+ # ```java
29
+ # page.onRequestFailed(request -> {
30
+ # System.out.println(request.url() + " " + request.failure());
31
+ # });
32
+ # ```
33
+ #
28
34
  # ```py
29
35
  # page.on("requestfailed", lambda request: print(request.url + " " + request.failure))
30
36
  # ```
@@ -62,6 +68,14 @@ module Playwright
62
68
  wrap_impl(@impl.post_data_buffer)
63
69
  end
64
70
 
71
+ # Returns parsed request's body for `form-urlencoded` and JSON as a fallback if any.
72
+ #
73
+ # When the response is `application/x-www-form-urlencoded` then a key/value object of the values will be returned.
74
+ # Otherwise it will be parsed as JSON.
75
+ def post_data_json
76
+ wrap_impl(@impl.post_data_json)
77
+ end
78
+
65
79
  # Request that was redirected by the server to this one, if any.
66
80
  #
67
81
  # When the server responds with a redirect, Playwright creates a new `Request` object. The two requests are connected by
@@ -76,6 +90,11 @@ module Playwright
76
90
  # console.log(response.request().redirectedFrom().url()); // 'http://example.com'
77
91
  # ```
78
92
  #
93
+ # ```java
94
+ # Response response = page.navigate("http://example.com");
95
+ # System.out.println(response.request().redirectedFrom().url()); // "http://example.com"
96
+ # ```
97
+ #
79
98
  # ```python async
80
99
  # response = await page.goto("http://example.com")
81
100
  # print(response.request.redirected_from.url) # "http://example.com"
@@ -94,6 +113,11 @@ module Playwright
94
113
  # console.log(response.request().redirectedFrom()); // null
95
114
  # ```
96
115
  #
116
+ # ```java
117
+ # Response response = page.navigate("https://google.com");
118
+ # System.out.println(response.request().redirectedFrom()); // null
119
+ # ```
120
+ #
97
121
  # ```python async
98
122
  # response = await page.goto("https://google.com")
99
123
  # print(response.request.redirected_from) # None
@@ -116,6 +140,10 @@ module Playwright
116
140
  # console.log(request.redirectedFrom().redirectedTo() === request); // true
117
141
  # ```
118
142
  #
143
+ # ```java
144
+ # System.out.println(request.redirectedFrom().redirectedTo() == request); // true
145
+ # ```
146
+ #
119
147
  # ```py
120
148
  # assert request.redirected_from.redirected_to == request
121
149
  # ```
@@ -148,6 +176,14 @@ module Playwright
148
176
  # console.log(request.timing());
149
177
  # ```
150
178
  #
179
+ # ```java
180
+ # page.onRequestFinished(request -> {
181
+ # Timing timing = request.timing();
182
+ # System.out.println(timing.responseEnd - timing.startTime);
183
+ # });
184
+ # page.navigate("http://example.com");
185
+ # ```
186
+ #
151
187
  # ```python async
152
188
  # async with page.expect_event("requestfinished") as request_info:
153
189
  # await page.goto("http://example.com")
@@ -170,16 +206,6 @@ module Playwright
170
206
  wrap_impl(@impl.url)
171
207
  end
172
208
 
173
- # @nodoc
174
- def post_data_json
175
- wrap_impl(@impl.post_data_json)
176
- end
177
-
178
- # @nodoc
179
- def after_initialize
180
- wrap_impl(@impl.after_initialize)
181
- end
182
-
183
209
  # -- inherited from EventEmitter --
184
210
  # @nodoc
185
211
  def once(event, callback)
@@ -4,52 +4,69 @@ module Playwright
4
4
 
5
5
  # Returns the buffer with response body.
6
6
  def body
7
- raise NotImplementedError.new('body is not implemented yet.')
7
+ wrap_impl(@impl.body)
8
8
  end
9
9
 
10
10
  # Waits for this response to finish, returns failure error if request failed.
11
11
  def finished
12
- raise NotImplementedError.new('finished is not implemented yet.')
12
+ wrap_impl(@impl.finished)
13
13
  end
14
14
 
15
15
  # Returns the `Frame` that initiated this response.
16
16
  def frame
17
- raise NotImplementedError.new('frame is not implemented yet.')
17
+ wrap_impl(@impl.frame)
18
18
  end
19
19
 
20
20
  # Returns the object with HTTP headers associated with the response. All header names are lower-case.
21
21
  def headers
22
- raise NotImplementedError.new('headers is not implemented yet.')
22
+ wrap_impl(@impl.headers)
23
+ end
24
+
25
+ # Returns the JSON representation of response body.
26
+ #
27
+ # This method will throw if the response body is not parsable via `JSON.parse`.
28
+ def json
29
+ wrap_impl(@impl.json)
23
30
  end
24
31
 
25
32
  # Contains a boolean stating whether the response was successful (status in the range 200-299) or not.
26
33
  def ok
27
- raise NotImplementedError.new('ok is not implemented yet.')
34
+ wrap_impl(@impl.ok)
28
35
  end
29
36
 
30
37
  # Returns the matching `Request` object.
31
38
  def request
32
- raise NotImplementedError.new('request is not implemented yet.')
39
+ wrap_impl(@impl.request)
33
40
  end
34
41
 
35
42
  # Contains the status code of the response (e.g., 200 for a success).
36
43
  def status
37
- raise NotImplementedError.new('status is not implemented yet.')
44
+ wrap_impl(@impl.status)
38
45
  end
39
46
 
40
47
  # Contains the status text of the response (e.g. usually an "OK" for a success).
41
48
  def status_text
42
- raise NotImplementedError.new('status_text is not implemented yet.')
49
+ wrap_impl(@impl.status_text)
43
50
  end
44
51
 
45
52
  # Returns the text representation of response body.
46
53
  def text
47
- raise NotImplementedError.new('text is not implemented yet.')
54
+ wrap_impl(@impl.text)
48
55
  end
49
56
 
50
57
  # Contains the URL of the response.
51
58
  def url
52
- raise NotImplementedError.new('url is not implemented yet.')
59
+ wrap_impl(@impl.url)
60
+ end
61
+
62
+ # @nodoc
63
+ def after_initialize
64
+ wrap_impl(@impl.after_initialize)
65
+ end
66
+
67
+ # @nodoc
68
+ def ok?
69
+ wrap_impl(@impl.ok?)
53
70
  end
54
71
 
55
72
  # -- inherited from EventEmitter --
@@ -5,7 +5,7 @@ module Playwright
5
5
 
6
6
  # Aborts the route's request.
7
7
  def abort(errorCode: nil)
8
- raise NotImplementedError.new('abort is not implemented yet.')
8
+ wrap_impl(@impl.abort(errorCode: unwrap_impl(errorCode)))
9
9
  end
10
10
 
11
11
  # Continues route's request with optional overrides.
@@ -23,6 +23,16 @@ module Playwright
23
23
  # });
24
24
  # ```
25
25
  #
26
+ # ```java
27
+ # page.route("**/*", route -> {
28
+ # // Override headers
29
+ # Map<String, String> headers = new HashMap<>(route.request().headers());
30
+ # headers.put("foo", "bar"); // set "foo" header
31
+ # headers.remove("origin"); // remove "origin" header
32
+ # route.resume(new Route.ResumeOptions().setHeaders(headers));
33
+ # });
34
+ # ```
35
+ #
26
36
  # ```python async
27
37
  # async def handle(route, request):
28
38
  # # override headers
@@ -48,8 +58,8 @@ module Playwright
48
58
  # }
49
59
  # page.route("**/*", handle)
50
60
  # ```
51
- def continue_(headers: nil, method: nil, postData: nil, url: nil)
52
- raise NotImplementedError.new('continue_ is not implemented yet.')
61
+ def continue(headers: nil, method: nil, postData: nil, url: nil)
62
+ wrap_impl(@impl.continue(headers: unwrap_impl(headers), method: unwrap_impl(method), postData: unwrap_impl(postData), url: unwrap_impl(url)))
53
63
  end
54
64
 
55
65
  # Fulfills route's request with given response.
@@ -67,6 +77,15 @@ module Playwright
67
77
  # });
68
78
  # ```
69
79
  #
80
+ # ```java
81
+ # page.route("**/*", route -> {
82
+ # route.fulfill(new Route.FulfillOptions()
83
+ # .setStatus(404)
84
+ # .setContentType("text/plain")
85
+ # .setBody("Not Found!"));
86
+ # });
87
+ # ```
88
+ #
70
89
  # ```python async
71
90
  # await page.route("**/*", lambda route: route.fulfill(
72
91
  # status=404,
@@ -88,6 +107,11 @@ module Playwright
88
107
  # await page.route('**/xhr_endpoint', route => route.fulfill({ path: 'mock_data.json' }));
89
108
  # ```
90
109
  #
110
+ # ```java
111
+ # page.route("**/xhr_endpoint", route -> route.fulfill(
112
+ # new Route.FulfillOptions().setPath(Paths.get("mock_data.json")));
113
+ # ```
114
+ #
91
115
  # ```python async
92
116
  # await page.route("**/xhr_endpoint", lambda route: route.fulfill(path="mock_data.json"))
93
117
  # ```
@@ -97,17 +121,38 @@ module Playwright
97
121
  # ```
98
122
  def fulfill(
99
123
  body: nil,
100
- bodyBytes: nil,
101
124
  contentType: nil,
102
125
  headers: nil,
103
126
  path: nil,
104
127
  status: nil)
105
- raise NotImplementedError.new('fulfill is not implemented yet.')
128
+ wrap_impl(@impl.fulfill(body: unwrap_impl(body), contentType: unwrap_impl(contentType), headers: unwrap_impl(headers), path: unwrap_impl(path), status: unwrap_impl(status)))
106
129
  end
107
130
 
108
131
  # A request to be routed.
109
132
  def request
110
- raise NotImplementedError.new('request is not implemented yet.')
133
+ wrap_impl(@impl.request)
134
+ end
135
+
136
+ # -- inherited from EventEmitter --
137
+ # @nodoc
138
+ def once(event, callback)
139
+ event_emitter_proxy.once(event, callback)
140
+ end
141
+
142
+ # -- inherited from EventEmitter --
143
+ # @nodoc
144
+ def on(event, callback)
145
+ event_emitter_proxy.on(event, callback)
146
+ end
147
+
148
+ # -- inherited from EventEmitter --
149
+ # @nodoc
150
+ def off(event, callback)
151
+ event_emitter_proxy.off(event, callback)
152
+ end
153
+
154
+ private def event_emitter_proxy
155
+ @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
111
156
  end
112
157
  end
113
158
  end
@@ -41,6 +41,32 @@ module Playwright
41
41
  # })();
42
42
  # ```
43
43
  #
44
+ # ```java
45
+ # // Script that evaluates to a selector engine instance.
46
+ # String createTagNameEngine = "{\n" +
47
+ # " // Returns the first element matching given selector in the root's subtree.\n" +
48
+ # " query(root, selector) {\n" +
49
+ # " return root.querySelector(selector);\n" +
50
+ # " },\n" +
51
+ # " // Returns all elements matching given selector in the root's subtree.\n" +
52
+ # " queryAll(root, selector) {\n" +
53
+ # " return Array.from(root.querySelectorAll(selector));\n" +
54
+ # " }\n" +
55
+ # "}";
56
+ # // Register the engine. Selectors will be prefixed with "tag=".
57
+ # playwright.selectors().register("tag", createTagNameEngine);
58
+ # Browser browser = playwright.firefox().launch();
59
+ # Page page = browser.newPage();
60
+ # page.setContent("<div><button>Click me</button></div>");
61
+ # // Use the selector prefixed with its name.
62
+ # ElementHandle button = page.querySelector("tag=button");
63
+ # // Combine it with other selector engines.
64
+ # page.click("tag=div >> text=\"Click me\"");
65
+ # // Can use it in any methods supporting selectors.
66
+ # int buttonCount = (int) page.evalOnSelectorAll("tag=button", "buttons => buttons.length");
67
+ # browser.close();
68
+ # ```
69
+ #
44
70
  # ```python async
45
71
  # # FIXME: add snippet
46
72
  # ```
@@ -48,8 +74,8 @@ module Playwright
48
74
  # ```python sync
49
75
  # # FIXME: add snippet
50
76
  # ```
51
- def register(name, script, contentScript: nil)
52
- raise NotImplementedError.new('register is not implemented yet.')
77
+ def register(name, contentScript: nil, path: nil, script: nil)
78
+ wrap_impl(@impl.register(unwrap_impl(name), contentScript: unwrap_impl(contentScript), path: unwrap_impl(path), script: unwrap_impl(script)))
53
79
  end
54
80
 
55
81
  # -- inherited from EventEmitter --