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
@@ -1,6 +1,6 @@
1
1
  module Playwright
2
2
  # The Touchscreen class operates in main-frame CSS pixels relative to the top-left corner of the viewport. Methods on the
3
- # touchscreen can only be used in browser contexts that have been intialized with `hasTouch` set to true.
3
+ # touchscreen can only be used in browser contexts that have been initialized with `hasTouch` set to true.
4
4
  class Touchscreen < PlaywrightApi
5
5
 
6
6
  # Dispatches a `touchstart` and `touchend` event with a single touch at the position (`x`,`y`).
@@ -11,5 +11,20 @@ module Playwright
11
11
  def url
12
12
  raise NotImplementedError.new('url is not implemented yet.')
13
13
  end
14
+
15
+ # Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
16
+ # value. Will throw an error if the webSocket is closed before the event is fired. Returns the event data value.
17
+ def expect_event(event, predicate: nil, timeout: nil)
18
+ raise NotImplementedError.new('expect_event is not implemented yet.')
19
+ end
20
+
21
+ # > NOTE: In most cases, you should use [`method: WebSocket.waitForEvent`].
22
+ #
23
+ # Waits for given `event` to fire. If predicate is provided, it passes event's value into the `predicate` function and
24
+ # waits for `predicate(event)` to return a truthy value. Will throw an error if the socket is closed before the `event` is
25
+ # fired.
26
+ def wait_for_event(event, predicate: nil, timeout: nil)
27
+ raise NotImplementedError.new('wait_for_event is not implemented yet.')
28
+ end
14
29
  end
15
30
  end
@@ -15,6 +15,16 @@ module Playwright
15
15
  # console.log(' ' + worker.url());
16
16
  # ```
17
17
  #
18
+ # ```java
19
+ # page.onWorker(worker -> {
20
+ # System.out.println("Worker created: " + worker.url());
21
+ # worker.onClose(worker1 -> System.out.println("Worker destroyed: " + worker1.url()));
22
+ # });
23
+ # System.out.println("Current workers:");
24
+ # for (Worker worker : page.workers())
25
+ # System.out.println(" " + worker.url());
26
+ # ```
27
+ #
18
28
  # ```py
19
29
  # def handle_worker(worker):
20
30
  # print("worker created: " + worker.url)
@@ -26,6 +36,20 @@ module Playwright
26
36
  # for worker in page.workers:
27
37
  # print(" " + worker.url)
28
38
  # ```
39
+ #
40
+ # ```csharp
41
+ # Page.Worker += (_, worker) =>
42
+ # {
43
+ # Console.WriteLine($"Worker created: {worker.Url}");
44
+ # worker.Close += (_, _) => Console.WriteLine($"Worker closed {worker.Url}");
45
+ # };
46
+ #
47
+ # Console.WriteLine("Current Workers:");
48
+ # foreach(var pageWorker in Page.Workers)
49
+ # {
50
+ # Console.WriteLine($"\tWorker: {pageWorker.Url}");
51
+ # }
52
+ # ```
29
53
  class Worker < PlaywrightApi
30
54
 
31
55
  # Returns the return value of `expression`.
@@ -34,7 +58,7 @@ module Playwright
34
58
  # wait for the promise to resolve and return its value.
35
59
  #
36
60
  # If the function passed to the [`method: Worker.evaluate`] returns a non-[Serializable] value, then
37
- # [`method: Worker.evaluate`] returns `undefined`. Playwright also supports transferring some additional values that are
61
+ # [`method: Worker.evaluate`] returns `undefined`. Playwright also supports transferring some additional values that are
38
62
  # not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`.
39
63
  def evaluate(expression, arg: nil)
40
64
  raise NotImplementedError.new('evaluate is not implemented yet.')
data/playwright.gemspec CHANGED
@@ -17,20 +17,22 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
19
19
  `git ls-files -z`.split("\x0").reject do |f|
20
- f.match(%r{^(test|spec|features)/}) || f.include?(".git") || f.start_with?("development/")
20
+ f.match(%r{^(test|spec|features)/}) || f.include?(".git") || f.include?(".circleci") || f.start_with?("development/")
21
21
  end
22
22
  end + `find lib/playwright_api -name *.rb -type f`.split("\n")
23
23
  spec.bindir = 'exe'
