playwright-ruby-client 1.17.0 → 1.17.1

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/docs/api/api_request.md +7 -0
  3. data/documentation/docs/api/api_request_context.md +137 -0
  4. data/documentation/docs/api/api_response.md +90 -0
  5. data/documentation/docs/api/browser_context.md +4 -0
  6. data/documentation/docs/include/api_coverage.md +30 -13
  7. data/lib/playwright/api_response_impl.rb +73 -0
  8. data/lib/playwright/channel_owners/api_request_context.rb +232 -0
  9. data/lib/playwright/channel_owners/browser_context.rb +3 -1
  10. data/lib/playwright/channel_owners/page.rb +4 -0
  11. data/lib/playwright/version.rb +2 -2
  12. data/lib/playwright_api/android.rb +6 -6
  13. data/lib/playwright_api/android_device.rb +8 -8
  14. data/lib/playwright_api/api_request.rb +18 -0
  15. data/lib/playwright_api/api_request_context.rb +14 -14
  16. data/lib/playwright_api/api_response.rb +68 -0
  17. data/lib/playwright_api/browser.rb +6 -6
  18. data/lib/playwright_api/browser_context.rb +12 -12
  19. data/lib/playwright_api/browser_type.rb +6 -6
  20. data/lib/playwright_api/cdp_session.rb +6 -6
  21. data/lib/playwright_api/console_message.rb +6 -6
  22. data/lib/playwright_api/dialog.rb +6 -6
  23. data/lib/playwright_api/element_handle.rb +6 -6
  24. data/lib/playwright_api/frame.rb +6 -6
  25. data/lib/playwright_api/js_handle.rb +6 -6
  26. data/lib/playwright_api/page.rb +15 -10
  27. data/lib/playwright_api/playwright.rb +6 -6
  28. data/lib/playwright_api/request.rb +6 -6
  29. data/lib/playwright_api/response.rb +6 -6
  30. data/lib/playwright_api/route.rb +6 -6
  31. data/lib/playwright_api/selectors.rb +6 -6
  32. data/lib/playwright_api/web_socket.rb +6 -6
  33. data/lib/playwright_api/worker.rb +8 -8
  34. data/playwright.gemspec +1 -1
  35. metadata +11 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35d4a4e4ac3aa460997a5a9cd44b5272142ba89b480908f0e429fb97d7968337
4
- data.tar.gz: 2a577b8683a2eba60ed97b88b183bd351477cbde0874b8d06d287be0ec4664e8
3
+ metadata.gz: 9407fc7093bb4cdb7539eec09b879e4bfd665626801594c764798ae41d3c7823
4
+ data.tar.gz: e6047ebe532d15fa5600986ae3fc9f42a23ea670923e1ec8fac6f6ecbb7f01c4
5
5
  SHA512:
6
- metadata.gz: 283b87141e9ab9090488684973741983506da16d9ea991945589a1177cd99a5cf2c3b65b35770cc95a6ed3645514c35c9925e75aaffb949d58cbe6a47380c334
7
- data.tar.gz: 7a6071b83e537784b58e6b350c1654a7dfa90bc99576f8ae1780c2104b30242ddd2e9651f6eb9f880a3a777e9345a5706373fbd66b64cc32739ce10cb389b5fb
6
+ metadata.gz: 70b935777666f43236ec9df9b8462ebebf7fb883cde2d57e167d3342a18280a86e286e99e206f47e6ee2c739f23f6afe43daa2def9ea0a322b5e09f3b36bfc81
7
+ data.tar.gz: 3392ad01696c2c22ba411d7e4821e0bf0a2f641526481201927ff6510d7bb077c9fb6b20fcafabd55e5067ff7b1153b950d6b3c532c0bd14d77b9a0b3ac7c4c0
@@ -0,0 +1,7 @@
1
+ ---
2
+ sidebar_position: 10
3
+ ---
4
+
5
+ # APIRequest
6
+
7
+ Not Implemented
@@ -8,3 +8,140 @@ This API is used for the Web API testing. You can use it to trigger API endpoint
8
8
  environment or the service to your e2e test. When used on [Page](./page) or a [BrowserContext](./browser_context), this API will automatically use
