capybara-lockstep 2.3.0 → 2.3.2
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/.ruby-version +1 -1
- data/CHANGELOG.md +27 -0
- data/Gemfile +5 -2
- data/Gemfile.lock +33 -15
- data/README.md +4 -0
- data/capybara-lockstep.gemspec +14 -21
- data/lib/capybara-lockstep/capybara_ext.rb +12 -26
- data/lib/capybara-lockstep/client/selenium.rb +16 -0
- data/lib/capybara-lockstep/client.rb +12 -0
- data/lib/capybara-lockstep/page_access.rb +0 -3
- data/lib/capybara-lockstep/version.rb +1 -1
- metadata +6 -27
- data/.github/workflows/test.yml +0 -61
- data/media/logo.dark.shapes.svg +0 -169
- data/media/logo.dark.text.svg +0 -107
- data/media/logo.light.shapes.svg +0 -168
- data/media/logo.light.text.svg +0 -106
- data/media/makandra-with-bottom-margin.dark.svg +0 -180
- data/media/makandra-with-bottom-margin.light.svg +0 -180
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cc60ce49170390b7a2160291bcee08a08a22bceacaf58e12b2f2bc5ebadf484e
|
|
4
|
+
data.tar.gz: dd6c60d318fe9f336462a3dcff507acf0120036d8ea160a97a5125ab94dc4248
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fcf26ef14e209a4fd8f6353c129fe9b88b97feb58dd787ebccddc3e19980802ebec1403a374cf580c1798ecf3bc30e365eba1218f40d3b0af3bbbc6f80ca9904
|
|
7
|
+
data.tar.gz: f8db9ee7dbc655724cab11b6f2e3a181ae182579ba78b5f193174b7a78951f407275e49dbceec0b10b4f41cb9abbdc28233a271b781ba686f4bc030e2b932c35
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
4.0.1
|
data/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,33 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
|
|
|
12
12
|
|
|
13
13
|
-
|
|
14
14
|
|
|
15
|
+
|
|
16
|
+
# 2.3.2 - 2026-09-11
|
|
17
|
+
|
|
18
|
+
## Compatible changes
|
|
19
|
+
|
|
20
|
+
- Treat a Selenium `UnknownError` carrying the CDP message `Promise was collected` as a benign "navigated away" event,
|
|
21
|
+
- like the existing `document unloaded` `JavascriptError`. Newer Chrome (141+) with selenium-webdriver 4.41 reports
|
|
22
|
+
- a destroyed JS execution context (e.g. Turbo frame swaps, SPA navigations) this way, which previously surfaced as
|
|
23
|
+
- a flaky, hard-to-diagnose test failure.
|
|
24
|
+
- Skip client synchronization when the effective timeout is not positive. Capybara evaluates filter blocks
|
|
25
|
+
- (e.g. `has_css?('.foo') { |node| node.has_field?('bar') }`) with `using_wait_time(0)`. A nested lookup inside such
|
|
26
|
+
- a block triggered a synchronization with a timeout of 0 when the client was out of sync (e.g. after a timed-out
|
|
27
|
+
- synchronization or on a page without the capybara-lockstep snippet). Capybara's Selenium driver persisted that 0
|
|
28
|
+
- as the WebDriver script timeout, so every later script-based command (including Capybara's visibility checks)
|
|
29
|
+
- failed with `Selenium::WebDriver::Error::ScriptTimeoutError`. This only affected the default configuration
|
|
30
|
+
- (`Capybara::Lockstep.timeout = nil`).
|
|
31
|
+
|
|
32
|
+
# 2.3.1 - 2026-02-17
|
|
33
|
+
|
|
34
|
+
## Compatible changes
|
|
35
|
+
|
|
36
|
+
- Add tests for Ruby 4.0
|
|
37
|
+
- Increase `required_ruby_version` and `activesupport` minimum version in gemspec so people
|
|
38
|
+
on legacy Ruby and Rails versions don't receive future upgrades
|
|
39
|
+
- Drop tests and support for Ruby < 3 and Rails < 7
|
|
40
|
+
- Drop dependency on `ruby2_keywords`
|
|
41
|
+
|
|
15
42
|
# 2.3.0
|
|
16
43
|
|
|
17
44
|
- Added support for cuprite as the capybara driver
|
data/Gemfile
CHANGED
|
@@ -5,7 +5,7 @@ source "https://rubygems.org"
|
|
|
5
5
|
# Specify your gem's dependencies in capybara-lockstep.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
-
gem 'activesupport', '~>
|
|
8
|
+
gem 'activesupport', '~> 8.0'
|
|
9
9
|
gem "rake", "~> 13.0"
|
|
10
10
|
|
|
11
11
|
gem "rspec", "~> 3.0"
|
|
@@ -14,7 +14,7 @@ gem 'sinatra'
|
|
|
14
14
|
gem 'thin' # ruby 3 does not include a webserver
|
|
15
15
|
gem 'puma'
|
|
16
16
|
gem 'byebug'
|
|
17
|
-
gem 'gemika'
|
|
17
|
+
gem 'gemika'
|
|
18
18
|
gem 'capybara', '>= 3'
|
|
19
19
|
gem 'selenium-webdriver', '>= 4'
|
|
20
20
|
gem 'cuprite'
|
|
@@ -25,3 +25,6 @@ gem 'cuprite'
|
|
|
25
25
|
# indirect dependencies ourselves.
|
|
26
26
|
gem 'base64' # needed by selenium-webdriver (and potentially others)
|
|
27
27
|
gem 'bigdecimal' # needed by activesupport (and potentially others)
|
|
28
|
+
gem 'ostruct'
|
|
29
|
+
gem 'logger'
|
|
30
|
+
gem 'cgi'
|
data/Gemfile.lock
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
capybara-lockstep (2.3.
|
|
5
|
-
activesupport (>=
|
|
4
|
+
capybara-lockstep (2.3.2)
|
|
5
|
+
activesupport (>= 7.0)
|
|
6
6
|
capybara (>= 3.0)
|
|
7
|
-
ruby2_keywords
|
|
8
7
|
|
|
9
8
|
GEM
|
|
10
9
|
remote: https://rubygems.org/
|
|
11
10
|
specs:
|
|
12
|
-
activesupport (
|
|
13
|
-
|
|
11
|
+
activesupport (8.1.2)
|
|
12
|
+
base64
|
|
13
|
+
bigdecimal
|
|
14
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
15
|
+
connection_pool (>= 2.2.5)
|
|
16
|
+
drb
|
|
14
17
|
i18n (>= 1.6, < 2)
|
|
18
|
+
json
|
|
19
|
+
logger (>= 1.4.2)
|
|
15
20
|
minitest (>= 5.1)
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
securerandom (>= 0.3)
|
|
22
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
23
|
+
uri (>= 0.13.1)
|
|
18
24
|
addressable (2.8.5)
|
|
19
25
|
public_suffix (>= 2.0.2, < 6.0)
|
|
20
26
|
base64 (0.2.0)
|
|
@@ -29,13 +35,16 @@ GEM
|
|
|
29
35
|
rack-test (>= 0.6.3)
|
|
30
36
|
regexp_parser (>= 1.5, < 3.0)
|
|
31
37
|
xpath (~> 3.2)
|
|
38
|
+
cgi (0.5.1)
|
|
32
39
|
childprocess (4.1.0)
|
|
33
|
-
concurrent-ruby (1.
|
|
40
|
+
concurrent-ruby (1.3.6)
|
|
41
|
+
connection_pool (3.0.2)
|
|
34
42
|
cuprite (0.17)
|
|
35
43
|
capybara (~> 3.0)
|
|
36
44
|
ferrum (~> 0.17.0)
|
|
37
45
|
daemons (1.4.1)
|
|
38
46
|
diff-lcs (1.5.1)
|
|
47
|
+
drb (2.2.3)
|
|
39
48
|
eventmachine (1.2.7)
|
|
40
49
|
ferrum (0.17.1)
|
|
41
50
|
addressable (~> 2.5)
|
|
@@ -43,19 +52,24 @@ GEM
|
|
|
43
52
|
concurrent-ruby (~> 1.1)
|
|
44
53
|
webrick (~> 1.7)
|
|
45
54
|
websocket-driver (~> 0.7)
|
|
46
|
-
gemika (0.
|
|
47
|
-
i18n (1.
|
|
55
|
+
gemika (2.0.0)
|
|
56
|
+
i18n (1.14.8)
|
|
48
57
|
concurrent-ruby (~> 1.0)
|
|
58
|
+
json (2.18.1)
|
|
59
|
+
logger (1.7.0)
|
|
49
60
|
matrix (0.4.2)
|
|
50
61
|
mini_mime (1.1.5)
|
|
51
62
|
mini_portile2 (2.8.5)
|
|
52
|
-
minitest (
|
|
63
|
+
minitest (6.0.1)
|
|
64
|
+
prism (~> 1.5)
|
|
53
65
|
mustermann (3.0.0)
|
|
54
66
|
ruby2_keywords (~> 0.0.1)
|
|
55
67
|
nio4r (2.6.1)
|
|
56
68
|
nokogiri (1.15.5)
|
|
57
69
|
mini_portile2 (~> 2.8.2)
|
|
58
70
|
racc (~> 1.4)
|
|
71
|
+
ostruct (0.6.3)
|
|
72
|
+
prism (1.9.0)
|
|
59
73
|
public_suffix (5.0.4)
|
|
60
74
|
puma (6.4.0)
|
|
61
75
|
nio4r (~> 2.0)
|
|
@@ -85,6 +99,7 @@ GEM
|
|
|
85
99
|
rspec (>= 3.0)
|
|
86
100
|
ruby2_keywords (0.0.5)
|
|
87
101
|
rubyzip (2.3.2)
|
|
102
|
+
securerandom (0.4.1)
|
|
88
103
|
selenium-webdriver (4.1.0)
|
|
89
104
|
childprocess (>= 0.5, < 5.0)
|
|
90
105
|
rexml (~> 3.2, >= 3.2.5)
|
|
@@ -99,8 +114,9 @@ GEM
|
|
|
99
114
|
eventmachine (~> 1.0, >= 1.0.4)
|
|
100
115
|
rack (>= 1, < 3)
|
|
101
116
|
tilt (2.3.0)
|
|
102
|
-
tzinfo (2.0.
|
|
117
|
+
tzinfo (2.0.6)
|
|
103
118
|
concurrent-ruby (~> 1.0)
|
|
119
|
+
uri (1.1.1)
|
|
104
120
|
webrick (1.9.1)
|
|
105
121
|
websocket-driver (0.8.0)
|
|
106
122
|
base64
|
|
@@ -108,20 +124,22 @@ GEM
|
|
|
108
124
|
websocket-extensions (0.1.5)
|
|
109
125
|
xpath (3.2.0)
|
|
110
126
|
nokogiri (~> 1.8)
|
|
111
|
-
zeitwerk (2.6.0)
|
|
112
127
|
|
|
113
128
|
PLATFORMS
|
|
114
129
|
ruby
|
|
115
130
|
|
|
116
131
|
DEPENDENCIES
|
|
117
|
-
activesupport (~>
|
|
132
|
+
activesupport (~> 8.0)
|
|
118
133
|
base64
|
|
119
134
|
bigdecimal
|
|
120
135
|
byebug
|
|
121
136
|
capybara (>= 3)
|
|
122
137
|
capybara-lockstep!
|
|
138
|
+
cgi
|
|
123
139
|
cuprite
|
|
124
|
-
gemika
|
|
140
|
+
gemika
|
|
141
|
+
logger
|
|
142
|
+
ostruct
|
|
125
143
|
puma
|
|
126
144
|
rake (~> 13.0)
|
|
127
145
|
rspec (~> 3.0)
|
data/README.md
CHANGED
|
@@ -342,6 +342,8 @@ Capybara::Lockstep.timeout = 5 # seconds
|
|
|
342
342
|
|
|
343
343
|
By default Capybara will **not** raise an error after a timeout. You may occasionally get a slow server response, and Capybara will retry synchronization before the next interaction or `visit`. This is often good enough.
|
|
344
344
|
|
|
345
|
+
When the effective timeout is `0` (e.g. inside a Capybara filter block, which Capybara evaluates with `using_wait_time(0)`), capybara-lockstep skips the synchronization, logs `Cannot synchronize client with a timeout of 0 seconds` and retries on the next interaction.
|
|
346
|
+
|
|
345
347
|
If you want to be strict you may configure that an `Capybara::Lockstep::Timeout` error is raised after a timeout:
|
|
346
348
|
|
|
347
349
|
```ruby
|
|
@@ -468,6 +470,8 @@ You can also run `bin/console` for an interactive prompt that will allow you to
|
|
|
468
470
|
|
|
469
471
|
capybara-lockstep supports both the `selenium-webdriver` and `cuprite` as drivers for capybara.
|
|
470
472
|
|
|
473
|
+
Make sure, your chromedriver version is up to date.
|
|
474
|
+
|
|
471
475
|
To run all the tests for all supported drivers, run `rake spec:all`.
|
|
472
476
|
|
|
473
477
|
To run all the tests for a specific driver, run `rake spec:selenium` or `rake spec:cuprite`.
|
data/capybara-lockstep.gemspec
CHANGED
|
@@ -5,33 +5,26 @@ Gem::Specification.new do |spec|
|
|
|
5
5
|
spec.version = Capybara::Lockstep::VERSION
|
|
6
6
|
spec.authors = ["Henning Koch"]
|
|
7
7
|
spec.email = ["henning.koch@makandra.de"]
|
|
8
|
-
|
|
9
|
-
spec.summary = "Synchronize Capybara commands with client-side JavaScript and AJAX requests"
|
|
10
8
|
spec.homepage = "https://github.com/makandra/capybara-lockstep"
|
|
9
|
+
spec.summary = "Synchronize Capybara commands with client-side JavaScript and AJAX requests"
|
|
11
10
|
spec.license = "MIT"
|
|
12
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
|
13
11
|
|
|
14
|
-
spec.metadata
|
|
15
|
-
|
|
12
|
+
spec.metadata = {
|
|
13
|
+
"homepage_uri" => spec.homepage,
|
|
14
|
+
"source_code_uri" => spec.homepage,
|
|
15
|
+
"bug_tracker_uri" => "#{spec.homepage}/issues",
|
|
16
|
+
"changelog_uri" => "#{spec.homepage}/blob/main/CHANGELOG.md",
|
|
17
|
+
"rubygems_mfa_required" => 'true',
|
|
18
|
+
}
|
|
16
19
|
|
|
17
|
-
spec.
|
|
18
|
-
spec.
|
|
19
|
-
spec.metadata["rubygems_mfa_required"] = 'true'
|
|
20
|
+
spec.files = `git ls-files`.split("\n").select { |f| !File.symlink?(f) && !f.match(%r{^(spec|dev|media|.github)/}) }
|
|
21
|
+
spec.require_paths = ["lib"]
|
|
20
22
|
|
|
21
|
-
# Specify which files should be added to the gem when it is released.
|
|
22
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
23
|
-
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
24
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
|
25
|
-
end
|
|
26
23
|
spec.bindir = "exe"
|
|
27
|
-
spec.executables =
|
|
28
|
-
spec.require_paths = ["lib"]
|
|
24
|
+
spec.executables = []
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
spec.add_dependency "capybara", ">= 3.0"
|
|
32
|
-
spec.add_dependency "activesupport", ">= 4.2"
|
|
33
|
-
spec.add_dependency "ruby2_keywords"
|
|
26
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
spec.add_dependency "capybara", ">= 3.0"
|
|
29
|
+
spec.add_dependency "activesupport", ">= 7.0"
|
|
37
30
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'ruby2_keywords'
|
|
2
|
-
|
|
3
1
|
module Capybara
|
|
4
2
|
module Lockstep
|
|
5
3
|
module SynchronizeMacros
|
|
@@ -13,43 +11,37 @@ module Capybara
|
|
|
13
11
|
|
|
14
12
|
def synchronize_before(meth, lazy:)
|
|
15
13
|
@synchronize_before_module.module_eval do
|
|
16
|
-
define_method meth do |*args, &block|
|
|
14
|
+
define_method meth do |*args, **kwargs, &block|
|
|
17
15
|
@synchronize_before_count ||= 0
|
|
18
16
|
@synchronize_before_count += 1
|
|
19
17
|
Lockstep.auto_synchronize(lazy: lazy, log: "Synchronizing before ##{meth}") if @synchronize_before_count == 1
|
|
20
|
-
super(*args, &block)
|
|
18
|
+
super(*args, **kwargs, &block)
|
|
21
19
|
ensure
|
|
22
20
|
@synchronize_before_count -= 1
|
|
23
21
|
end
|
|
24
|
-
|
|
25
|
-
ruby2_keywords meth
|
|
26
22
|
end
|
|
27
23
|
end
|
|
28
24
|
|
|
29
25
|
def synchronize_after(meth)
|
|
30
26
|
@synchronize_after_module.module_eval do
|
|
31
|
-
define_method meth do |*args, &block|
|
|
27
|
+
define_method meth do |*args, **kwargs, &block|
|
|
32
28
|
@synchronize_after_count ||= 0
|
|
33
29
|
@synchronize_after_count += 1
|
|
34
|
-
super(*args, &block)
|
|
30
|
+
super(*args, **kwargs, &block)
|
|
35
31
|
ensure
|
|
36
32
|
Lockstep.auto_synchronize(log: "Synchronizing after ##{meth}") if @synchronize_after_count == 1
|
|
37
33
|
@synchronize_after_count -= 1
|
|
38
34
|
end
|
|
39
|
-
|
|
40
|
-
ruby2_keywords meth
|
|
41
35
|
end
|
|
42
36
|
end
|
|
43
37
|
|
|
44
38
|
def unsynchronize_after(meth)
|
|
45
39
|
@unsynchronize_after_module.module_eval do
|
|
46
|
-
define_method meth do |*args, &block|
|
|
47
|
-
super(*args, &block)
|
|
40
|
+
define_method meth do |*args, **kwargs, &block|
|
|
41
|
+
super(*args, **kwargs, &block)
|
|
48
42
|
ensure
|
|
49
43
|
Lockstep.unsynchronize
|
|
50
44
|
end
|
|
51
|
-
|
|
52
|
-
ruby2_keywords meth
|
|
53
45
|
end
|
|
54
46
|
end
|
|
55
47
|
end
|
|
@@ -82,7 +74,7 @@ end
|
|
|
82
74
|
module Capybara
|
|
83
75
|
module Lockstep
|
|
84
76
|
module VisitWithWaiting
|
|
85
|
-
def visit(*args, &block)
|
|
77
|
+
def visit(*args, **kwargs, &block)
|
|
86
78
|
# For some reason, in Capybara proper, visit(nil) navigates to the root route.
|
|
87
79
|
# We mimic this behavior for (1) parity and (2) to not crash when we inspect the URL below.
|
|
88
80
|
url = args[0].presence || '/'
|
|
@@ -104,15 +96,13 @@ module Capybara
|
|
|
104
96
|
Lockstep.auto_synchronize(lazy: false, log: "Synchronizing before visiting #{url}")
|
|
105
97
|
end
|
|
106
98
|
|
|
107
|
-
super(*args, &block).tap do
|
|
99
|
+
super(*args, **kwargs, &block).tap do
|
|
108
100
|
if visiting_real_url
|
|
109
101
|
# We haven't yet synchronized the new screen.
|
|
110
102
|
Lockstep.unsynchronize
|
|
111
103
|
end
|
|
112
104
|
end
|
|
113
105
|
end
|
|
114
|
-
|
|
115
|
-
ruby2_keywords :visit
|
|
116
106
|
end
|
|
117
107
|
end
|
|
118
108
|
end
|
|
@@ -127,7 +117,7 @@ module Capybara
|
|
|
127
117
|
|
|
128
118
|
def synchronize_around_script_method(meth)
|
|
129
119
|
mod = Module.new do
|
|
130
|
-
define_method meth do |script, *args, &block|
|
|
120
|
+
define_method meth do |script, *args, **kwargs, &block|
|
|
131
121
|
# Synchronization uses execute_script itself, so don't synchronize when
|
|
132
122
|
# we're already synchronizing.
|
|
133
123
|
if !Lockstep.synchronizing?
|
|
@@ -142,7 +132,7 @@ module Capybara
|
|
|
142
132
|
Lockstep.auto_synchronize(lazy: !script_may_navigate_away, log: "Synchronizing before script: #{script}")
|
|
143
133
|
end
|
|
144
134
|
|
|
145
|
-
super(script, *args, &block)
|
|
135
|
+
super(script, *args, **kwargs, &block)
|
|
146
136
|
ensure
|
|
147
137
|
if !Lockstep.synchronizing?
|
|
148
138
|
# We haven't yet synchronized with whatever changes the JavaScript
|
|
@@ -150,8 +140,6 @@ module Capybara
|
|
|
150
140
|
Lockstep.unsynchronize
|
|
151
141
|
end
|
|
152
142
|
end
|
|
153
|
-
|
|
154
|
-
ruby2_keywords meth
|
|
155
143
|
end
|
|
156
144
|
prepend(mod)
|
|
157
145
|
end
|
|
@@ -246,16 +234,14 @@ end
|
|
|
246
234
|
module Capybara
|
|
247
235
|
module Lockstep
|
|
248
236
|
module SynchronizeWithCatchUp
|
|
249
|
-
def synchronize(*args, &block)
|
|
237
|
+
def synchronize(*args, **kwargs, &block)
|
|
250
238
|
# This method is called by Capybara before most interactions with
|
|
251
239
|
# the browser. It is a different method than Capybara::Lockstep.synchronize!
|
|
252
240
|
# We use the { lazy } option to only synchronize when we're out of sync.
|
|
253
241
|
Lockstep.auto_synchronize(lazy: true, log: 'Synchronizing before node access')
|
|
254
242
|
|
|
255
|
-
super(*args, &block)
|
|
243
|
+
super(*args, **kwargs, &block)
|
|
256
244
|
end
|
|
257
|
-
|
|
258
|
-
ruby2_keywords :synchronize
|
|
259
245
|
end
|
|
260
246
|
end
|
|
261
247
|
end
|
|
@@ -32,6 +32,22 @@ module Capybara
|
|
|
32
32
|
else
|
|
33
33
|
unhandled_synchronize_error(e)
|
|
34
34
|
end
|
|
35
|
+
rescue ::Selenium::WebDriver::Error::UnknownError => e
|
|
36
|
+
# Newer Chrome (e.g. chrome-headless-shell 141) with selenium-webdriver 4.41
|
|
37
|
+
# reports the same "navigated away" condition differently than the older
|
|
38
|
+
# JavascriptError "document unloaded" message handled above. When an interaction
|
|
39
|
+
# destroys the JS execution context that owns our pending async probe (a Turbo
|
|
40
|
+
# frame swap or an SPA navigation), the promise can never resolve and the driver
|
|
41
|
+
# raises a Selenium::WebDriver::Error::UnknownError wrapping the CDP error:
|
|
42
|
+
# 'unknown error: unhandled inspector error: {"code":-32000,"message":"Promise was collected"}'.
|
|
43
|
+
# Treat this symmetrically to the 'unload' branch above: leave the client
|
|
44
|
+
# unsynchronized and retry on the next Capybara synchronize call, by then we
|
|
45
|
+
# should see the new page. Any other UnknownError is still unexpected and re-raised.
|
|
46
|
+
if e.message.include?('Promise was collected')
|
|
47
|
+
log ERROR_NAVIGATED_AWAY
|
|
48
|
+
else
|
|
49
|
+
unhandled_synchronize_error(e)
|
|
50
|
+
end
|
|
35
51
|
rescue StandardError => e
|
|
36
52
|
unhandled_synchronize_error(e)
|
|
37
53
|
end
|
|
@@ -37,6 +37,18 @@ module Capybara
|
|
|
37
37
|
# If synchronization fails below we consider us unsynchronized after.
|
|
38
38
|
self.synchronized = false
|
|
39
39
|
|
|
40
|
+
# Capybara evaluates filter blocks with `using_wait_time(0)`. Our default timeout is
|
|
41
|
+
# Capybara.default_max_wait_time, so a nested lookup inside such a block would try
|
|
42
|
+
# to synchronize with a timeout of 0. An async script can never finish within 0 seconds,
|
|
43
|
+
# and Capybara's Selenium driver would persist that 0 as the WebDriver script timeout,
|
|
44
|
+
# breaking every later script-based command with a ScriptTimeoutError.
|
|
45
|
+
if timeout <= 0
|
|
46
|
+
log "Cannot synchronize client with a timeout of #{timeout} seconds"
|
|
47
|
+
# Don't raise an error, this will happen in an innocent test.
|
|
48
|
+
# We will retry on the next Capybara synchronize call with a real timeout.
|
|
49
|
+
return
|
|
50
|
+
end
|
|
51
|
+
|
|
40
52
|
# Running the synchronization script while an alert is open would close the alert,
|
|
41
53
|
# most likely causing subsequent expectations to fail.
|
|
42
54
|
if alert_present?
|
|
@@ -25,8 +25,6 @@ module Capybara
|
|
|
25
25
|
false
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
private
|
|
29
|
-
|
|
30
28
|
def selenium_driver?
|
|
31
29
|
defined?(Capybara::Selenium::Driver) && driver.is_a?(Capybara::Selenium::Driver)
|
|
32
30
|
end
|
|
@@ -35,7 +33,6 @@ module Capybara
|
|
|
35
33
|
defined?(Capybara::Cuprite::Driver) && driver.is_a?(Capybara::Cuprite::Driver)
|
|
36
34
|
end
|
|
37
35
|
|
|
38
|
-
|
|
39
36
|
end
|
|
40
37
|
end
|
|
41
38
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: capybara-lockstep
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.3.
|
|
4
|
+
version: 2.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Henning Koch
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: capybara
|
|
@@ -29,35 +29,20 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
32
|
+
version: '7.0'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '
|
|
40
|
-
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: ruby2_keywords
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - ">="
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: '0'
|
|
47
|
-
type: :runtime
|
|
48
|
-
prerelease: false
|
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - ">="
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: '0'
|
|
39
|
+
version: '7.0'
|
|
54
40
|
email:
|
|
55
41
|
- henning.koch@makandra.de
|
|
56
42
|
executables: []
|
|
57
43
|
extensions: []
|
|
58
44
|
extra_rdoc_files: []
|
|
59
45
|
files:
|
|
60
|
-
- ".github/workflows/test.yml"
|
|
61
46
|
- ".gitignore"
|
|
62
47
|
- ".rspec"
|
|
63
48
|
- ".ruby-version"
|
|
@@ -86,12 +71,6 @@ files:
|
|
|
86
71
|
- lib/capybara-lockstep/server.rb
|
|
87
72
|
- lib/capybara-lockstep/util.rb
|
|
88
73
|
- lib/capybara-lockstep/version.rb
|
|
89
|
-
- media/logo.dark.shapes.svg
|
|
90
|
-
- media/logo.dark.text.svg
|
|
91
|
-
- media/logo.light.shapes.svg
|
|
92
|
-
- media/logo.light.text.svg
|
|
93
|
-
- media/makandra-with-bottom-margin.dark.svg
|
|
94
|
-
- media/makandra-with-bottom-margin.light.svg
|
|
95
74
|
- tasks/spec_tasks.rb
|
|
96
75
|
homepage: https://github.com/makandra/capybara-lockstep
|
|
97
76
|
licenses:
|
|
@@ -109,14 +88,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
109
88
|
requirements:
|
|
110
89
|
- - ">="
|
|
111
90
|
- !ruby/object:Gem::Version
|
|
112
|
-
version:
|
|
91
|
+
version: 3.0.0
|
|
113
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
93
|
requirements:
|
|
115
94
|
- - ">="
|
|
116
95
|
- !ruby/object:Gem::Version
|
|
117
96
|
version: '0'
|
|
118
97
|
requirements: []
|
|
119
|
-
rubygems_version:
|
|
98
|
+
rubygems_version: 4.0.3
|
|
120
99
|
specification_version: 4
|
|
121
100
|
summary: Synchronize Capybara commands with client-side JavaScript and AJAX requests
|
|
122
101
|
test_files: []
|
data/.github/workflows/test.yml
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Tests
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
pull_request:
|
|
8
|
-
branches:
|
|
9
|
-
- main
|
|
10
|
-
workflow_dispatch:
|
|
11
|
-
branches:
|
|
12
|
-
- main
|
|
13
|
-
jobs:
|
|
14
|
-
test:
|
|
15
|
-
runs-on: ubuntu-24.04
|
|
16
|
-
timeout-minutes: 3
|
|
17
|
-
strategy:
|
|
18
|
-
fail-fast: false
|
|
19
|
-
matrix:
|
|
20
|
-
include:
|
|
21
|
-
- ruby: 2.7.2
|
|
22
|
-
gemfile: Gemfile
|
|
23
|
-
capybara_driver: selenium
|
|
24
|
-
- ruby: 2.7.2
|
|
25
|
-
gemfile: Gemfile
|
|
26
|
-
capybara_driver: cuprite
|
|
27
|
-
- ruby: 3.2.0
|
|
28
|
-
gemfile: Gemfile
|
|
29
|
-
capybara_driver: selenium
|
|
30
|
-
- ruby: 3.4.1
|
|
31
|
-
gemfile: Gemfile
|
|
32
|
-
capybara_driver: selenium
|
|
33
|
-
- ruby: 3.4.1
|
|
34
|
-
gemfile: Gemfile
|
|
35
|
-
capybara_driver: cuprite
|
|
36
|
-
env:
|
|
37
|
-
BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
|
|
38
|
-
CAPYBARA_DRIVER: "${{ matrix.capybara_driver }}"
|
|
39
|
-
steps:
|
|
40
|
-
- uses: actions/checkout@v3
|
|
41
|
-
- name: Install Chrome
|
|
42
|
-
uses: browser-actions/setup-chrome@latest
|
|
43
|
-
- name: Show Chrome version
|
|
44
|
-
run: chrome --version
|
|
45
|
-
- name: Install ChromeDriver
|
|
46
|
-
uses: nanasess/setup-chromedriver@master
|
|
47
|
-
if: "${{ matrix.capybara_driver == 'selenium' }}"
|
|
48
|
-
- name: Install ruby
|
|
49
|
-
uses: ruby/setup-ruby@v1
|
|
50
|
-
with:
|
|
51
|
-
ruby-version: "${{ matrix.ruby }}"
|
|
52
|
-
- name: Bundle
|
|
53
|
-
run: |
|
|
54
|
-
gem install bundler:2.3.1
|
|
55
|
-
bundle install --no-deployment
|
|
56
|
-
- name: Run tests
|
|
57
|
-
uses: nick-invision/retry@v2
|
|
58
|
-
with:
|
|
59
|
-
timeout_seconds: 30
|
|
60
|
-
max_attempts: 3
|
|
61
|
-
command: bundle exec rake spec
|