24
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
25
  spec.require_paths = ['lib']
26
26
 
27
- spec.add_dependency 'concurrent-ruby'
27
+ spec.add_dependency 'concurrent-ruby', '>= 1.1.6'
28
28
  spec.add_dependency 'mime-types', '>= 3.0'
29
29
  spec.add_development_dependency 'bundler', '~> 2.2.3'
30
+ spec.add_development_dependency 'chunky_png'
30
31
  spec.add_development_dependency 'dry-inflector'
31
32
  spec.add_development_dependency 'pry-byebug'
32
33
  spec.add_development_dependency 'rake', '~> 13.0.3'
33
34
  spec.add_development_dependency 'rspec', '~> 3.10.0 '
35
+ spec.add_development_dependency 'rspec_junit_formatter' # for CircleCI.
34
36
  spec.add_development_dependency 'rubocop', '~> 1.7.0'
35
37
  spec.add_development_dependency 'rubocop-rspec'
36
38
  spec.add_development_dependency 'sinatra'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: playwright-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-18 00:00:00.000000000 Z
11
+ date: 2021-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 1.1.6
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 1.1.6
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: mime-types
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 2.2.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: chunky_png
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: dry-inflector
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +122,20 @@ dependencies:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
124
  version: 3.10.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec_junit_formatter
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
111
139
  - !ruby/object:Gem::Dependency
112
140
  name: rubocop
113
141
  requirement: !ruby/object:Gem::Requirement
@@ -187,26 +215,26 @@ files:
187
215
  - lib/playwright/channel_owner.rb
188
216
  - lib/playwright/channel_owners/android.rb
189
217
  - lib/playwright/channel_owners/android_device.rb
218
+ - lib/playwright/channel_owners/artifact.rb
190
219
  - lib/playwright/channel_owners/binding_call.rb
191
220
  - lib/playwright/channel_owners/browser.rb
192
221
  - lib/playwright/channel_owners/browser_context.rb
193
222
  - lib/playwright/channel_owners/browser_type.rb
194
- - lib/playwright/channel_owners/chromium_browser.rb
195
- - lib/playwright/channel_owners/chromium_browser_context.rb
196
223
  - lib/playwright/channel_owners/console_message.rb
197
- - lib/playwright/channel_owners/download.rb
224
+ - lib/playwright/channel_owners/dialog.rb
198
225
  - lib/playwright/channel_owners/electron.rb
199
226
  - lib/playwright/channel_owners/element_handle.rb
200
- - lib/playwright/channel_owners/firefox_browser.rb
201
227
  - lib/playwright/channel_owners/frame.rb
202
228
  - lib/playwright/channel_owners/js_handle.rb
203
229
  - lib/playwright/channel_owners/page.rb
204
230
  - lib/playwright/channel_owners/playwright.rb
205
231
  - lib/playwright/channel_owners/request.rb
206
232
  - lib/playwright/channel_owners/response.rb
233
+ - lib/playwright/channel_owners/route.rb
207
234
  - lib/playwright/channel_owners/selectors.rb
208
- - lib/playwright/channel_owners/webkit_browser.rb
235
+ - lib/playwright/channel_owners/stream.rb
209
236
  - lib/playwright/connection.rb
237
+ - lib/playwright/download.rb
210
238
  - lib/playwright/errors.rb
211
239
  - lib/playwright/event_emitter.rb
212
240
  - lib/playwright/event_emitter_proxy.rb
@@ -222,6 +250,7 @@ files:
222
250
  - lib/playwright/keyboard_impl.rb
223
251
  - lib/playwright/mouse_impl.rb
224
252
  - lib/playwright/playwright_api.rb
253
+ - lib/playwright/route_handler_entry.rb
225
254
  - lib/playwright/select_option_values.rb
226
255
  - lib/playwright/timeout_settings.rb
227
256
  - lib/playwright/touchscreen_impl.rb
@@ -229,20 +258,20 @@ files:
229
258
  - lib/playwright/url_matcher.rb
230
259
  - lib/playwright/utils.rb
231
260
  - lib/playwright/version.rb
261
+ - lib/playwright/video.rb
232
262
  - lib/playwright/wait_helper.rb
233
263
  - lib/playwright_api/accessibility.rb
234
264
  - lib/playwright_api/android.rb
235
265
  - lib/playwright_api/android_device.rb
