async-webdriver 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee23c04114676fa39b6838b560ad843f0d011e8c89ac1de1038c66c2f7bd5e26
4
- data.tar.gz: aa95efc428c3cdfcb362c8a9f6fbc80aaa4cec6258630adb2f057479ba051537
3
+ metadata.gz: 8a6324ffc2dfcde7982396b2dbda22df843948de94ba4e61811a777b64156a05
4
+ data.tar.gz: 25cc350a2093f0bc1651500139bb654c5ed0af2f8ac553ecbc5d3544691e9999
5
5
  SHA512:
6
- metadata.gz: bf32864d5c72d2529151f4de5f1f72d6e4a5a3731d0598e49df758d97371f176ec34504d9922d6f56499855c9d21726fb7fba641b08c19f2ae084960a35ec90f
7
- data.tar.gz: 67f0fd5bdba22e79cba73c2db37e69da65ddc3dc22a8603584a59d1cae158902ac1ca501a7d80304683e56f831aa621ca852acd3b31079c4c7a2b19d2a36711c
6
+ metadata.gz: 4a39e3446f54eeb665252c3cb7f76bcdf5b6dc8ba0fcc8e67f0570d5e93f783e77e833cb499211562e26f922fbe14f507a6e7645cbe45c5f7c9af921e3c4f9b7
7
+ data.tar.gz: 0205a411504dac570476a891f849542d337f9cf1d44b4462811e3bfdc006b24f3eddd338c27822f7119a9467676cad6f17efdb30c57ddd14ceaf4e15537066d6
checksums.yaml.gz.sig CHANGED
Binary file
@@ -91,7 +91,25 @@ module Async
91
91
 
92
92
  reply = @sessions.pop
93
93
 
94
- Session.open(@bridge.endpoint, reply["sessionId"], reply["capabilities"], &block)
94
+ session = Session.open(@bridge.endpoint, reply["sessionId"], reply["capabilities"])
95
+
96
+ return session unless block_given?
97
+
98
+ begin
99
+ yield session
100
+
101
+ # Try to reuse the session for extreme performance:
102
+ reuse(session)
103
+ session = nil
104
+ ensure
105
+ session&.close
106
+ end
107
+ end
108
+
109
+ def reuse(session)
110
+ session.reset!
111
+
112
+ @sessions << {"sessionId" => session.id, "capabilities" => session.capabilities}
95
113
  end
96
114
  end
97
115
  end
@@ -114,13 +114,6 @@ module Async
114
114
  self
115
115
  end
116
116
 
117
- include Scope::Alerts
118
- include Scope::Cookies
119
- include Scope::Elements
120
- include Scope::Fields
121
- include Scope::Printing
122
- include Scope::ScreenCapture
123
-
124
117
  # Execute a script in the context of the element. `this` will be the element.
125
118
  # @parameter script [String] The script to execute.
126
119
  # @parameter arguments [Array] The arguments to pass to the script.
@@ -135,6 +128,13 @@ module Async
135
128
  @session.execute_async("return (function(){#{script}}).call(...arguments)", self, *arguments)
136
129
  end
137
130
 
131
+ include Scope::Alerts
132
+ include Scope::Cookies
133
+ include Scope::Elements
134
+ include Scope::Fields
135
+ include Scope::Printing
136
+ include Scope::ScreenCapture
137
+
138
138
  # Get the value of an attribute.
139
139
  #
140
140
  # Given an attribute name, e.g. `href`, this method will return the value of the attribute, as if you had executed the following JavaScript:
@@ -10,30 +10,14 @@ module Async
10
10
  module Document
11
11
  # Get the current document title.
12
12
  # @returns [String] The document title.
13
- def title
14
- get("title")
13
+ def document_title
14
+ session.get("title")
15
15
  end
16
16
 
17
17
  # Get the current document source.
18
18
  # @returns [String] The document source.