9
9
  the cookies from the corresponding [BrowserContext](./browser_context). This means that if you log in using this API, your e2e test will be
10
10
  logged in and vice versa.
11
+
12
+ ## delete
13
+
14
+ ```
15
+ def delete(
16
+ url,
17
+ data: nil,
18
+ failOnStatusCode: nil,
19
+ form: nil,
20
+ headers: nil,
21
+ ignoreHTTPSErrors: nil,
22
+ multipart: nil,
23
+ params: nil,
24
+ timeout: nil)
25
+ ```
26
+
27
+ Sends HTTP(S) [DELETE](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE) request and returns its
28
+ response. The method will populate request cookies from the context and update context cookies from the response. The
29
+ method will automatically follow redirects.
30
+
31
+ ## dispose
32
+
33
+ ```
34
+ def dispose
35
+ ```
36
+
37
+ All responses returned by [APIRequestContext#get](./api_request_context#get) and similar methods are stored in the memory, so that you
38
+ can later call [APIResponse#body](./api_response#body). This method discards all stored responses, and makes
39
+ [APIResponse#body](./api_response#body) throw "Response disposed" error.
40
+
41
+ ## fetch
42
+
43
+ ```
44
+ def fetch(
45
+ urlOrRequest,
46
+ data: nil,
47
+ failOnStatusCode: nil,
48
+ form: nil,
49
+ headers: nil,
50
+ ignoreHTTPSErrors: nil,
51
+ method: nil,
52
+ multipart: nil,
53
+ params: nil,
54
+ timeout: nil)
55
+ ```
56
+
57
+ Sends HTTP(S) request and returns its response. The method will populate request cookies from the context and update
58
+ context cookies from the response. The method will automatically follow redirects.
59
+
60
+ ## get
61
+
62
+ ```
63
+ def get(
64
+ url,
65
+ failOnStatusCode: nil,
66
+ headers: nil,
67
+ ignoreHTTPSErrors: nil,
68
+ params: nil,
69
+ timeout: nil)
70
+ ```
71
+
72
+ Sends HTTP(S) [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET) request and returns its response. The
73
+ method will populate request cookies from the context and update context cookies from the response. The method will
74
+ automatically follow redirects.
75
+
76
+ ## head
77
+
78
+ ```
79
+ def head(
80
+ url,
81
+ failOnStatusCode: nil,
82
+ headers: nil,
83
+ ignoreHTTPSErrors: nil,
84
+ params: nil,
85
+ timeout: nil)
86
+ ```
87
+
88
+ Sends HTTP(S) [HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD) request and returns its response.
89
+ The method will populate request cookies from the context and update context cookies from the response. The method will
90
+ automatically follow redirects.
91
+
92
+ ## patch
93
+
94
+ ```
95
+ def patch(
96
+ url,
97
+ data: nil,
98
+ failOnStatusCode: nil,
99
+ form: nil,
100
+ headers: nil,
101
+ ignoreHTTPSErrors: nil,
102
+ multipart: nil,
103
+ params: nil,
104
+ timeout: nil)
105
+ ```
106
+
107
+ Sends HTTP(S) [PATCH](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH) request and returns its response.
108
+ The method will populate request cookies from the context and update context cookies from the response. The method will
109
+ automatically follow redirects.
110
+
111
+ ## post
112
+
113
+ ```
114
+ def post(
115
+ url,
116
+ data: nil,
117
+ failOnStatusCode: nil,
118
+ form: nil,
119
+ headers: nil,
120
+ ignoreHTTPSErrors: nil,
121
+ multipart: nil,
122
+ params: nil,
123
+ timeout: nil)
124
+ ```
125
+
126
+ Sends HTTP(S) [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) request and returns its response.
127
+ The method will populate request cookies from the context and update context cookies from the response. The method will
128
+ automatically follow redirects.
129
+
130
+ ## put
131
+
132
+ ```
133
+ def put(
134
+ url,
135
+ data: nil,
136
+ failOnStatusCode: nil,
137
+ form: nil,
138
+ headers: nil,
139
+ ignoreHTTPSErrors: nil,
140
+ multipart: nil,
141
+ params: nil,
142
+ timeout: nil)
143
+ ```
144
+
145
+ Sends HTTP(S) [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT) request and returns its response. The
146
+ method will populate request cookies from the context and update context cookies from the response. The method will
147
+ automatically follow redirects.
@@ -0,0 +1,90 @@
1
+ ---
2
+ sidebar_position: 10
3
+ ---
4
+
5
+ # APIResponse
6
+
7
+ [APIResponse](./api_response) class represents responses returned by [APIRequestContext#get](./api_request_context#get) and similar methods.
8
+
9
+ ## body
10
+
11
+ ```
12
+ def body
13
+ ```
14
+
15
+ Returns the buffer with response body.
16
+
17
+ ## dispose
18
+
19
+ ```
20
+ def dispose
21
+ ```
22
+
23
+ Disposes the body of this response. If not called then the body will stay in memory until the context closes.
24
+
25
+ ## headers
26
+
27
+ ```
28
+ def headers
29
+ ```
30
+
31
+ An object with all the response HTTP headers associated with this response.
32
+
33
+ ## headers_array
34
+
35
+ ```
36
+ def headers_array
37
+ ```
38
+
39
+ An array with all the request HTTP headers associated with this response. Header names are not lower-cased. Headers with
40
+ multiple entries, such as `Set-Cookie`, appear in the array multiple times.
41
+
42
+ ## json
43
+
44
+ ```
45
+ def json
46
+ ```
47
+
48
+ Returns the JSON representation of response body.
49
+
50
+ This method will throw if the response body is not parsable via `JSON.parse`.
51
+
52
+ ## ok
53
+
54
+ ```
55
+ def ok
56
+ ```
57
+
58
+ Contains a boolean stating whether the response was successful (status in the range 200-299) or not.
59
+
60
+ ## status
61
+
62
+ ```
63
+ def status
64
+ ```
65
+
66
+ Contains the status code of the response (e.g., 200 for a success).
67
+
68
+ ## status_text
69
+
70
+ ```
71
+ def status_text
72
+ ```
73
+
74
+ Contains the status text of the response (e.g. usually an "OK" for a success).
75
+
76
+ ## text
77
+
78
+ ```
79
+ def text
80
+ ```
81
+
82
+ Returns the text representation of response body.
83
+
84
+ ## url
85
+
86
+ ```
87
+ def url
88
+ ```
89
+
90
+ Contains the URL of the response.
@@ -436,4 +436,8 @@ def expect_page(predicate: nil, timeout: nil)
436
436
  Performs action and waits for a new [Page](./page) to be created in the context. If predicate is provided, it passes [Page](./page) value into the `predicate` and waits for `predicate.call(page)` to return a truthy value. Will throw an error if
437
437
  the context closes before new [Page](./page) is created.
438
438
 
439
+ ## request
440
+
441
+ API testing helper associated with this context. Requests made with this API will use context cookies.
442
+
439
443
  ## tracing
@@ -1,17 +1,5 @@
1
1
  # API coverages
2
2
 
3
- ## APIRequestContext
4
-
5
- * ~~delete~~
6
- * ~~dispose~~
7
- * ~~fetch~~
8
- * ~~get~~
9
- * ~~head~~
10
- * ~~patch~~
11
- * ~~post~~
12
- * ~~put~~
13
- * ~~storage_state~~
14
-
15
3
  ## Request
16
4
 
17
5
  * all_headers
@@ -361,7 +349,7 @@
361
349
  * expect_event
362
350
  * expect_page
363
351
  * ~~wait_for_event~~
364
- * ~~request~~
352
+ * request
365
353
  * tracing
366
354
 
367
355
  ## CDPSession
@@ -461,6 +449,35 @@
461
449
  * locator
462
450
  * nth
463
451
 
452
+ ## APIResponse
453
+
454
+ * body
455
+ * dispose
456
+ * headers
457
+ * headers_array
458
+ * json
459
+ * ok
460
+ * status
461
+ * status_text
462
+ * text
463
+ * url
464
+
465
+ ## APIRequestContext
466
+
467
+ * delete
468
+ * dispose
469
+ * fetch
470
+ * get
471
+ * head
472
+ * patch
473
+ * post
474
+ * put
475
+ * ~~storage_state~~
476
+
477
+ ## ~~APIRequest~~
478
+
479
+ * ~~new_context~~
480
+
464
481
  ## Android
465
482
 
466
483
  * devices
@@ -0,0 +1,73 @@
1
+ module Playwright
2
+ define_api_implementation :APIResponseImpl do
3
+ include Utils::Errors::SafeCloseError
4
+
5
+ # @params context [APIRequestContext]
6
+ # @params initializer [Hash]
7
+ def initialize(context, initializer)
8
+ @request = context
9
+ @initializer = initializer
10
+ @headers = RawHeaders.new(initializer['headers'])
11
+ end
12
+
13
+ def to_s
14
+ "#<APIResponse url=#{url} status=#{status} status_text=#{status_text}>"
15
+ end
16
+
17
+ def url
18
+ @initializer['url']
19
+ end
20
+
21
+ def ok
22
+ (200...300).include?(status)
23
+ end
24
+ alias_method :ok?, :ok
25
+
26
+ def status
27
+ @initializer['status']
28
+ end
29
+
30
+ def status_text
31
+ @initializer['statusText']
32
+ end
33
+
34
+ def headers
35
+ @headers.headers
36
+ end
37
+
38
+ def headers_array
39
+ @headers.headers_array
40
+ end
41
+
42
+ class AlreadyDisposedError < StandardError
43
+ def initialize
44
+ super('Response has been disposed')
45
+ end
46
+ end
47
+
48
+ def body
49
+ binary = @request.channel.send_message_to_server("fetchResponseBody", fetchUid: fetch_uid)
50
+ raise AlreadyDisposedError.new unless binary
51
+ Base64.strict_decode64(binary)
52
+ rescue => err
53
+ if safe_close_error?(err)
54
+ raise AlreadyDisposedError.new
55
+ else
56
+ raise
57
+ end
58
+ end
59
+ alias_method :text, :body
60
+
61
+ def json
62
+ JSON.parse(text)
63
+ end
64
+
65
+ def dispose
66
+ @request.channel.send_message_to_server("disposeAPIResponse", fetchUid: fetch_uid)
67
+ end
68
+
69
+ private def fetch_uid
70
+ @initializer['fetchUid']
71
+ end
72
+ end
73
+ end
@@ -1,4 +1,236 @@
1
+ require 'base64'
2
+
1
3
  module Playwright
2
4
  define_channel_owner :APIRequestContext do
5
+ def dispose
6
+ @channel.send_message_to_server('dispose')
7
+ end
8
+
9
+ def delete(
10
+ url,
11
+ data: nil,
12
+ failOnStatusCode: nil,
13
+ form: nil,
14
+ headers: nil,
15
+ ignoreHTTPSErrors: nil,
16
+ multipart: nil,
17
+ params: nil,
18
+ timeout: nil)
19
+ fetch(
20
+ url,
21
+ method: 'DELETE',
22
+ data: data,
23
+ failOnStatusCode: failOnStatusCode,
24
+ form: form,
25
+ headers: headers,
26
+ ignoreHTTPSErrors: ignoreHTTPSErrors,
27
+ multipart: multipart,
28
+ params: params,
29
+ timeout: timeout,
30
+ )
31
+ end
32
+
33
+ def head(
34
+ url,
35
+ failOnStatusCode: nil,
36
+ headers: nil,
37
+ ignoreHTTPSErrors: nil,
38
+ params: nil,
39
+ timeout: nil)
40
+ fetch(
41
+ url,
42
+ method: 'HEAD',
43
+ failOnStatusCode: failOnStatusCode,
44
+ headers: headers,
45
+ ignoreHTTPSErrors: ignoreHTTPSErrors,
46
+ params: params,
47
+ timeout: timeout,
48
+ )
49
+ end
50
+
51
+ def get(
52
+ url,
53
+ failOnStatusCode: nil,
54
+ headers: nil,
55
+ ignoreHTTPSErrors: nil,
56
+ params: nil,
57
+ timeout: nil)
58
+ fetch(
59
+ url,
60
+ method: 'GET',
61
+ failOnStatusCode: failOnStatusCode,
62
+ headers: headers,
63
+ ignoreHTTPSErrors: ignoreHTTPSErrors,
64
+ params: params,
65
+ timeout: timeout,
66
+ )
67
+ end
68
+
69
+ def patch(
70
+ url,
71
+ data: nil,
72
+ failOnStatusCode: nil,
73
+ form: nil,
74
+ headers: nil,
75
+ ignoreHTTPSErrors: nil,
76
+ multipart: nil,
77
+ params: nil,
78
+ timeout: nil)
79
+ fetch(
80
+ url,
81
+ method: 'PATCH',
82
+ data: data,
83
+ failOnStatusCode: failOnStatusCode,
84
+ form: form,
85
+ headers: headers,
86
+ ignoreHTTPSErrors: ignoreHTTPSErrors,
87
+ multipart: multipart,
88
+ params: params,
89
+ timeout: timeout,
90
+ )
91
+ end
92
+
93
+ def put(
94
+ url,
95
+ data: nil,
96
+ failOnStatusCode: nil,
97
+ form: nil,
98
+ headers: nil,
99
+ ignoreHTTPSErrors: nil,
100
+ multipart: nil,
101
+ params: nil,
102
+ timeout: nil)
103
+ fetch(
104
+ url,
105
+ method: 'PUT',
106
+ data: data,
107
+ failOnStatusCode: failOnStatusCode,
108
+ form: form,
109
+ headers: headers,
110
+ ignoreHTTPSErrors: ignoreHTTPSErrors,
111
+ multipart: multipart,
112
+ params: params,
113
+ timeout: timeout,
114
+ )
115
+ end
116
+
117
+ def post(
118
+ url,
119
+ data: nil,
120
+ failOnStatusCode: nil,
121
+ form: nil,
122
+ headers: nil,
123
+ ignoreHTTPSErrors: nil,
124
+ multipart: nil,
125
+ params: nil,
126
+ timeout: nil)
127
+ fetch(
128
+ url,
129
+ method: 'POST',
130
+ data: data,
131
+ failOnStatusCode: failOnStatusCode,
132
+ form: form,
133
+ headers: headers,
134
+ ignoreHTTPSErrors: ignoreHTTPSErrors,
135
+ multipart: multipart,
136
+ params: params,
137
+ timeout: timeout,
138
+ )
139
+ end
140
+
141
+ def fetch(
142
+ urlOrRequest,
143
+ data: nil,
144
+ failOnStatusCode: nil,
145
+ form: nil,
146
+ headers: nil,
147
+ ignoreHTTPSErrors: nil,
148
+ method: nil,
149
+ multipart: nil,
150
+ params: nil,
151
+ timeout: nil)
152
+
153
+ if [ChannelOwners::Request, String].none? { |type| urlOrRequest.is_a?(type) }
154
+ raise ArgumentError.new("First argument must be either URL string or Request")
155
+ end
156
+ if [data, form, multipart].compact.count > 1
157
+ raise ArgumentError.new("Only one of 'data', 'form' or 'multipart' can be specified")
158
+ end
159
+
160
+ request = urlOrRequest.is_a?(ChannelOwners::Request) ? urlOrRequest : nil
161
+ headers_obj = headers || request&.headers
162
+ fetch_params = {
163
+ url: request&.url || urlOrRequest,
164
+ params: object_to_array(params),
165
+ method: method || request&.method || 'GET',
166
+ headers: headers_obj ? HttpHeaders.new(headers_obj).as_serialized : nil,
167
+ }
168
+
169
+ json_data = nil
170
+ form_data = nil
171
+ multipart_data = nil
172
+ post_data_buffer = nil
173
+ if data
174
+ case data
175
+ when String
176
+ if headers_obj&.any? { |key, value| key.downcase == 'content-type' && value == 'application/json' }
177
+ json_data = data
178
+ else
179
+ post_data_buffer = data
180
+ end
181
+ when Hash, Array, Numeric, true, false
182
+ json_data = data
183
+ else
184
+ raise ArgumentError.new("Unsupported 'data' type: #{data.class}")
185
+ end
186
+ elsif form
187
+ form_data = object_to_array(form)
188
+ elsif multipart
189
+ multipart_data = multipart.map do |name, value|
190
+ if file_payload?(value)
191
+ { name: name, file: file_payload_to_json(value) }
192
+ else
193
+ { name: name, value: value.to_s }
194
+ end
195
+ end
196
+ end
197
+
198
+ if !json_data && !form_data && !multipart_data
199
+ post_data_buffer ||= request&.post_data_buffer
200
+ end
201
+ if post_data_buffer
202
+ fetch_params[:postData] = Base64.strict_encode64(post_data_buffer)
203
+ end
204
+
205
+ fetch_params[:jsonData] = json_data
206
+ fetch_params[:formData] = form_data
207
+ fetch_params[:multipartData] = multipart_data
208
+ fetch_params[:timeout] = timeout
209
+ fetch_params[:failOnStatusCode] = failOnStatusCode
210
+ fetch_params[:ignoreHTTPSErrors] = ignoreHTTPSErrors
211
+ fetch_params.compact!
212
+ response = @channel.send_message_to_server('fetch', fetch_params)
213
+
214
+ APIResponseImpl.new(self, response)
215
+ end
216
+
217
+ private def file_payload?(value)
218
+ value.is_a?(Hash) &&
219
+ %w(name mimeType buffer).all? { |key| value.has_key?(key) || value.has_key?(key.to_sym) }
220
+ end
221
+
222
+ private def file_payload_to_json(payload)
223
+ {
224
+ name: payload[:name] || payload['name'],
225
+ mimeType: payload[:mimeType] || payload['mimeType'],
226
+ buffer: Base64.strict_encode64(payload[:buffer] || payload['buffer'])
227
+ }
228
+ end
229
+
230
+ private def object_to_array(hash)
231
+ hash&.map do |key, value|
232
+ { name: key, value: value.to_s }
233
+ end
234
+ end
3
235
  end
4
236
  end
@@ -4,7 +4,7 @@ module Playwright
4
4
  include Utils::Errors::SafeCloseError
5
5
  attr_accessor :browser
6
6
  attr_writer :owner_page, :options
7
- attr_reader :tracing
7
+ attr_reader :tracing, :request
8
8
 
9
9
  private def after_initialize
10
10
  @pages = Set.new
@@ -15,6 +15,8 @@ module Playwright
15
15
  @background_pages = Set.new
16
16
 
17
17
  @tracing = TracingImpl.new(@channel, self)
18
+ @request = ChannelOwners::APIRequestContext.from(@initializer['APIRequestContext'])
19
+
18
20
  @channel.on('bindingCall', ->(params) { on_binding(ChannelOwners::BindingCall.from(params['binding'])) })
19
21
  @channel.once('close', ->(_) { on_close })
20
22
  @channel.on('page', ->(params) { on_page(ChannelOwners::Page.from(params['page']) )})
@@ -733,6 +733,10 @@ module Playwright
733
733
  @workers.to_a
734
734
  end
735
735
 
736
+ def request
737
+ @browser_context.request
738
+ end
739
+
736
740
  def pause
737
741
  @browser_context.send(:pause)
738
742
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playwright
4
- VERSION = '1.17.0'
5
- COMPATIBLE_PLAYWRIGHT_VERSION = '1.17.0'
4
+ VERSION = '1.17.1'
5
+ COMPATIBLE_PLAYWRIGHT_VERSION = '1.17.2'
6
6
  end
@@ -36,12 +36,6 @@ module Playwright
36
36
  end
37
37
  alias_method :default_timeout=, :set_default_timeout
38
38
 
39
- # -- inherited from EventEmitter --
40
- # @nodoc
41
- def off(event, callback)
42
- event_emitter_proxy.off(event, callback)
43
- end
44
-
45
39
  # -- inherited from EventEmitter --
46
40
  # @nodoc
47
41
  def once(event, callback)
@@ -54,6 +48,12 @@ module Playwright
54
48
  event_emitter_proxy.on(event, callback)
55
49
  end
56
50
 
51
+ # -- inherited from EventEmitter --
52
+ # @nodoc
53
+ def off(event, callback)
54
+ event_emitter_proxy.off(event, callback)
55
+ end
56
+
57
57
  private def event_emitter_proxy
58
58
  @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
59
59
  end