236
266
  - lib/playwright_api/android_input.rb
237
- - lib/playwright_api/binding_call.rb
267
+ - lib/playwright_api/android_socket.rb
268
+ - lib/playwright_api/android_web_view.rb
238
269
  - lib/playwright_api/browser.rb
239
270
  - lib/playwright_api/browser_context.rb
240
271
  - lib/playwright_api/browser_type.rb
241
272
  - lib/playwright_api/cdp_session.rb
242
- - lib/playwright_api/chromium_browser_context.rb
243
273
  - lib/playwright_api/console_message.rb
244
274
  - lib/playwright_api/dialog.rb
245
- - lib/playwright_api/download.rb
246
275
  - lib/playwright_api/element_handle.rb
247
276
  - lib/playwright_api/file_chooser.rb
248
277
  - lib/playwright_api/frame.rb
@@ -256,7 +285,6 @@ files:
256
285
  - lib/playwright_api/route.rb
257
286
  - lib/playwright_api/selectors.rb
258
287
  - lib/playwright_api/touchscreen.rb
259
- - lib/playwright_api/video.rb
260
288
  - lib/playwright_api/web_socket.rb
261
289
  - lib/playwright_api/worker.rb
262
290
  - playwright.gemspec
@@ -279,7 +307,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
279
307
  - !ruby/object:Gem::Version
280
308
  version: '0'
281
309
  requirements: []
282
- rubygems_version: 3.2.3
310
+ rubygems_version: 3.2.15
283
311
  signing_key:
284
312
  specification_version: 4
285
313
  summary: The Ruby binding of playwright driver