19
- def source
20
- get("source")
21
- end
22
-
23
- # Execute a script in the current document.
24
- # @parameter script [String] The script to execute.
25
- # @parameter arguments [Array] The arguments to pass to the script.
26
- # @returns [Object] The result of the script.
27
- def execute(script, *arguments)
28
- post("execute/sync", {script: script, args: arguments})
29
- end
30
-
31
- # Execute a script in the current document asynchronously.
32
- # @parameter script [String] The script to execute.
33
- # @parameter arguments [Array] The arguments to pass to the script.
34
- # @returns [Object] The result of the script.
35
- def execute_async(script, *arguments)
36
- post("execute/async", {script: script, args: arguments})
19
+ def document_source
20
+ session.get("source")
37
21
  end
38
22
  end
39
23
  end
@@ -97,6 +97,22 @@ module Async
97
97
  self
98
98
  end
99
99
 
100
+ # Execute a script in the current document.
101
+ # @parameter script [String] The script to execute.
102
+ # @parameter arguments [Array] The arguments to pass to the script.
103
+ # @returns [Object] The result of the script.
104
+ def execute(script, *arguments)
105
+ post("execute/sync", {script: script, args: arguments})
106
+ end
107
+
108
+ # Execute a script in the current document asynchronously.
109
+ # @parameter script [String] The script to execute.
110
+ # @parameter arguments [Array] The arguments to pass to the script.
111
+ # @returns [Object] The result of the script.
112
+ def execute_async(script, *arguments)
113
+ post("execute/async", {script: script, args: arguments})
114
+ end
115
+
100
116
  include Scope::Alerts
101
117
  include Scope::Cookies
102
118
  include Scope::Document
@@ -107,6 +123,19 @@ module Async
107
123
  include Scope::Printing
108
124
  include Scope::ScreenCapture
109
125
  include Scope::Timeouts
126
+
127
+ # Reset the session to a clean state.
128
+ def reset!
129
+ # Go to a blank page (in theory this should also invalidate any Element instances):
130
+ self.navigate_to("about:blank")
131
+
132
+ # Clear cookies and local storage:
133
+ self.delete_all_cookies
134
+ self.execute("localStorage.clear();")
135
+
136
+ # Detach the session instance from the underlying HTTP client:
137
+ @delegate = nil
138
+ end
110
139
  end
111
140
  end
112
141
  end
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Async
7
7
  module WebDriver
8
- VERSION = "0.2.0"
8
+ VERSION = "0.3.0"
9
9
  end
10
10
  end
data/readme.md CHANGED
@@ -8,7 +8,7 @@ Provides a client implementation of the W3C WebDriver specification with support
8
8
 
9
9
  In the past, I've used [selenium-webdriver](https://github.com/SeleniumHQ/selenium) for testing web applications. However, I found it to be slow. I wanted to improve the performance of my tests, so I decided to write a new implementation from scratch. The W3C WebDriver specification is quite simple, so it wasn't too difficult to implement, and I was able to get a significant performance improvement, between 2x-10x depending on the usage. Specifically, most test suites can take advantage of pre-warmed sessions, which can minimise the overhead of each test running in a new session. Additionally, I'd like to explore reusing sessions between tests, which could provide even more performance improvements.
10
10
 
11
- In addition, building on top of [async](https://github.com/socketry/async) allows us to take advantage of [async-http](https://github.com/socketry/async-http) running in the same reactor, which can provide a significant performance improvement over the existing HTTP servers like [capybara](https://github.com/teamcapybara/capybara) which need to start a separate application server process. This also makes it possible to share a single database transaction between the client and server, which can significantly reduce the overhead of "cleaning" the database after each test, and improve the opportunity for parallelisation.
11
+ In addition, building on top of [async](https://github.com/socketry/async) allows us to take advantage of [async-http](https://github.com/socketry/async-http) and run the web server in the same reactor as the test itself, which can provide a performance improvement over [capybara](https://github.com/teamcapybara/capybara) which usually needs to start a separate server process. This also makes it possible to share a single database transaction between the client and server, which can significantly reduce the overhead of "cleaning" the database after each test, and improve the opportunity for parallelisation.
12
12
 
13
13
  ## Usage
14
14
 
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.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
metadata.gz.sig CHANGED
Binary file