async-webdriver 0.10.0 → 0.11.0
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
- checksums.yaml.gz.sig +0 -0
- data/context/navigation-timing.md +2 -2
- data/lib/async/webdriver/bridge/chrome.rb +7 -1
- data/lib/async/webdriver/bridge/driver.rb +10 -0
- data/lib/async/webdriver/bridge/firefox.rb +7 -0
- data/lib/async/webdriver/bridge/generic.rb +3 -0
- data/lib/async/webdriver/bridge/pool.rb +30 -0
- data/lib/async/webdriver/bridge/process_group.rb +5 -0
- data/lib/async/webdriver/bridge/safari.rb +6 -0
- data/lib/async/webdriver/bridge.rb +4 -0
- data/lib/async/webdriver/element.rb +2 -0
- data/lib/async/webdriver/error.rb +1 -0
- data/lib/async/webdriver/scope/printing.rb +37 -5
- data/lib/async/webdriver/scope/window.rb +50 -0
- data/lib/async/webdriver/scope.rb +9 -0
- data/lib/async/webdriver/session.rb +2 -0
- data/lib/async/webdriver/version.rb +3 -1
- data/readme.md +21 -0
- data/releases.md +5 -0
- data.tar.gz.sig +0 -0
- metadata +4 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9a70af1593c116227ab4863c4e209bb4002faf9bdfe18e7183b0656811b83066
|
|
4
|
+
data.tar.gz: 64ca1a5125e4a8289f2d55b6a6fe8b6e8579ae1b0b9ffd139bcc407d22a4702a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e9770cacf231cf999256001afb4e53a6c8d2dbbe5ea34f9d67974651ba8c2d04ff7ce0984aa083dfe15895d63ec7c2265de7d6d919e9571a4e7cd11a8f65cc6a
|
|
7
|
+
data.tar.gz: f775e069001ebbf3a52a4d909e8734242c039410c218142c44cd1973921af1f6490098debd3be854dbd214e017908e277d4a6a5f6c1585393254cacce3992d97
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -84,7 +84,7 @@ The most reliable approach is to use `wait_for_navigation` to wait for the URL o
|
|
|
84
84
|
```ruby
|
|
85
85
|
# ✅ RELIABLE: Wait for URL change
|
|
86
86
|
session.click_button("Submit")
|
|
87
|
-
session.wait_for_navigation
|
|
87
|
+
session.wait_for_navigation{|url| url.end_with?("/success")}
|
|
88
88
|
session.navigate_to("/next-page") # Now safe
|
|
89
89
|
```
|
|
90
90
|
|
|
@@ -96,7 +96,7 @@ For critical operations like authentication, wait for server-side effects to com
|
|
|
96
96
|
# ✅ RELIABLE: Wait for authentication cookie
|
|
97
97
|
session.click_button("Login")
|
|
98
98
|
session.wait_for_navigation do |url, ready_state|
|
|
99
|
-
|
|
99
|
+
ready_state == "complete" && session.cookies.any?{|cookie| cookie["name"] == "auth_token"}
|
|
100
100
|
end
|
|
101
101
|
session.navigate_to("/dashboard") # Now safe
|
|
102
102
|
```
|
|
@@ -20,6 +20,7 @@ module Async
|
|
|
20
20
|
# end
|
|
21
21
|
# ```
|
|
22
22
|
class Chrome < Generic
|
|
23
|
+
# @returns [String] The path to the `chromedriver` executable.
|
|
23
24
|
def path
|
|
24
25
|
@options.fetch(:path, "chromedriver")
|
|
25
26
|
end
|
|
@@ -33,7 +34,10 @@ module Async
|
|
|
33
34
|
return nil
|
|
34
35
|
end
|
|
35
36
|
|
|
37
|
+
# A locally managed `chromedriver` process.
|
|
36
38
|
class Driver < Bridge::Driver
|
|
39
|
+
# Initialize a managed Chrome driver process.
|
|
40
|
+
# @parameter options [Hash] Driver configuration options.
|
|
37
41
|
def initialize(**options)
|
|
38
42
|
super(**options)
|
|
39
43
|
@process_group = nil
|
|
@@ -47,12 +51,14 @@ module Async
|
|
|
47
51
|
].compact
|
|
48
52
|
end
|
|
49
53
|
|
|
54
|
+
# Start the managed Chrome driver process and wait for readiness.
|
|
50
55
|
def start
|
|
51
56
|
@process_group = ProcessGroup.spawn(*arguments(**@options))
|
|
52
57
|
|
|
53
58
|
super
|
|
54
59
|
end
|
|
55
60
|
|
|
61
|
+
# Stop the managed Chrome driver process.
|
|
56
62
|
def close
|
|
57
63
|
if @process_group
|
|
58
64
|
@process_group.close
|
|
@@ -76,7 +82,7 @@ module Async
|
|
|
76
82
|
alwaysMatch: {
|
|
77
83
|
browserName: "chrome",
|
|
78
84
|
"goog:chromeOptions": {
|
|
79
|
-
args: [headless ? "--headless" : nil].compact,
|
|
85
|
+
args: [headless ? "--headless=new" : nil].compact,
|
|
80
86
|
},
|
|
81
87
|
webSocketUrl: true,
|
|
82
88
|
},
|
|
@@ -8,12 +8,15 @@ module Async
|
|
|
8
8
|
module Bridge
|
|
9
9
|
# Represents an instance of a locally running driver (usually with a process group).
|
|
10
10
|
class Driver
|
|
11
|
+
# Initialize a driver wrapper.
|
|
12
|
+
# @parameter options [Hash] Driver configuration options.
|
|
11
13
|
def initialize(**options)
|
|
12
14
|
@options = options
|
|
13
15
|
@count = 0
|
|
14
16
|
@closed = false
|
|
15
17
|
end
|
|
16
18
|
|
|
19
|
+
# @returns [Integer] The number of concurrent sessions the driver can sustain.
|
|
17
20
|
def concurrency
|
|
18
21
|
@options.fetch(:concurrency, 128)
|
|
19
22
|
end
|
|
@@ -23,18 +26,22 @@ module Async
|
|
|
23
26
|
# @attribute [Hash] The status of the driver after a connection has been established.
|
|
24
27
|
attr :status
|
|
25
28
|
|
|
29
|
+
# @returns [Boolean] Whether the driver can still be used.
|
|
26
30
|
def viable?
|
|
27
31
|
!@closed
|
|
28
32
|
end
|
|
29
33
|
|
|
34
|
+
# @returns [Boolean] Whether the driver has been closed.
|
|
30
35
|
def closed?
|
|
31
36
|
@closed
|
|
32
37
|
end
|
|
33
38
|
|
|
39
|
+
# Mark the driver as closed.
|
|
34
40
|
def close
|
|
35
41
|
@closed = true
|
|
36
42
|
end
|
|
37
43
|
|
|
44
|
+
# @returns [Boolean] Whether the driver may be returned to a pool.
|
|
38
45
|
def reusable?
|
|
39
46
|
@options.fetch(:reusable, !@closed)
|
|
40
47
|
end
|
|
@@ -50,14 +57,17 @@ module Async
|
|
|
50
57
|
end
|
|
51
58
|
end
|
|
52
59
|
|
|
60
|
+
# @returns [Integer] The port the driver listens on.
|
|
53
61
|
def port
|
|
54
62
|
@port ||= @options.fetch(:port, self.ephemeral_port)
|
|
55
63
|
end
|
|
56
64
|
|
|
65
|
+
# @returns [Async::HTTP::Endpoint] The HTTP endpoint exposed by the driver.
|
|
57
66
|
def endpoint
|
|
58
67
|
Async::HTTP::Endpoint.parse("http://localhost", port: self.port)
|
|
59
68
|
end
|
|
60
69
|
|
|
70
|
+
# @returns [Client] A client connected to the driver endpoint.
|
|
61
71
|
def client
|
|
62
72
|
Client.open(self.endpoint)
|
|
63
73
|
end
|
|
@@ -19,6 +19,7 @@ module Async
|
|
|
19
19
|
# bridge&.close
|
|
20
20
|
# end
|
|
21
21
|
class Firefox < Generic
|
|
22
|
+
# @returns [String] The path to the `geckodriver` executable.
|
|
22
23
|
def path
|
|
23
24
|
@options.fetch(:path, "geckodriver")
|
|
24
25
|
end
|
|
@@ -32,12 +33,16 @@ module Async
|
|
|
32
33
|
return nil
|
|
33
34
|
end
|
|
34
35
|
|
|
36
|
+
# A locally managed `geckodriver` process.
|
|
35
37
|
class Driver < Bridge::Driver
|
|
38
|
+
# Initialize a managed Firefox driver process.
|
|
39
|
+
# @parameter options [Hash] Driver configuration options.
|
|
36
40
|
def initialize(**options)
|
|
37
41
|
super(**options)
|
|
38
42
|
@process_group = nil
|
|
39
43
|
end
|
|
40
44
|
|
|
45
|
+
# @returns [Integer] Firefox drivers support one session at a time.
|
|
41
46
|
def concurrency
|
|
42
47
|
1
|
|
43
48
|
end
|
|
@@ -50,12 +55,14 @@ module Async
|
|
|
50
55
|
].compact
|
|
51
56
|
end
|
|
52
57
|
|
|
58
|
+
# Start the managed Firefox driver process and wait for readiness.
|
|
53
59
|
def start
|
|
54
60
|
@process_group = ProcessGroup.spawn(*arguments(**@options))
|
|
55
61
|
|
|
56
62
|
super
|
|
57
63
|
end
|
|
58
64
|
|
|
65
|
+
# Stop the managed Firefox driver process.
|
|
59
66
|
def close
|
|
60
67
|
if @process_group
|
|
61
68
|
@process_group.close
|
|
@@ -12,6 +12,8 @@ module Async
|
|
|
12
12
|
module Bridge
|
|
13
13
|
# Generic W3C WebDriver implementation.
|
|
14
14
|
class Generic
|
|
15
|
+
# Initialize a generic bridge wrapper.
|
|
16
|
+
# @parameter options [Hash] Bridge configuration options.
|
|
15
17
|
def initialize(**options)
|
|
16
18
|
@options = options
|
|
17
19
|
end
|
|
@@ -26,6 +28,7 @@ module Async
|
|
|
26
28
|
version != nil
|
|
27
29
|
end
|
|
28
30
|
|
|
31
|
+
# @returns [Boolean] Whether headless mode is enabled by default.
|
|
29
32
|
def headless?
|
|
30
33
|
@options.fetch(:headless, true)
|
|
31
34
|
end
|
|
@@ -24,14 +24,22 @@ module Async
|
|
|
24
24
|
# end
|
|
25
25
|
# ```
|
|
26
26
|
class Pool
|
|
27
|
+
# Controls pooled drivers and cached sessions.
|
|
27
28
|
class BridgeController
|
|
29
|
+
# Initialize the bridge controller.
|
|
30
|
+
# @parameter bridge [Bridge] The bridge used to create drivers.
|
|
31
|
+
# @parameter capabilities [Hash] Capabilities used for new sessions.
|
|
28
32
|
def initialize(bridge, capabilities: bridge.default_capabilities)
|
|
29
33
|
@bridge = bridge
|
|
30
34
|
@capabilities = capabilities
|
|
31
35
|
@pool = Async::Pool::Controller.new(self)
|
|
32
36
|
end
|
|
33
37
|
|
|
38
|
+
# Caches sessions created from a single driver instance.
|
|
34
39
|
class SessionCache
|
|
40
|
+
# Initialize a session cache for one driver instance.
|
|
41
|
+
# @parameter driver [Driver] The driver backing cached sessions.
|
|
42
|
+
# @parameter capabilities [Hash] Capabilities for newly created sessions.
|
|
35
43
|
def initialize(driver, capabilities)
|
|
36
44
|
@driver = driver
|
|
37
45
|
@capabilities = capabilities
|
|
@@ -40,14 +48,17 @@ module Async
|
|
|
40
48
|
@sessions = []
|
|
41
49
|
end
|
|
42
50
|
|
|
51
|
+
# @returns [Boolean] Whether the underlying driver remains usable.
|
|
43
52
|
def viable?
|
|
44
53
|
@driver&.viable?
|
|
45
54
|
end
|
|
46
55
|
|
|
56
|
+
# @returns [Boolean] Whether cached sessions may be reused.
|
|
47
57
|
def reusable?
|
|
48
58
|
@driver&.reusable?
|
|
49
59
|
end
|
|
50
60
|
|
|
61
|
+
# Close the cached sessions, driver, and HTTP client.
|
|
51
62
|
def close
|
|
52
63
|
if @driver
|
|
53
64
|
@driver.close
|
|
@@ -64,10 +75,13 @@ module Async
|
|
|
64
75
|
end
|
|
65
76
|
end
|
|
66
77
|
|
|
78
|
+
# @returns [Integer] The number of concurrently usable sessions.
|
|
67
79
|
def concurrency
|
|
68
80
|
@driver.concurrency
|
|
69
81
|
end
|
|
70
82
|
|
|
83
|
+
# Acquire a cached or newly created session payload.
|
|
84
|
+
# @returns [Hash] A WebDriver session payload.
|
|
71
85
|
def acquire
|
|
72
86
|
if @sessions.empty?
|
|
73
87
|
session = @client.post("session", {capabilities: @capabilities})
|
|
@@ -85,6 +99,8 @@ module Async
|
|
|
85
99
|
end
|
|
86
100
|
end
|
|
87
101
|
|
|
102
|
+
# Return a session payload to the cache.
|
|
103
|
+
# @parameter session [Hash] The session payload to cache.
|
|
88
104
|
def release(session)
|
|
89
105
|
@sessions.push(session)
|
|
90
106
|
end
|
|
@@ -95,12 +111,16 @@ module Async
|
|
|
95
111
|
SessionCache.new(@bridge.start, @capabilities)
|
|
96
112
|
end
|
|
97
113
|
|
|
114
|
+
# Acquire a session payload from the pool.
|
|
115
|
+
# @returns [Hash] The acquired session payload.
|
|
98
116
|
def acquire
|
|
99
117
|
session_cache = @pool.acquire
|
|
100
118
|
|
|
101
119
|
return session_cache.acquire
|
|
102
120
|
end
|
|
103
121
|
|
|
122
|
+
# Return a session payload to the pool.
|
|
123
|
+
# @parameter session [Hash] The session payload to release.
|
|
104
124
|
def release(session)
|
|
105
125
|
session_cache = session[:cache]
|
|
106
126
|
|
|
@@ -109,6 +129,8 @@ module Async
|
|
|
109
129
|
@pool.release(session_cache)
|
|
110
130
|
end
|
|
111
131
|
|
|
132
|
+
# Retire a session payload and its cache from the pool.
|
|
133
|
+
# @parameter session [Hash] The session payload to retire.
|
|
112
134
|
def retire(session)
|
|
113
135
|
session_cache = session[:cache]
|
|
114
136
|
|
|
@@ -117,6 +139,7 @@ module Async
|
|
|
117
139
|
@pool.retire(session_cache)
|
|
118
140
|
end
|
|
119
141
|
|
|
142
|
+
# Close the underlying driver pool.
|
|
120
143
|
def close
|
|
121
144
|
if @pool
|
|
122
145
|
@pool.close
|
|
@@ -136,15 +159,19 @@ module Async
|
|
|
136
159
|
@controller.close
|
|
137
160
|
end
|
|
138
161
|
|
|
162
|
+
# A pooled session wrapper that returns sessions to the cache on close.
|
|
139
163
|
class CachedWrapper < Session
|
|
164
|
+
# @returns [Pool] The pool responsible for reusing this session.
|
|
140
165
|
def pool
|
|
141
166
|
@options[:pool]
|
|
142
167
|
end
|
|
143
168
|
|
|
169
|
+
# @returns [Hash] The raw session payload returned by the bridge.
|
|
144
170
|
def payload
|
|
145
171
|
@options[:payload]
|
|
146
172
|
end
|
|
147
173
|
|
|
174
|
+
# Return the session to the pool when possible.
|
|
148
175
|
def close
|
|
149
176
|
unless self.pool.reuse(self)
|
|
150
177
|
super
|
|
@@ -167,6 +194,9 @@ module Async
|
|
|
167
194
|
end
|
|
168
195
|
end
|
|
169
196
|
|
|
197
|
+
# Reset and return a session to the pool.
|
|
198
|
+
# @parameter session [CachedWrapper] The session to reuse.
|
|
199
|
+
# @returns [Boolean] Always returns `true` once the session is released.
|
|
170
200
|
def reuse(session)
|
|
171
201
|
session.reset!
|
|
172
202
|
|
|
@@ -75,13 +75,18 @@ module Async
|
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
+
# A driver wrapper that closes an associated process handle.
|
|
78
79
|
class ProcessDriver < Driver
|
|
80
|
+
# Initialize a process-backed driver.
|
|
81
|
+
# @parameter endpoint [Object] Driver options or endpoint information.
|
|
82
|
+
# @parameter process [ProcessGroup] The managed process group.
|
|
79
83
|
def initialize(endpoint, process)
|
|
80
84
|
super(endpoint)
|
|
81
85
|
|
|
82
86
|
@process = process
|
|
83
87
|
end
|
|
84
88
|
|
|
89
|
+
# Close the driver and its process group.
|
|
85
90
|
def close
|
|
86
91
|
super
|
|
87
92
|
|
|
@@ -20,6 +20,7 @@ module Async
|
|
|
20
20
|
# end
|
|
21
21
|
# ```
|
|
22
22
|
class Safari < Generic
|
|
23
|
+
# @returns [String] The path to the `safaridriver` executable.
|
|
23
24
|
def path
|
|
24
25
|
@options.fetch(:path, "safaridriver")
|
|
25
26
|
end
|
|
@@ -33,7 +34,10 @@ module Async
|
|
|
33
34
|
return nil
|
|
34
35
|
end
|
|
35
36
|
|
|
37
|
+
# A locally managed `safaridriver` process.
|
|
36
38
|
class Driver < Bridge::Driver
|
|
39
|
+
# Initialize a managed Safari driver process.
|
|
40
|
+
# @parameter options [Hash] Driver configuration options.
|
|
37
41
|
def initialize(**options)
|
|
38
42
|
super(**options)
|
|
39
43
|
@process_group = nil
|
|
@@ -47,12 +51,14 @@ module Async
|
|
|
47
51
|
].compact
|
|
48
52
|
end
|
|
49
53
|
|
|
54
|
+
# Start the managed Safari driver process and wait for readiness.
|
|
50
55
|
def start
|
|
51
56
|
@process_group = ProcessGroup.spawn(*arguments(**@options))
|
|
52
57
|
|
|
53
58
|
super
|
|
54
59
|
end
|
|
55
60
|
|
|
61
|
+
# Stop the managed Safari driver process.
|
|
56
62
|
def close
|
|
57
63
|
if @process_group
|
|
58
64
|
@process_group.close
|
|
@@ -21,6 +21,9 @@ module Async
|
|
|
21
21
|
Bridge::Safari,
|
|
22
22
|
]
|
|
23
23
|
|
|
24
|
+
# Iterate over supported bridge implementations.
|
|
25
|
+
# @yields {|bridge| ...} Each supported bridge class.
|
|
26
|
+
# @parameter bridge [Class] A supported bridge implementation.
|
|
24
27
|
def self.each(&block)
|
|
25
28
|
return enum_for(:each) unless block_given?
|
|
26
29
|
|
|
@@ -45,6 +48,7 @@ module Async
|
|
|
45
48
|
# ```
|
|
46
49
|
ASYNC_WEBDRIVER_BRIDGE_HEADLESS = "ASYNC_WEBDRIVER_BRIDGE_HEADLESS"
|
|
47
50
|
|
|
51
|
+
# Raised when no supported bridge implementation is available.
|
|
48
52
|
class UnsupportedError < Error
|
|
49
53
|
end
|
|
50
54
|
|
|
@@ -8,13 +8,45 @@ require "base64"
|
|
|
8
8
|
module Async
|
|
9
9
|
module WebDriver
|
|
10
10
|
module Scope
|
|
11
|
-
# Helpers for
|
|
11
|
+
# Helpers for printing the current page to PDF.
|
|
12
12
|
module Printing
|
|
13
|
-
# Print the current page
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
# Print the current page as a PDF and return the raw binary data.
|
|
14
|
+
#
|
|
15
|
+
# All margin and page measurements are in centimetres. The W3C WebDriver
|
|
16
|
+
# default page size is US Letter (21.59 × 27.94 cm) with 1 cm margins.
|
|
17
|
+
#
|
|
18
|
+
# @parameter orientation [String | Nil] `"portrait"` or `"landscape"`. Default: `"portrait"`.
|
|
19
|
+
# @parameter scale [Float | Nil] Scaling factor between 0.1 and 2.0. Default: `1.0`.
|
|
20
|
+
# @parameter background [Boolean | Nil] Whether to print background graphics and colours. Default: `false`.
|
|
21
|
+
# @parameter page [Hash | Nil] Page dimensions in cm. Keys: `:width`, `:height`.
|
|
22
|
+
# @parameter margin [Hash | Nil] Page margins in cm. Keys: `:top`, `:bottom`, `:left`, `:right`.
|
|
23
|
+
# @parameter page_ranges [Array(String) | Nil] Page ranges to print, e.g. `["1-5", "8"]`. Default: all pages.
|
|
24
|
+
# @parameter shrink_to_fit [Boolean | Nil] Whether to shrink content to fit the page. Default: `true`.
|
|
25
|
+
# @returns [String] The raw PDF binary data.
|
|
26
|
+
def print(orientation: nil, scale: nil, background: nil, page: nil, margin: nil, page_ranges: nil, shrink_to_fit: nil)
|
|
27
|
+
parameters = {
|
|
28
|
+
orientation: orientation,
|
|
29
|
+
scale: scale,
|
|
30
|
+
background: background,
|
|
31
|
+
page: page,
|
|
32
|
+
margin: margin,
|
|
33
|
+
pageRanges: page_ranges,
|
|
34
|
+
shrinkToFit: shrink_to_fit,
|
|
35
|
+
}.compact
|
|
16
36
|
|
|
17
|
-
|
|
37
|
+
# Synchronise with Chrome's rendering pipeline before issuing the print
|
|
38
|
+
# command. The underlying CDP call (Page.printToPDF) is synchronous: if
|
|
39
|
+
# the renderer process has not yet fully initialised its print pipeline
|
|
40
|
+
# by the time the command arrives, Chrome returns JSON-RPC error -32000
|
|
41
|
+
# ("Printing failed") with no retry. A JavaScript round-trip forces
|
|
42
|
+
# ChromeDriver to wait for the renderer to be live (a JS execution
|
|
43
|
+
# context must exist), which also guarantees the print pipeline is ready.
|
|
44
|
+
# Without this, fast-loading pages can trigger the race intermittently.
|
|
45
|
+
session.execute("return document.readyState")
|
|
46
|
+
|
|
47
|
+
reply = session.post("print", parameters)
|
|
48
|
+
|
|
49
|
+
return Base64.decode64(reply)
|
|
18
50
|
end
|
|
19
51
|
end
|
|
20
52
|
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2023-2025, by Samuel Williams.
|
|
5
|
+
|
|
6
|
+
module Async
|
|
7
|
+
module WebDriver
|
|
8
|
+
module Scope
|
|
9
|
+
# Helpers for managing the browser window size and position.
|
|
10
|
+
module Window
|
|
11
|
+
# Get the current window rect (position and size).
|
|
12
|
+
# @returns [Hash] The window rect with keys `"x"`, `"y"`, `"width"`, `"height"`.
|
|
13
|
+
def window_rect
|
|
14
|
+
session.get("window/rect")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Set the window rect (position and/or size).
|
|
18
|
+
# @parameter x [Integer | Nil] The x position of the window.
|
|
19
|
+
# @parameter y [Integer | Nil] The y position of the window.
|
|
20
|
+
# @parameter width [Integer | Nil] The width of the window in CSS pixels.
|
|
21
|
+
# @parameter height [Integer | Nil] The height of the window in CSS pixels.
|
|
22
|
+
def set_window_rect(x: nil, y: nil, width: nil, height: nil)
|
|
23
|
+
session.post("window/rect", {x: x, y: y, width: width, height: height}.compact)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Resize the browser window to the given dimensions.
|
|
27
|
+
# @parameter width [Integer] The new width in CSS pixels.
|
|
28
|
+
# @parameter height [Integer] The new height in CSS pixels.
|
|
29
|
+
def resize_window(width, height)
|
|
30
|
+
set_window_rect(width: width, height: height)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Maximize the browser window.
|
|
34
|
+
def maximize_window
|
|
35
|
+
session.post("window/maximize")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Minimize the browser window.
|
|
39
|
+
def minimize_window
|
|
40
|
+
session.post("window/minimize")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Make the browser window fullscreen.
|
|
44
|
+
def fullscreen_window
|
|
45
|
+
session.post("window/fullscreen")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -13,3 +13,12 @@ require_relative "scope/navigation"
|
|
|
13
13
|
require_relative "scope/printing"
|
|
14
14
|
require_relative "scope/screen_capture"
|
|
15
15
|
require_relative "scope/timeouts"
|
|
16
|
+
require_relative "scope/window"
|
|
17
|
+
|
|
18
|
+
module Async
|
|
19
|
+
module WebDriver
|
|
20
|
+
# @namespace
|
|
21
|
+
module Scope
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -56,6 +56,7 @@ module Async
|
|
|
56
56
|
@options = options
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
+
# @returns [String] A concise representation of the session.
|
|
59
60
|
def inspect
|
|
60
61
|
"\#<#{self.class} id=#{@id.inspect}>"
|
|
61
62
|
end
|
|
@@ -126,6 +127,7 @@ module Async
|
|
|
126
127
|
include Scope::Printing
|
|
127
128
|
include Scope::ScreenCapture
|
|
128
129
|
include Scope::Timeouts
|
|
130
|
+
include Scope::Window
|
|
129
131
|
|
|
130
132
|
# Reset the session to a clean state.
|
|
131
133
|
def reset!
|
data/readme.md
CHANGED
|
@@ -28,6 +28,11 @@ Please see the [project documentation](https://socketry.github.io/async-webdrive
|
|
|
28
28
|
|
|
29
29
|
Please see the [project releases](https://socketry.github.io/async-webdriver/releases/index) for all releases.
|
|
30
30
|
|
|
31
|
+
### v0.11.0
|
|
32
|
+
|
|
33
|
+
- Add `Scope::Window` with `#window_rect`, `#resize_window`, `#set_window_rect`, `#maximize_window`, `#minimize_window`, and `#fullscreen_window`.
|
|
34
|
+
- Expand `Scope::Printing#print` with full W3C WebDriver parameters: `orientation`, `scale`, `background`, `page`, `margin`, `page_ranges`, and `shrink_to_fit`.
|
|
35
|
+
|
|
31
36
|
### v0.10.0
|
|
32
37
|
|
|
33
38
|
- Introduce `Scope#wait_for_navigation` to properly wait for page navigations to complete.
|
|
@@ -55,6 +60,22 @@ We welcome contributions to this project.
|
|
|
55
60
|
4. Push to the branch (`git push origin my-new-feature`).
|
|
56
61
|
5. Create new Pull Request.
|
|
57
62
|
|
|
63
|
+
### Running Tests
|
|
64
|
+
|
|
65
|
+
To run the test suite:
|
|
66
|
+
|
|
67
|
+
``` shell
|
|
68
|
+
bundle exec sus
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Making Releases
|
|
72
|
+
|
|
73
|
+
To make a new release:
|
|
74
|
+
|
|
75
|
+
``` shell
|
|
76
|
+
bundle exec bake gem:release:patch # or minor or major
|
|
77
|
+
```
|
|
78
|
+
|
|
58
79
|
### Developer Certificate of Origin
|
|
59
80
|
|
|
60
81
|
In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
|
data/releases.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
+
## v0.11.0
|
|
4
|
+
|
|
5
|
+
- Add `Scope::Window` with `#window_rect`, `#resize_window`, `#set_window_rect`, `#maximize_window`, `#minimize_window`, and `#fullscreen_window`.
|
|
6
|
+
- Expand `Scope::Printing#print` with full W3C WebDriver parameters: `orientation`, `scale`, `background`, `page`, `margin`, `page_ranges`, and `shrink_to_fit`.
|
|
7
|
+
|
|
3
8
|
## v0.10.0
|
|
4
9
|
|
|
5
10
|
- Introduce `Scope#wait_for_navigation` to properly wait for page navigations to complete.
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: async-webdriver
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -143,6 +143,7 @@ files:
|
|
|
143
143
|
- lib/async/webdriver/scope/printing.rb
|
|
144
144
|
- lib/async/webdriver/scope/screen_capture.rb
|
|
145
145
|
- lib/async/webdriver/scope/timeouts.rb
|
|
146
|
+
- lib/async/webdriver/scope/window.rb
|
|
146
147
|
- lib/async/webdriver/session.rb
|
|
147
148
|
- lib/async/webdriver/version.rb
|
|
148
149
|
- lib/async/webdriver/xpath.rb
|
|
@@ -163,14 +164,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
163
164
|
requirements:
|
|
164
165
|
- - ">="
|
|
165
166
|
- !ruby/object:Gem::Version
|
|
166
|
-
version: '3.
|
|
167
|
+
version: '3.3'
|
|
167
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
169
|
requirements:
|
|
169
170
|
- - ">="
|
|
170
171
|
- !ruby/object:Gem::Version
|
|
171
172
|
version: '0'
|
|
172
173
|
requirements: []
|
|
173
|
-
rubygems_version:
|
|
174
|
+
rubygems_version: 4.0.6
|
|
174
175
|
specification_version: 4
|
|
175
176
|
summary: A native library implementing the W3C WebDriver client specification.
|
|
176
177
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|