playwright-ruby-client 0.2.0 → 0.5.4
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.
- checksums.yaml +4 -4
- data/README.md +17 -5
- data/docs/api_coverage.md +116 -74
- data/lib/playwright.rb +48 -9
- data/lib/playwright/channel.rb +12 -2
- data/lib/playwright/channel_owners/artifact.rb +30 -0
- data/lib/playwright/channel_owners/binding_call.rb +3 -0
- data/lib/playwright/channel_owners/browser.rb +21 -0
- data/lib/playwright/channel_owners/browser_context.rb +154 -3
- data/lib/playwright/channel_owners/browser_type.rb +28 -0
- data/lib/playwright/channel_owners/dialog.rb +28 -0
- data/lib/playwright/channel_owners/element_handle.rb +6 -4
- data/lib/playwright/channel_owners/frame.rb +25 -2
- data/lib/playwright/channel_owners/js_handle.rb +2 -2
- data/lib/playwright/channel_owners/page.rb +141 -25
- data/lib/playwright/channel_owners/playwright.rb +24 -27
- data/lib/playwright/channel_owners/request.rb +26 -2
- data/lib/playwright/channel_owners/response.rb +60 -0
- data/lib/playwright/channel_owners/route.rb +78 -0
- data/lib/playwright/channel_owners/selectors.rb +19 -1
- data/lib/playwright/channel_owners/stream.rb +15 -0
- data/lib/playwright/connection.rb +11 -32
- data/lib/playwright/download.rb +27 -0
- data/lib/playwright/errors.rb +6 -0
- data/lib/playwright/events.rb +2 -5
- data/lib/playwright/keyboard_impl.rb +1 -1
- data/lib/playwright/mouse_impl.rb +41 -0
- data/lib/playwright/playwright_api.rb +3 -1
- data/lib/playwright/route_handler_entry.rb +28 -0
- data/lib/playwright/transport.rb +29 -7
- data/lib/playwright/url_matcher.rb +1 -1
- data/lib/playwright/utils.rb +9 -0
- data/lib/playwright/version.rb +1 -1
- data/lib/playwright/video.rb +51 -0
- data/lib/playwright/wait_helper.rb +2 -2
- data/lib/playwright_api/accessibility.rb +39 -1
- data/lib/playwright_api/android.rb +74 -2
- data/lib/playwright_api/android_device.rb +141 -23
- data/lib/playwright_api/android_input.rb +17 -13
- data/lib/playwright_api/android_socket.rb +16 -0
- data/lib/playwright_api/android_web_view.rb +21 -0
- data/lib/playwright_api/browser.rb +77 -2
- data/lib/playwright_api/browser_context.rb +182 -29
- data/lib/playwright_api/browser_type.rb +40 -9
- data/lib/playwright_api/dialog.rb +54 -7
- data/lib/playwright_api/element_handle.rb +105 -31
- data/lib/playwright_api/file_chooser.rb +6 -1
- data/lib/playwright_api/frame.rb +229 -36
- data/lib/playwright_api/js_handle.rb +23 -0
- data/lib/playwright_api/keyboard.rb +48 -1
- data/lib/playwright_api/mouse.rb +26 -5
- data/lib/playwright_api/page.rb +491 -81
- data/lib/playwright_api/playwright.rb +21 -4
- data/lib/playwright_api/request.rb +30 -2
- data/lib/playwright_api/response.rb +21 -11
- data/lib/playwright_api/route.rb +51 -5
- data/lib/playwright_api/selectors.rb +27 -1
- data/lib/playwright_api/touchscreen.rb +1 -1
- data/lib/playwright_api/worker.rb +25 -1
- data/playwright.gemspec +4 -2
- metadata +42 -14
- data/lib/playwright/channel_owners/chromium_browser.rb +0 -8
- data/lib/playwright/channel_owners/chromium_browser_context.rb +0 -8
- data/lib/playwright/channel_owners/download.rb +0 -27
- data/lib/playwright/channel_owners/firefox_browser.rb +0 -8
- data/lib/playwright/channel_owners/webkit_browser.rb +0 -8
- data/lib/playwright_api/binding_call.rb +0 -27
- data/lib/playwright_api/chromium_browser_context.rb +0 -59
- data/lib/playwright_api/download.rb +0 -95
- data/lib/playwright_api/video.rb +0 -24
@@ -3,5 +3,46 @@ module Playwright
|
|
3
3
|
def initialize(channel)
|
4
4
|
@channel = channel
|
5
5
|
end
|
6
|
+
|
7
|
+
def move(x, y, steps: nil)
|
8
|
+
params = { x: x, y: y, steps: steps }.compact
|
9
|
+
@channel.send_message_to_server('mouseMove', params)
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def down(button: nil, clickCount: nil)
|
14
|
+
params = { button: button, clickCount: clickCount }.compact
|
15
|
+
@channel.send_message_to_server('mouseDown', params)
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def up(button: nil, clickCount: nil)
|
20
|
+
params = { button: button, clickCount: clickCount }.compact
|
21
|
+
@channel.send_message_to_server('mouseUp', params)
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def click(
|
26
|
+
x,
|
27
|
+
y,
|
28
|
+
button: nil,
|
29
|
+
clickCount: nil,
|
30
|
+
delay: nil)
|
31
|
+
|
32
|
+
params = {
|
33
|
+
x: x,
|
34
|
+
y: y,
|
35
|
+
button: button,
|
36
|
+
clickCount: clickCount,
|
37
|
+
delay: delay,
|
38
|
+
}.compact
|
39
|
+
@channel.send_message_to_server('mouseClick', params)
|
40
|
+
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def dblclick(x, y, button: nil, delay: nil)
|
45
|
+
click(x, y, button: button, clickCount: 2, delay: delay)
|
46
|
+
end
|
6
47
|
end
|
7
48
|
end
|
@@ -124,7 +124,9 @@ module Playwright
|
|
124
124
|
end
|
125
125
|
|
126
126
|
private def unwrap_impl(object)
|
127
|
-
if object.is_a?(
|
127
|
+
if object.is_a?(Array)
|
128
|
+
object.map { |obj| unwrap_impl(obj) }
|
129
|
+
elsif object.is_a?(PlaywrightApi)
|
128
130
|
object.instance_variable_get(:@impl)
|
129
131
|
else
|
130
132
|
object
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Playwright
|
2
|
+
class RouteHandlerEntry
|
3
|
+
# @param url [String]
|
4
|
+
# @param handler [Proc]
|
5
|
+
def initialize(url, handler)
|
6
|
+
@url_value = url
|
7
|
+
@url_matcher = UrlMatcher.new(url)
|
8
|
+
@handler = handler
|
9
|
+
end
|
10
|
+
|
11
|
+
def handle(route, request)
|
12
|
+
if @url_matcher.match?(request.url)
|
13
|
+
@handler.call(route, request)
|
14
|
+
true
|
15
|
+
else
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def same_value?(url:, handler: nil)
|
21
|
+
if handler
|
22
|
+
@url_value == url && @handler == handler
|
23
|
+
else
|
24
|
+
@url_value == url
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/playwright/transport.rb
CHANGED
@@ -12,39 +12,46 @@ module Playwright
|
|
12
12
|
def initialize(playwright_cli_executable_path:)
|
13
13
|
@driver_executable_path = playwright_cli_executable_path
|
14
14
|
@debug = ENV['DEBUG'].to_s == 'true' || ENV['DEBUG'].to_s == '1'
|
15
|
+
@mutex = Mutex.new
|
15
16
|
end
|
16
17
|
|
17
18
|
def on_message_received(&block)
|
18
19
|
@on_message = block
|
19
20
|
end
|
20
21
|
|
22
|
+
def on_driver_crashed(&block)
|
23
|
+
@on_driver_crashed = block
|
24
|
+
end
|
25
|
+
|
21
26
|
class AlreadyDisconnectedError < StandardError ; end
|
22
27
|
|
23
28
|
# @param message [Hash]
|
24
29
|
def send_message(message)
|
25
30
|
debug_send_message(message) if @debug
|
26
31
|
msg = JSON.dump(message)
|
27
|
-
@
|
28
|
-
|
29
|
-
|
32
|
+
@mutex.synchronize {
|
33
|
+
@stdin.write([msg.bytes.length].pack('V')) # unsigned 32bit, little endian, real byte size instead of chars
|
34
|
+
@stdin.write(msg) # write UTF-8 in binary mode as byte stream
|
35
|
+
}
|
36
|
+
rescue Errno::EPIPE, IOError
|
30
37
|
raise AlreadyDisconnectedError.new('send_message failed')
|
31
38
|
end
|
32
39
|
|
33
40
|
# Terminate playwright-cli driver.
|
34
41
|
def stop
|
35
42
|
[@stdin, @stdout, @stderr].each { |io| io.close unless io.closed? }
|
43
|
+
@thread&.terminate
|
36
44
|
end
|
37
45
|
|
38
46
|
# Start `playwright-cli run-driver`
|
39
47
|
#
|
40
48
|
# @note This method blocks until playwright-cli exited. Consider using Thread or Future.
|
41
|
-
def
|
42
|
-
@stdin, @stdout, @stderr, @thread = Open3.popen3(@driver_executable_path
|
49
|
+
def async_run
|
50
|
+
@stdin, @stdout, @stderr, @thread = Open3.popen3("#{@driver_executable_path} run-driver")
|
51
|
+
@stdin.binmode # Ensure Strings are written 1:1 without encoding conversion, necessary for integer values
|
43
52
|
|
44
53
|
Thread.new { handle_stdout }
|
45
54
|
Thread.new { handle_stderr }
|
46
|
-
|
47
|
-
@thread.join
|
48
55
|
end
|
49
56
|
|
50
57
|
private
|
@@ -69,6 +76,21 @@ module Playwright
|
|
69
76
|
|
70
77
|
def handle_stderr
|
71
78
|
while err = @stderr.read
|
79
|
+
# sometimed driver crashes with the error below.
|
80
|
+
# --------
|
81
|
+
# undefined:1
|
82
|
+
# �
|
83
|
+
# ^
|
84
|
+
|
85
|
+
# SyntaxError: Unexpected token � in JSON at position 0
|
86
|
+
# at JSON.parse (<anonymous>)
|
87
|
+
# at Transport.transport.onmessage (/home/runner/work/playwright-ruby-client/playwright-ruby-client/node_modules/playwright/lib/cli/driver.js:42:73)
|
88
|
+
# at Immediate.<anonymous> (/home/runner/work/playwright-ruby-client/playwright-ruby-client/node_modules/playwright/lib/protocol/transport.js:74:26)
|
89
|
+
# at processImmediate (internal/timers.js:461:21)
|
90
|
+
if err.include?('undefined:1')
|
91
|
+
@on_driver_crashed&.call
|
92
|
+
break
|
93
|
+
end
|
72
94
|
$stderr.write(err)
|
73
95
|
end
|
74
96
|
rescue IOError
|
data/lib/playwright/utils.rb
CHANGED
@@ -3,6 +3,7 @@ module Playwright
|
|
3
3
|
module PrepareBrowserContextOptions
|
4
4
|
# @see https://github.com/microsoft/playwright/blob/5a2cfdbd47ed3c3deff77bb73e5fac34241f649d/src/client/browserContext.ts#L265
|
5
5
|
private def prepare_browser_context_options(params)
|
6
|
+
params[:sdkLanguage] = 'ruby'
|
6
7
|
if params[:noViewport] == 0
|
7
8
|
params.delete(:noViewport)
|
8
9
|
params[:noDefaultViewport] = true
|
@@ -10,6 +11,14 @@ module Playwright
|
|
10
11
|
if params[:extraHTTPHeaders]
|
11
12
|
params[:extraHTTPHeaders] = ::Playwright::HttpHeaders.new(params[:extraHTTPHeaders]).as_serialized
|
12
13
|
end
|
14
|
+
if params[:record_video_dir]
|
15
|
+
params[:recordVideo] = {
|
16
|
+
dir: params.delete(:record_video_dir)
|
17
|
+
}
|
18
|
+
if params[:record_video_size]
|
19
|
+
params[:recordVideo][:size] = params.delete(:record_video_size)
|
20
|
+
end
|
21
|
+
end
|
13
22
|
if params[:storageState].is_a?(String)
|
14
23
|
params[:storageState] = JSON.parse(File.read(params[:storageState]))
|
15
24
|
end
|
data/lib/playwright/version.rb
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Playwright
|
2
|
+
class Video
|
3
|
+
def initialize(page)
|
4
|
+
@page = page
|
5
|
+
@artifact = Concurrent::Promises.resolvable_future
|
6
|
+
if @page.closed?
|
7
|
+
on_page_closed
|
8
|
+
else
|
9
|
+
page.once('close', -> { on_page_closed })
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private def on_page_closed
|
14
|
+
unless @artifact.resolved?
|
15
|
+
@artifact.reject('Page closed')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# called only from Page#on_video via send(:set_artifact, artifact)
|
20
|
+
private def set_artifact(artifact)
|
21
|
+
@artifact.fulfill(artifact)
|
22
|
+
end
|
23
|
+
|
24
|
+
def path
|
25
|
+
wait_for_artifact_and do |artifact|
|
26
|
+
artifact.absolute_path
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def save_as(path)
|
31
|
+
wait_for_artifact_and do |artifact|
|
32
|
+
artifact.save_as(path)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete
|
37
|
+
wait_for_artifact_and do |artifact|
|
38
|
+
artifact.delete
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private def wait_for_artifact_and(&block)
|
43
|
+
artifact = @artifact.value!
|
44
|
+
unless artifact
|
45
|
+
raise 'Page did not produce any video frames'
|
46
|
+
end
|
47
|
+
|
48
|
+
block.call(artifact)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -22,9 +22,9 @@ module Playwright
|
|
22
22
|
def reject_on_timeout(timeout_ms, message)
|
23
23
|
return if timeout_ms <= 0
|
24
24
|
|
25
|
-
Concurrent::Promises.schedule(timeout_ms / 1000.0)
|
25
|
+
Concurrent::Promises.schedule(timeout_ms / 1000.0) do
|
26
26
|
reject(TimeoutError.new(message: message))
|
27
|
-
|
27
|
+
end
|
28
28
|
|
29
29
|
self
|
30
30
|
end
|
@@ -6,7 +6,7 @@ module Playwright
|
|
6
6
|
# Accessibility is a very platform-specific thing. On different platforms, there are different screen readers that might
|
7
7
|
# have wildly different output.
|
8
8
|
#
|
9
|
-
# Rendering engines of Chromium, Firefox and
|
9
|
+
# Rendering engines of Chromium, Firefox and WebKit have a concept of "accessibility tree", which is then translated into
|
10
10
|
# different platform-specific APIs. Accessibility namespace gives access to this Accessibility Tree.
|
11
11
|
#
|
12
12
|
# Most of the accessibility tree gets filtered out when converting from internal browser AX Tree to Platform-specific
|
@@ -28,6 +28,11 @@ module Playwright
|
|
28
28
|
# console.log(snapshot);
|
29
29
|
# ```
|
30
30
|
#
|
31
|
+
# ```java
|
32
|
+
# String snapshot = page.accessibility().snapshot();
|
33
|
+
# System.out.println(snapshot);
|
34
|
+
# ```
|
35
|
+
#
|
31
36
|
# ```python async
|
32
37
|
# snapshot = await page.accessibility.snapshot()
|
33
38
|
# print(snapshot)
|
@@ -38,6 +43,11 @@ module Playwright
|
|
38
43
|
# print(snapshot)
|
39
44
|
# ```
|
40
45
|
#
|
46
|
+
# ```csharp
|
47
|
+
# var accessibilitySnapshot = await Page.Accessibility.SnapshotAsync();
|
48
|
+
# Console.WriteLine(accessibilitySnapshot);
|
49
|
+
# ```
|
50
|
+
#
|
41
51
|
# An example of logging the focused node's name:
|
42
52
|
#
|
43
53
|
#
|
@@ -57,6 +67,34 @@ module Playwright
|
|
57
67
|
# }
|
58
68
|
# ```
|
59
69
|
#
|
70
|
+
# ```csharp
|
71
|
+
# Func<AccessibilitySnapshotResult, AccessibilitySnapshotResult> findFocusedNode = root =>
|
72
|
+
# {
|
73
|
+
# var nodes = new Stack<AccessibilitySnapshotResult>(new[] { root });
|
74
|
+
# while (nodes.Count > 0)
|
75
|
+
# {
|
76
|
+
# var node = nodes.Pop();
|
77
|
+
# if (node.Focused) return node;
|
78
|
+
# foreach (var innerNode in node.Children)
|
79
|
+
# {
|
80
|
+
# nodes.Push(innerNode);
|
81
|
+
# }
|
82
|
+
# }
|
83
|
+
#
|
84
|
+
# return null;
|
85
|
+
# };
|
86
|
+
#
|
87
|
+
# var accessibilitySnapshot = await Page.Accessibility.SnapshotAsync();
|
88
|
+
# var focusedNode = findFocusedNode(accessibilitySnapshot);
|
89
|
+
# if(focusedNode != null)
|
90
|
+
# Console.WriteLine(focusedNode.Name);
|
91
|
+
# ```
|
92
|
+
#
|
93
|
+
# ```java
|
94
|
+
# // FIXME
|
95
|
+
# String snapshot = page.accessibility().snapshot();
|
96
|
+
# ```
|
97
|
+
#
|
60
98
|
# ```python async
|
61
99
|
# def find_focused_node(node):
|
62
100
|
# if (node.get("focused"))
|
@@ -1,12 +1,84 @@
|
|
1
1
|
module Playwright
|
2
|
-
#
|
2
|
+
# Playwright has **experimental** support for Android automation. You can access android namespace via:
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# ```js
|
6
|
+
# const { _android: android } = require('playwright');
|
7
|
+
# ```
|
8
|
+
#
|
9
|
+
# An example of the Android automation script would be:
|
10
|
+
#
|
11
|
+
#
|
12
|
+
# ```js
|
13
|
+
# const { _android: android } = require('playwright');
|
14
|
+
#
|
15
|
+
# (async () => {
|
16
|
+
# // Connect to the device.
|
17
|
+
# const [device] = await android.devices();
|
18
|
+
# console.log(`Model: ${device.model()}`);
|
19
|
+
# console.log(`Serial: ${device.serial()}`);
|
20
|
+
# // Take screenshot of the whole device.
|
21
|
+
# await device.screenshot({ path: 'device.png' });
|
22
|
+
#
|
23
|
+
# {
|
24
|
+
# // --------------------- WebView -----------------------
|
25
|
+
#
|
26
|
+
# // Launch an application with WebView.
|
27
|
+
# await device.shell('am force-stop org.chromium.webview_shell');
|
28
|
+
# await device.shell('am start org.chromium.webview_shell/.WebViewBrowserActivity');
|
29
|
+
# // Get the WebView.
|
30
|
+
# const webview = await device.webView({ pkg: 'org.chromium.webview_shell' });
|
31
|
+
#
|
32
|
+
# // Fill the input box.
|
33
|
+
# await device.fill({ res: 'org.chromium.webview_shell:id/url_field' }, 'github.com/microsoft/playwright');
|
34
|
+
# await device.press({ res: 'org.chromium.webview_shell:id/url_field' }, 'Enter');
|
35
|
+
#
|
36
|
+
# // Work with WebView's page as usual.
|
37
|
+
# const page = await webview.page();
|
38
|
+
# await page.waitForNavigation({ url: /.*microsoft\/playwright.*/ });
|
39
|
+
# console.log(await page.title());
|
40
|
+
# }
|
41
|
+
#
|
42
|
+
# {
|
43
|
+
# // --------------------- Browser -----------------------
|
44
|
+
#
|
45
|
+
# // Launch Chrome browser.
|
46
|
+
# await device.shell('am force-stop com.android.chrome');
|
47
|
+
# const context = await device.launchBrowser();
|
48
|
+
#
|
49
|
+
# // Use BrowserContext as usual.
|
50
|
+
# const page = await context.newPage();
|
51
|
+
# await page.goto('https://webkit.org/');
|
52
|
+
# console.log(await page.evaluate(() => window.location.href));
|
53
|
+
# await page.screenshot({ path: 'page.png' });
|
54
|
+
#
|
55
|
+
# await context.close();
|
56
|
+
# }
|
57
|
+
#
|
58
|
+
# // Close the device.
|
59
|
+
# await device.close();
|
60
|
+
# })();
|
61
|
+
# ```
|
62
|
+
#
|
63
|
+
# Note that since you don't need Playwright to install web browsers when testing Android, you can omit browser download
|
64
|
+
# via setting the following environment variable when installing Playwright:
|
65
|
+
#
|
66
|
+
# ```sh js
|
67
|
+
# $ PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm i -D playwright
|
68
|
+
# ```
|
3
69
|
class Android < PlaywrightApi
|
4
70
|
|
5
|
-
#
|
71
|
+
# Returns the list of detected Android devices.
|
6
72
|
def devices
|
7
73
|
wrap_impl(@impl.devices)
|
8
74
|
end
|
9
75
|
|
76
|
+
# This setting will change the default maximum time for all the methods accepting `timeout` option.
|
77
|
+
def set_default_timeout(timeout)
|
78
|
+
raise NotImplementedError.new('set_default_timeout is not implemented yet.')
|
79
|
+
end
|
80
|
+
alias_method :default_timeout=, :set_default_timeout
|
81
|
+
|
10
82
|
# -- inherited from EventEmitter --
|
11
83
|
# @nodoc
|
12
84
|
def once(event, callback)
|
@@ -1,55 +1,173 @@
|
|
1
1
|
module Playwright
|
2
|
-
#
|
2
|
+
# `AndroidDevice` represents a connected device, either real hardware or emulated. Devices can be obtained using
|
3
|
+
# [`method: Android.devices`].
|
3
4
|
class AndroidDevice < PlaywrightApi
|
4
5
|
|
5
|
-
#
|
6
|
-
|
7
|
-
wrap_impl(@impl.tree)
|
6
|
+
def input # property
|
7
|
+
wrap_impl(@impl.input)
|
8
8
|
end
|
9
9
|
|
10
|
-
#
|
10
|
+
# Disconnects from the device.
|
11
11
|
def close
|
12
12
|
wrap_impl(@impl.close)
|
13
13
|
end
|
14
14
|
|
15
|
-
#
|
16
|
-
def
|
17
|
-
|
15
|
+
# Drags the widget defined by `selector` towards `dest` point.
|
16
|
+
def drag(selector, dest, speed: nil)
|
17
|
+
raise NotImplementedError.new('drag is not implemented yet.')
|
18
18
|
end
|
19
19
|
|
20
|
-
#
|
20
|
+
# Fills the specific `selector` input box with `text`.
|
21
|
+
def fill(selector, text)
|
22
|
+
raise NotImplementedError.new('fill is not implemented yet.')
|
23
|
+
end
|
24
|
+
|
25
|
+
# Flings the widget defined by `selector` in the specified `direction`.
|
26
|
+
def fling(selector, direction, speed: nil)
|
27
|
+
raise NotImplementedError.new('fling is not implemented yet.')
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns information about a widget defined by `selector`.
|
31
|
+
def info(selector)
|
32
|
+
wrap_impl(@impl.info(unwrap_impl(selector)))
|
33
|
+
end
|
34
|
+
|
35
|
+
# Installs an apk on the device.
|
36
|
+
def install_apk(file, args: nil)
|
37
|
+
raise NotImplementedError.new('install_apk is not implemented yet.')
|
38
|
+
end
|
39
|
+
|
40
|
+
# Launches Chrome browser on the device, and returns its persistent context.
|
41
|
+
def launch_browser(
|
42
|
+
acceptDownloads: nil,
|
43
|
+
bypassCSP: nil,
|
44
|
+
colorScheme: nil,
|
45
|
+
command: nil,
|
46
|
+
deviceScaleFactor: nil,
|
47
|
+
extraHTTPHeaders: nil,
|
48
|
+
geolocation: nil,
|
49
|
+
hasTouch: nil,
|
50
|
+
httpCredentials: nil,
|
51
|
+
ignoreHTTPSErrors: nil,
|
52
|
+
isMobile: nil,
|
53
|
+
javaScriptEnabled: nil,
|
54
|
+
locale: nil,
|
55
|
+
noViewport: nil,
|
56
|
+
offline: nil,
|
57
|
+
permissions: nil,
|
58
|
+
record_har_omit_content: nil,
|
59
|
+
record_har_path: nil,
|
60
|
+
record_video_dir: nil,
|
61
|
+
record_video_size: nil,
|
62
|
+
screen: nil,
|
63
|
+
timezoneId: nil,
|
64
|
+
userAgent: nil,
|
65
|
+
viewport: nil,
|
66
|
+
&block)
|
67
|
+
wrap_impl(@impl.launch_browser(acceptDownloads: unwrap_impl(acceptDownloads), bypassCSP: unwrap_impl(bypassCSP), colorScheme: unwrap_impl(colorScheme), command: unwrap_impl(command), deviceScaleFactor: unwrap_impl(deviceScaleFactor), extraHTTPHeaders: unwrap_impl(extraHTTPHeaders), geolocation: unwrap_impl(geolocation), hasTouch: unwrap_impl(hasTouch), httpCredentials: unwrap_impl(httpCredentials), ignoreHTTPSErrors: unwrap_impl(ignoreHTTPSErrors), isMobile: unwrap_impl(isMobile), javaScriptEnabled: unwrap_impl(javaScriptEnabled), locale: unwrap_impl(locale), noViewport: unwrap_impl(noViewport), offline: unwrap_impl(offline), permissions: unwrap_impl(permissions), record_har_omit_content: unwrap_impl(record_har_omit_content), record_har_path: unwrap_impl(record_har_path), record_video_dir: unwrap_impl(record_video_dir), record_video_size: unwrap_impl(record_video_size), screen: unwrap_impl(screen), timezoneId: unwrap_impl(timezoneId), userAgent: unwrap_impl(userAgent), viewport: unwrap_impl(viewport), &wrap_block_call(block)))
|
68
|
+
end
|
69
|
+
|
70
|
+
# Performs a long tap on the widget defined by `selector`.
|
71
|
+
def long_tap(selector)
|
72
|
+
raise NotImplementedError.new('long_tap is not implemented yet.')
|
73
|
+
end
|
74
|
+
|
75
|
+
# Device model.
|
76
|
+
def model
|
77
|
+
wrap_impl(@impl.model)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Launches a process in the shell on the device and returns a socket to communicate with the launched process.
|
81
|
+
def open(command)
|
82
|
+
raise NotImplementedError.new('open is not implemented yet.')
|
83
|
+
end
|
84
|
+
|
85
|
+
# Pinches the widget defined by `selector` in the closing direction.
|
86
|
+
def pinch_close(selector, percent, speed: nil)
|
87
|
+
raise NotImplementedError.new('pinch_close is not implemented yet.')
|
88
|
+
end
|
89
|
+
|
90
|
+
# Pinches the widget defined by `selector` in the open direction.
|
91
|
+
def pinch_open(selector, percent, speed: nil)
|
92
|
+
raise NotImplementedError.new('pinch_open is not implemented yet.')
|
93
|
+
end
|
94
|
+
|
95
|
+
# Presses the specific `key` in the widget defined by `selector`.
|
96
|
+
def press(selector, key)
|
97
|
+
raise NotImplementedError.new('press is not implemented yet.')
|
98
|
+
end
|
99
|
+
|
100
|
+
# Copies a file to the device.
|
101
|
+
def push(file, path, mode: nil)
|
102
|
+
raise NotImplementedError.new('push is not implemented yet.')
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns the buffer with the captured screenshot of the device.
|
21
106
|
def screenshot(path: nil)
|
22
107
|
wrap_impl(@impl.screenshot(path: unwrap_impl(path)))
|
23
108
|
end
|
24
109
|
|
25
|
-
#
|
110
|
+
# Scrolls the widget defined by `selector` in the specified `direction`.
|
111
|
+
def scroll(selector, direction, percent, speed: nil)
|
112
|
+
raise NotImplementedError.new('scroll is not implemented yet.')
|
113
|
+
end
|
114
|
+
|
115
|
+
# Device serial number.
|
116
|
+
def serial
|
117
|
+
wrap_impl(@impl.serial)
|
118
|
+
end
|
119
|
+
|
120
|
+
# This setting will change the default maximum time for all the methods accepting `timeout` option.
|
121
|
+
def set_default_timeout(timeout)
|
122
|
+
raise NotImplementedError.new('set_default_timeout is not implemented yet.')
|
123
|
+
end
|
124
|
+
alias_method :default_timeout=, :set_default_timeout
|
125
|
+
|
126
|
+
# Executes a shell command on the device and returns its output.
|
26
127
|
def shell(command)
|
27
128
|
wrap_impl(@impl.shell(unwrap_impl(command)))
|
28
129
|
end
|
29
130
|
|
30
|
-
#
|
31
|
-
def
|
32
|
-
|
131
|
+
# Swipes the widget defined by `selector` in the specified `direction`.
|
132
|
+
def swipe(selector, direction, percent, speed: nil)
|
133
|
+
raise NotImplementedError.new('swipe is not implemented yet.')
|
33
134
|
end
|
34
135
|
|
35
|
-
#
|
36
|
-
def
|
37
|
-
|
136
|
+
# Taps on the widget defined by `selector`.
|
137
|
+
def tap_point(selector, duration: nil)
|
138
|
+
raise NotImplementedError.new('tap_point is not implemented yet.')
|
38
139
|
end
|
39
140
|
|
40
|
-
#
|
41
|
-
def
|
42
|
-
|
141
|
+
# Waits for the specific `selector` to either appear or disappear, depending on the `state`.
|
142
|
+
def wait(selector, state: nil)
|
143
|
+
raise NotImplementedError.new('wait is not implemented yet.')
|
144
|
+
end
|
145
|
+
|
146
|
+
# Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
|
147
|
+
# value.
|
148
|
+
def wait_for_event(event, optionsOrPredicate: nil)
|
149
|
+
raise NotImplementedError.new('wait_for_event is not implemented yet.')
|
150
|
+
end
|
151
|
+
|
152
|
+
# This method waits until `AndroidWebView` matching the `selector` is opened and returns it. If there is already an open
|
153
|
+
# `AndroidWebView` matching the `selector`, returns immediately.
|
154
|
+
def web_view(selector)
|
155
|
+
raise NotImplementedError.new('web_view is not implemented yet.')
|
156
|
+
end
|
157
|
+
|
158
|
+
# Currently open WebViews.
|
159
|
+
def web_views
|
160
|
+
raise NotImplementedError.new('web_views is not implemented yet.')
|
43
161
|
end
|
44
162
|
|
45
163
|
# @nodoc
|
46
|
-
def
|
47
|
-
wrap_impl(@impl.
|
164
|
+
def tap_on(selector, duration: nil, timeout: nil)
|
165
|
+
wrap_impl(@impl.tap_on(unwrap_impl(selector), duration: unwrap_impl(duration), timeout: unwrap_impl(timeout)))
|
48
166
|
end
|
49
167
|
|
50
168
|
# @nodoc
|
51
|
-
def
|
52
|
-
wrap_impl(@impl.
|
169
|
+
def tree
|
170
|
+
wrap_impl(@impl.tree)
|
53
171
|
end
|
54
172
|
|
55
173
|
# -- inherited from EventEmitter --
|