@@ -1,8 +0,0 @@
1
- require_relative './browser'
2
-
3
- module Playwright
4
- module ChannelOwners
5
- class ChromiumBrowser < Browser
6
- end
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- require_relative './browser_context'
2
-
3
- module Playwright
4
- module ChannelOwners
5
- class ChromiumBrowserContext < BrowserContext
6
- end
7
- end
8
- end
@@ -1,27 +0,0 @@
1
- module Playwright
2
- define_channel_owner :Download do
3
- def url
4
- @initializer['url']
5
- end
6
-
7
- def suggested_filename
8
- @initializer['suggestedFilename']
9
- end
10
-
11
- def delete
12
- @channel.send_message_to_server('delete')
13
- end
14
-
15
- def failure
16
- @channel.send_message_to_server('failure')
17
- end
18
-
19
- def path
20
- @channel.send_message_to_server('path')
21
- end
22
-
23
- def save_as(path)
24
- @channel.send_message_to_server('saveAs', path: path)
25
- end
26
- end
27
- end
@@ -1,8 +0,0 @@
1
- require_relative './browser'
2
-
3
- module Playwright
4
- module ChannelOwners
5
- class FirefoxBrowser < Browser
6
- end
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- require_relative './browser'
2
-
3
- module Playwright
4
- module ChannelOwners
5
- class WebKitBrowser < Browser
6
- end
7
- end
8
- end
@@ -1,27 +0,0 @@
1
- module Playwright
2
- # @nodoc
3
- class BindingCall < PlaywrightApi
4
-
5
- # -- inherited from EventEmitter --
6
- # @nodoc
7
- def once(event, callback)
8
- event_emitter_proxy.once(event, callback)
9
- end
10
-
11
- # -- inherited from EventEmitter --
12
- # @nodoc
13
- def on(event, callback)
14
- event_emitter_proxy.on(event, callback)
15
- end
16
-
17
- # -- inherited from EventEmitter --
18
- # @nodoc
19
- def off(event, callback)
20
- event_emitter_proxy.off(event, callback)
21
- end
22
-
23
- private def event_emitter_proxy
24
- @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
25
- end
26
- end
27
- end
@@ -1,59 +0,0 @@
1
- require_relative './browser_context.rb'
2
-
3
- module Playwright
4
- # - extends: `BrowserContext`
5
- #
6
- # Chromium-specific features including background pages, service worker support, etc.
7
- #
8
- #
9
- # ```js
10
- # const backgroundPage = await context.waitForEvent('backgroundpage');
11
- # ```
12
- #
13
- # ```python async
14
- # background_page = await context.wait_for_event("backgroundpage")
15
- # ```
16
- #
17
- # ```python sync
18
- # background_page = context.wait_for_event("backgroundpage")
19
- # ```
20
- class ChromiumBrowserContext < BrowserContext
21
-
22
- # All existing background pages in the context.
23
- def background_pages
24
- raise NotImplementedError.new('background_pages is not implemented yet.')
25
- end
26
-
27
- # Returns the newly created session.
28
- def new_cdp_session(page)
29
- raise NotImplementedError.new('new_cdp_session is not implemented yet.')
30
- end
31
-
32
- # All existing service workers in the context.
33
- def service_workers
34
- raise NotImplementedError.new('service_workers is not implemented yet.')
35
- end
36
-
37
- # -- inherited from EventEmitter --
38
- # @nodoc
39
- def once(event, callback)
40
- event_emitter_proxy.once(event, callback)
41
- end
42
-
43
- # -- inherited from EventEmitter --
44
- # @nodoc
45
- def on(event, callback)
46
- event_emitter_proxy.on(event, callback)
47
- end
48
-
49
- # -- inherited from EventEmitter --
50
- # @nodoc
51
- def off(event, callback)
52
- event_emitter_proxy.off(event, callback)
53
- end
54
-
55
- private def event_emitter_proxy
56
- @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
57
- end
58
- end
59
- end
@@ -1,100 +0,0 @@
1
- module Playwright
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
- #
7
- # Download event is emitted once the download starts. Download path becomes available once download completes:
8
- #
9
- #
10
- # ```js
11
- # const [ download ] = await Promise.all([
12
- # page.waitForEvent('download'), // wait for download to start
13
- # page.click('a')
14
- # ]);
15
- # // wait for download to complete
16
- # const path = await download.path();
17
- # ```
18
- #
19
- # ```python async
20
- # async with page.expect_download() as download_info:
21
- # await page.click("a")
22
- # download = await download_info.value
23
- # # waits for download to complete
24
- # path = await download.path()
25
- # ```
26
- #
27
- # ```python sync
28
- # with page.expect_download() as download_info:
29
- # page.click("a")
30
- # download = download_info.value
31
- # # wait for download to complete
32
- # path = download.path()
33
- # ```
34
- #
35
- # > NOTE: Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the
36
- # downloaded content. If `acceptDownloads` is not set, download events are emitted, but the actual download is not
37
- # performed and user has no access to the downloaded files.
38
- class Download < PlaywrightApi
39
-
40
- # Returns readable stream for current download or `null` if download failed.
41
- def create_read_stream
42
- raise NotImplementedError.new('create_read_stream is not implemented yet.')
43
- end
44
-
45
- # Deletes the downloaded file.
46
- def delete
47
- wrap_impl(@impl.delete)
48
- end
49
-
50
- # Returns download error if any.
51
- def failure
52
- wrap_impl(@impl.failure)
53
- end
54
-
55
- # Returns path to the downloaded file in case of successful download.
56
- def path
57
- wrap_impl(@impl.path)
58
- end
59
-
60
- # Saves the download to a user-specified path.
61
- def save_as(path)
62
- wrap_impl(@impl.save_as(unwrap_impl(path)))
63
- end
64
-
65
- # Returns suggested filename for this download. It is typically computed by the browser from the
66
- # [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) response header
67
- # or the `download` attribute. See the spec on [whatwg](https://html.spec.whatwg.org/#downloading-resources). Different
68
- # browsers can use different logic for computing it.
69
- def suggested_filename
70
- wrap_impl(@impl.suggested_filename)
71
- end
72
-
73
- # Returns downloaded url.
74
- def url
75
- wrap_impl(@impl.url)
76
- end
77
-
78
- # -- inherited from EventEmitter --
79
- # @nodoc
80
- def once(event, callback)
81
- event_emitter_proxy.once(event, callback)
82
- end
83
-
84
- # -- inherited from EventEmitter --
85
- # @nodoc
86
- def on(event, callback)
87
- event_emitter_proxy.on(event, callback)
88
- end
89
-
90
- # -- inherited from EventEmitter --
91
- # @nodoc
92
- def off(event, callback)
93
- event_emitter_proxy.off(event, callback)
94
- end
95
-
96
- private def event_emitter_proxy
97
- @event_emitter_proxy ||= EventEmitterProxy.new(self, @impl)
98
- end
99
- end
100
- end