capybara-lockstep 2.0.0.rc1 → 2.0.1

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: f264c637e6de9b4a6ab18e1e33ebf3c81fe46a9a20173b5c4c8097f5be4d8ae6
4
- data.tar.gz: f48886c96cbdfe898d5245a85955b76a5caee1c64662e4e12823427b7cb6c883
3
+ metadata.gz: fec95c22e010d3c9f9fbf5c9625a2660267de90a80da2a395355a9aa6ffe292e
4
+ data.tar.gz: 80b6ccc788241ca29aec1eddc2e0a5faa85ce5122fda16ba000b9980ca921270
5
5
  SHA512:
6
- metadata.gz: c959856af42047611c8c90b4b9c2de6a0a201ba9bff3f5ae9f2bc0a1e32026999283253c6d7ace66305364c57550dc20b5ee131251dcbf80cec707b47994bb30
7
- data.tar.gz: be4f33cb2e453d1bf830a75d70a55ffdb43c243ccf0f9d0513bf578b88d0aec6fca135cb4c16f6f13096edd52d44c190794f480ba35140ec965c32e09ddafa6f
6
+ metadata.gz: bb4df421a7b648a20950d56c91bfdf3ed6c3155a5fe93a9808bb48de550a31820a17a265306957df3cbed7fc3b119b9dd643be05aea372bec33dcff131dcfb18
7
+ data.tar.gz: 8f5dcb3934037d1cccf3c03257a00c4d8fa45b1797d0261fd74a19b3f787f9034b9966064eed25be3fc556cc4be5ecfbf930508893c9b973b6a5cb2f70c3e38e
@@ -9,7 +9,7 @@ on:
9
9
  - master
10
10
  workflow_dispatch:
11
11
  branches:
12
- - master
12
+ - master
13
13
  jobs:
14
14
  test:
15
15
  runs-on: ubuntu-20.04
@@ -18,8 +18,6 @@ jobs:
18
18
  fail-fast: false
19
19
  matrix:
20
20
  include:
21
- - ruby: 2.6.6
22
- gemfile: Gemfile
23
21
  - ruby: 2.7.2
24
22
  gemfile: Gemfile
25
23
  - ruby: 3.2.0
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ /todo.txt
1
2
  /.bundle/
2
3
  /.yardoc
3
4
  /_yardoc/
data/CHANGELOG.md CHANGED
@@ -3,14 +3,23 @@ All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
4
4
 
5
5
 
6
- # 2.0.0-rc1
6
+ # 2.0.1
7
7
 
8
+ - Don't crash when an interaction closes the window (tab).
9
+
10
+
11
+ # 2.0.0
12
+
13
+ This major release detects many additional sources of flaky tests:
14
+
8
15
  - We now synchronize before a user interaction. Previously we only synchronized before an observation. This could lead to race conditions when a test chained multiple interactions without [making an observation in between](https://makandracards.com/makandra/47336-fixing-flaky-e2e-tests#section-interleave-actions-and-expectations).
9
- - We now synchronize after a user interaction (e.g. after a click). Previously we only synchronized before an observation. This could lead to race conditions when a test made assertions without going to Capybara, e.g. by accessing the database or global state variables.
16
+ - We now synchronize after a user interaction (e.g. after a click). Previously we only synchronized before an observation. This could lead to race conditions when a test made assertions without going through Capybara, e.g. by accessing the database or global state variables.
10
17
  - When a job ends (e.g. an AJAX request finishes) we now wait for one [JavaScript task](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/). This gives event listeners more time to schedule new async work.
11
18
  - We now wait one JavaScript task after `touchstart`, `mousedown`, `click` and `keydown` events. This gives event listeners more time to schedule async work after a user interaction.
12
- - You can now wait while the backend server is busy, by using `Capybara::Lockstep::Middleware` in your Rails or Rack app. We previously only waited for AJAX requests on the client, but using the middleware addresses some additional edge cases. For example, the middleware detects requests that were aborted on the frontend, but are still being processed by the backend.
13
- - You can signal async work from the backend, e.g. for background jobs. Note that you don't need to signal work for the regular request/response cycle, as this is detected automatically.
19
+ - You can now [wait while the backend server is busy](https://github.com/makandra/capybara-lockstep/#including-the-middleware-optional), by using `Capybara::Lockstep::Middleware` in your Rails or Rack app. We previously only waited for AJAX requests on the client, but using the middleware addresses some additional edge cases. For example, the middleware detects requests that were aborted on the frontend, but are still being processed by the backend.
20
+ - You can [signal async work from the backend](https://github.com/makandra/capybara-lockstep/#on-the-backend), e.g. for background jobs. Note that you don't need to signal work for the regular request/response cycle, as this is detected automatically.
21
+
22
+ Although we now cover a lot more edge cases, this releases will not slow down your test suite considerably.
14
23
 
15
24
 
16
25
  ## 1.3.1 - 2023-10-25
data/Gemfile CHANGED
@@ -5,17 +5,15 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in capybara-lockstep.gemspec
6
6
  gemspec
7
7
 
8
+ gem 'activesupport', '~> 6.0'
8
9
  gem "rake", "~> 13.0"
9
10
 
10
11
  gem "rspec", "~> 3.0"
11
- gem 'jasmine'
12
+ gem "rspec-wait"
13
+ gem 'sinatra'
12
14
  gem 'thin' # ruby 3 does not include a webserver
13
- gem 'chrome_remote'
14
-
15
+ gem 'puma'
15
16
  gem 'byebug'
16
17
  gem 'gemika', '>= 0.8.1'
17
-
18
- gem 'activesupport', '~> 6.0'
19
-
20
- gem 'capybara', '= 3.36.0' # last version compatible with Ruby < 2.7, which is in our test matrix
21
- gem 'selenium-webdriver', '=4.1.0' # last version compatible with Ruby < 2.7, which is in our test matrix
18
+ gem 'capybara', '>= 3'
19
+ gem 'selenium-webdriver', '>= 4'
data/Gemfile.lock CHANGED
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- capybara-lockstep (2.0.0.rc1)
5
- activesupport (>= 3.2)
6
- capybara (>= 2.0)
4
+ capybara-lockstep (2.0.1)
5
+ activesupport (>= 4.2)
6
+ capybara (>= 3.0)
7
7
  ruby2_keywords
8
- selenium-webdriver (>= 3)
8
+ selenium-webdriver (>= 4.0)
9
9
 
10
10
  GEM
11
11
  remote: https://rubygems.org/
@@ -16,10 +16,10 @@ GEM
16
16
  minitest (>= 5.1)
17
17
  tzinfo (~> 2.0)
18
18
  zeitwerk (~> 2.3)
19
- addressable (2.8.1)
19
+ addressable (2.8.5)
20
20
  public_suffix (>= 2.0.2, < 6.0)
21
21
  byebug (11.1.3)
22
- capybara (3.36.0)
22
+ capybara (3.39.2)
23
23
  addressable
24
24
  matrix
25
25
  mini_mime (>= 0.1.3)
@@ -29,36 +29,34 @@ GEM
29
29
  regexp_parser (>= 1.5, < 3.0)
30
30
  xpath (~> 3.2)
31
31
  childprocess (4.1.0)
32
- chrome_remote (0.3.0)
33
- websocket-driver (~> 0.6)
34
32
  concurrent-ruby (1.1.10)
35
- daemons (1.3.1)
33
+ daemons (1.4.1)
36
34
  diff-lcs (1.3)
37
35
  eventmachine (1.2.7)
38
36
  gemika (0.8.1)
39
37
  i18n (1.12.0)
40
38
  concurrent-ruby (~> 1.0)
41
- jasmine (3.6.0)
42
- jasmine-core (~> 3.6.0)
43
- phantomjs
44
- rack (>= 1.2.1)
45
- rake
46
- jasmine-core (3.6.0)
47
39
  matrix (0.4.2)
48
- mini_mime (1.1.2)
49
- mini_portile2 (2.8.1)
40
+ mini_mime (1.1.5)
41
+ mini_portile2 (2.8.5)
50
42
  minitest (5.16.3)
51
- nokogiri (1.13.8)
52
- mini_portile2 (~> 2.8.0)
43
+ mustermann (3.0.0)
44
+ ruby2_keywords (~> 0.0.1)
45
+ nio4r (2.6.1)
46
+ nokogiri (1.15.5)
47
+ mini_portile2 (~> 2.8.2)
53
48
  racc (~> 1.4)
54
- phantomjs (2.1.1.0)
55
- public_suffix (5.0.0)
56
- racc (1.6.0)
57
- rack (2.2.3)
58
- rack-test (2.0.2)
49
+ public_suffix (5.0.4)
50
+ puma (6.4.0)
51
+ nio4r (~> 2.0)
52
+ racc (1.7.3)
53
+ rack (2.2.8)
54
+ rack-protection (3.1.0)
55
+ rack (~> 2.2, >= 2.2.4)
56
+ rack-test (2.1.0)
59
57
  rack (>= 1.3)
60
- rake (13.0.1)
61
- regexp_parser (2.5.0)
58
+ rake (13.1.0)
59
+ regexp_parser (2.8.2)
62
60
  rexml (3.2.5)
63
61
  rspec (3.7.0)
64
62
  rspec-core (~> 3.7.0)
@@ -73,21 +71,26 @@ GEM
73
71
  diff-lcs (>= 1.2.0, < 2.0)
74
72
  rspec-support (~> 3.7.0)
75
73
  rspec-support (3.7.0)
74
+ rspec-wait (0.0.9)
75
+ rspec (>= 3, < 4)
76
76
  ruby2_keywords (0.0.5)
77
77
  rubyzip (2.3.2)
78
78
  selenium-webdriver (4.1.0)
79
79
  childprocess (>= 0.5, < 5.0)
80
80
  rexml (~> 3.2, >= 3.2.5)
81
81
  rubyzip (>= 1.2.2)
82
- thin (1.8.0)
82
+ sinatra (3.1.0)
83
+ mustermann (~> 3.0)
84
+ rack (~> 2.2, >= 2.2.4)
85
+ rack-protection (= 3.1.0)
86
+ tilt (~> 2.0)
87
+ thin (1.8.2)
83
88
  daemons (~> 1.0, >= 1.0.9)
84
89
  eventmachine (~> 1.0, >= 1.0.4)
85
90
  rack (>= 1, < 3)
91
+ tilt (2.3.0)
86
92
  tzinfo (2.0.5)
87
93
  concurrent-ruby (~> 1.0)
88
- websocket-driver (0.7.3)
89
- websocket-extensions (>= 0.1.0)
90
- websocket-extensions (0.1.5)
91
94
  xpath (3.2.0)
92
95
  nokogiri (~> 1.8)
93
96
  zeitwerk (2.6.0)
@@ -98,14 +101,15 @@ PLATFORMS
98
101
  DEPENDENCIES
99
102
  activesupport (~> 6.0)
100
103
  byebug
101
- capybara (= 3.36.0)
104
+ capybara (>= 3)
102
105
  capybara-lockstep!
103
- chrome_remote
104
106
  gemika (>= 0.8.1)
105
- jasmine
107
+ puma
106
108
  rake (~> 13.0)
107
109
  rspec (~> 3.0)
108
- selenium-webdriver (= 4.1.0)
110
+ rspec-wait
111
+ selenium-webdriver (>= 4)
112
+ sinatra
109
113
  thin
110
114
 
111
115
  BUNDLED WITH
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
- # capybara-lockstep
1
+ # capybara-lockstep [![Tests](https://github.com/makandra/capybara-lockstep/actions/workflows/test.yml/badge.svg)](https://github.com/makandra/capybara-lockstep/actions)
2
2
 
3
3
  This Ruby gem synchronizes [Capybara](https://github.com/teamcapybara/capybara) commands with client-side JavaScript and AJAX requests. This greatly improves the stability of an end-to-end ("E2E") test suite, even if that suite has timing issues.
4
4
 
5
5
  The next section explain why your test suite is flaky and how capybara-lockstep can help.\
6
- If you don't care you may skip to [installation instructions](#installation).
6
+ If you don't care you may **skip to [installation instructions](#installation)**.
7
7
 
8
8
 
9
9
  Why are tests flaky?
@@ -58,8 +58,9 @@ How capybara-lockstep helps
58
58
 
59
59
  capybara-lockstep waits until the browser is idle before moving on to the next Capybara command. This greatly relieves the pressure on [Capybara's retry logic](https://github.com/teamcapybara/capybara#asynchronous-javascript-ajax-and-friends).
60
60
 
61
- capybara-lockstep synchronizes before:
61
+ capybara-lockstep synchronizes when one of the following occurs:
62
62
 
63
+ - Capybara looks up an element
63
64
  - Capybara simulates a user interaction (clicking, typing, etc.)
64
65
  - Capybara visits a new URL
65
66
  - Capybara executes JavaScript
@@ -69,13 +70,24 @@ When capybara-lockstep synchronizes it will:
69
70
  - wait for all document resources to load (images, CSS, fonts, frames).
70
71
  - wait for client-side JavaScript to render or hydrate DOM elements.
71
72
  - wait for any pending AJAX requests to finish and their callbacks to be called.
72
- - capybara-lockstep waits for dynamically inserted `<script>`s to load (e.g. from [dynamic imports](https://webpack.js.org/guides/code-splitting/#dynamic-imports) or Analytics snippets).
73
- - capybara-lockstep waits for dynamically inserted `<img>` or `<iframe>` elements to load.
73
+ - wait for dynamically inserted `<script>`s to load (e.g. from [dynamic imports](https://webpack.js.org/guides/code-splitting/#dynamic-imports) or Analytics snippets).
74
+ - waits for dynamically inserted `<img>` or `<iframe>` elements to load.
74
75
 
75
- In summary Capybara can no longer observe the page while HTTP requests are in flight.
76
+ In summary Capybara can no longer observe or interact with the page while HTTP requests are in flight.
76
77
  This covers most async work that causes flaky tests.
77
78
 
78
- You can also configure capybara-lockstep to [wait for other async work](#signaling-asynchronous-work) that does not involve the network, like animations.
79
+
80
+ ### Limitations
81
+
82
+ Async work not synchronized by capybara-lockstep includes:
83
+
84
+ - Animations
85
+ - Websocket connections
86
+ - Media elements (`<video>`, `<audio>`)
87
+ - Service workers
88
+ - Work scheduled via `setTimeout()` or `setInterval()`.
89
+
90
+ You can configure capybara-lockstep to [wait for additional async work](#signaling-asynchronous-work).
79
91
 
80
92
 
81
93
  Installation
@@ -85,8 +97,8 @@ Installation
85
97
 
86
98
  Check if your application satisfies all requirements for capybara-lockstep:
87
99
 
88
- - Capybara 2 or higher.
89
- - Your Capybara driver must use [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/). capybara-lockstep deactivates itself for any other driver.
100
+ - Capybara 2.0 or higher.
101
+ - Your Capybara driver must use [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/) 3.0 or higher. capybara-lockstep deactivates itself for any other driver.
90
102
  - This gem was only tested with a Selenium-controlled Chrome browser. [Chrome in headless mode](https://makandracards.com/makandra/492109-running-capybara-tests-in-headless-chrome) is recommended, but not required.
91
103
  - This gem was only tested with Rails, but there's no Rails dependency.
92
104
 
@@ -110,7 +122,7 @@ $ bundle install
110
122
  If you're not using Rails you should also `require 'capybara-lockstep'` in your `spec_helper.rb` (RSpec), `test_helper.rb` (Minitest) or `env.rb` (Cucumber).
111
123
 
112
124
 
113
- ### Including the JavaScript snippet
125
+ ### Including the JavaScript snippet (required)
114
126
 
115
127
  capybara-lockstep requires a JavaScript snippet to be embedded by the application under test. If that snippet is missing on a screen, capybara-lockstep will not be able to synchronize with the browser. In that case the test will continue without synchronization.
116
128
 
@@ -122,11 +134,31 @@ capybara-lockstep requires a JavaScript snippet to be embedded by the applicatio
122
134
 
123
135
  Ideally the snippet should be included in the `<head>` before any other `<script>` tags.
124
136
 
125
- **If you're not using Rails** you can `include Capybara::Lockstep::Helper` and access the JavaScript with `capybara_lockstep_script`.
137
+ **If you're not using Rails** you can `include Capybara::Lockstep::Helper` and access the JavaScript code with `capybara_lockstep_js`.
126
138
 
127
139
  **If you have a strict [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)** the `capybara_lockstep` Rails helper will insert a CSP nonce by default. You can also pass an explicit nonce string using the `:nonce` option.
128
140
 
129
141
 
142
+ ### Including the middleware (optional)
143
+
144
+ This gem provides a Rack middleware to block Capybara while your Rails (or Rack) backend is busy.
145
+
146
+ Using the middleware is optional, as the [JavaScript snippet](#including-the-javascript-snippet-required) already for AJAX requests on the client. However, using the middleware covers some additional edge cases. For example, the middleware detects requests that were aborted on the frontend, but are still being processed by the backend.
147
+
148
+ To include the middleware in a Rails application, add the following line to `config/environments/test.rb`:
149
+
150
+ ```ruby
151
+ config.middleware.insert_before 0, Capybara::Lockstep::Middleware
152
+ ```
153
+
154
+ In a **non-Rails** application you should include the middleware as high up in your middleware stack as possible:
155
+
156
+ ```ruby
157
+ use Capybara::Lockstep::Middleware
158
+ # Other middleware here
159
+ ```
160
+
161
+
130
162
 
131
163
  ### Verify successful integration
132
164
 
@@ -152,16 +184,22 @@ Note that you may see some failures from tests with wrong assertions, which prev
152
184
 
153
185
  ## Signaling asynchronous work
154
186
 
155
- By default capybara-lockstep waits until resources have loaded, AJAX requests have finished and their callbacks have been called.
187
+ [By default](#how-capybara-lockstep-helps) capybara-lockstep waits until resources have loaded, AJAX requests have finished and their callbacks have been called.
188
+ There are also some [limitations](#limitations).
189
+
190
+ You can configure capybara-lockstep to wait for other async work.
156
191
 
157
- You can configure capybara-lockstep to wait for other async work that does not involve the network. Let's say we have an animation that fades in a new element over 2 seconds. The following will prevent Capybara from observing the page while the animation is running:
192
+
193
+ ### On the frontend
194
+
195
+ Let's say we have an animation that fades in a new element over 2 seconds. The following will block Capybara while the animation is running:
158
196
 
159
197
  ```js
160
198
  async function fadeIn(element) {
161
- CapybaraLockstep.startWork('Animation')
199
+ CapybaraLockstep?.startWork('Animation')
162
200
  startAnimation(element, 'fade-in')
163
201
  await waitForAnimationEnd(element)
164
- CapybaraLockstep.stopWork('Animation')
202
+ CapybaraLockstep?.stopWork('Animation')
165
203
  }
166
204
  ```
167
205
 
@@ -175,20 +213,24 @@ The string argument is used for logging (when logging is enabled). It does **not
175
213
  You may omit the string argument, in which case nothing will be logged, but the work will still be tracked.
176
214
 
177
215
 
178
- ## Note on interacting with the JavaScript API
216
+ ### On the backend
179
217
 
180
- If you only load capybara-lockstep in tests you, should check for the `CapybaraLockstep` global to be defined before you interact with the JavaScript API.
218
+ You don't need to signal work within the regular request/response cycle, as this is detected automatically. You can however signal
219
+ work that happens outside a request, e.g. in a background job or WebSocket handler.
181
220
 
182
- ```js
183
- if (window.CapybaraLockstep) {
184
- // interact with CapybaraLockstep
185
- }
186
- ```
187
-
188
- If you can use ES6 you may also use [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining) to only call a function if `window.CapybaraLockstep` is defined:
221
+ The following will block Capybara while a [Sidekiq](https://sidekiq.org/) job is running:
189
222
 
190
- ```js
191
- window.CapybaraLockstep?.startWork('Work')
223
+ ```ruby
224
+ class HardJob
225
+ include Sidekiq::Job
226
+
227
+ def perform(name, count)
228
+ Capybara::Lockstep.start_work('HardJob') if defined?(Capybara::Lockstep)
229
+ # do something
230
+ ensure
231
+ Capybara::Lockstep.stop_work('StopWork') if defined?(Capybara::Lockstep)
232
+ end
233
+ end
192
234
  ```
193
235
 
194
236
 
@@ -335,14 +377,13 @@ It is theoretically possible that your test will observe the browser in that win
335
377
  Any issues caused by this will usually be mitigated by Capybara's retry logic. **If** you think that this is an issue for your test suite, you can configure capybara-headless to wait additional tasks before it considers the browser to be idle:
336
378
 
337
379
  ```ruby
338
- Capybara::Lockstep.wait_tasks = 1
380
+ Capybara::Lockstep.wait_tasks = 2 // default is 1
339
381
  ```
340
382
 
341
383
  If you see longer chains of `then()` or nested `setTimeout()` calls in your code, you may need to configure a higher number of tasks to wait.
342
384
 
343
385
  Waiting additional tasks will have a negative performance impact on your test suite.
344
386
 
345
- > **Note:** When capybara-lockstep detects jQuery on the page, it will automatically patch [`$.ajax()`](https://api.jquery.com/jQuery.ajax/) to wait an additional task after the response was received. If your only concern is callbacks to `$.ajax()` you do not need so set `Capybara::Lockstep.wait_tasks`.
346
387
 
347
388
 
348
389
  ## Running code after synchronization
data/Rakefile CHANGED
@@ -6,8 +6,6 @@ require "rspec/core/rake_task"
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  task default: :spec
9
- require 'jasmine'
10
- load 'jasmine/tasks/jasmine.rake'
11
9
 
12
10
  begin
13
11
  require 'gemika/tasks'
@@ -28,9 +28,9 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ["lib"]
29
29
 
30
30
  # Uncomment to register a new dependency of your gem
31
- spec.add_dependency "capybara", ">= 2.0"
32
- spec.add_dependency "selenium-webdriver", ">= 3"
33
- spec.add_dependency "activesupport", ">= 3.2"
31
+ spec.add_dependency "capybara", ">= 3.0"
32
+ spec.add_dependency "selenium-webdriver", ">= 4.0"
33
+ spec.add_dependency "activesupport", ">= 4.2"
34
34
  spec.add_dependency "ruby2_keywords"
35
35
 
36
36
  # For more information and examples about making a new gem, checkout our
@@ -7,6 +7,7 @@ module Capybara
7
7
  ERROR_SNIPPET_MISSING = 'Cannot synchronize: capybara-lockstep JavaScript snippet is missing'
8
8
  ERROR_PAGE_MISSING = 'Cannot synchronize with empty page'
9
9
  ERROR_ALERT_OPEN = 'Cannot synchronize while an alert is open'
10
+ ERROR_WINDOW_CLOSED = 'Cannot synchronize with closed window'
10
11
  ERROR_NAVIGATED_AWAY = "Browser navigated away while synchronizing"
11
12
 
12
13
  SYNCHRONIZED_IVAR = :@lockstep_synchronized_client
@@ -94,7 +95,11 @@ module Capybara
94
95
  end
95
96
  rescue ::Selenium::WebDriver::Error::UnexpectedAlertOpenError
96
97
  log ERROR_ALERT_OPEN
97
- # Don't raise an error, this will happen in an innocent test.
98
+ # Don't raise an error, this will happen in an innocent test where a click opens an alert.
99
+ # We will retry on the next Capybara synchronize call.
100
+ rescue ::Selenium::WebDriver::Error::NoSuchWindowError
101
+ log ERROR_WINDOW_CLOSED
102
+ # Don't raise an error, this will happen in an innocent test where a click closes a window.
98
103
  # We will retry on the next Capybara synchronize call.
99
104
  rescue ::Selenium::WebDriver::Error::JavascriptError => e
100
105
  # When the URL changes while a script is running, my current selenium-webdriver
@@ -53,6 +53,14 @@ module Capybara
53
53
  @mode = mode&.to_sym
54
54
  end
55
55
 
56
+ def with_mode(temporary_mode, &block)
57
+ old_mode = mode
58
+ self.mode = temporary_mode
59
+ block.call
60
+ ensure
61
+ self.mode = temporary_mode
62
+ end
63
+
56
64
  def enabled=(enabled)
57
65
  case enabled
58
66
  when true
@@ -284,7 +284,7 @@ window.CapybaraLockstep = (function() {
284
284
  // Only litter the log with interaction events if we're actually going
285
285
  // to be busy for at least 1 task.
286
286
  if (waitTasks > 0) {
287
- let tag = eventType + ' listeners'
287
+ let tag = eventType
288
288
  startWork(tag)
289
289
  stopWork(tag)
290
290
  }
@@ -301,6 +301,10 @@ window.CapybaraLockstep = (function() {
301
301
  trackInteraction('mousedown')
302
302
  trackInteraction('click')
303
303
  trackInteraction('keydown')
304
+ trackInteraction('focusin')
305
+ trackInteraction('focusout')
306
+ trackInteraction('input')
307
+ trackInteraction('change')
304
308
  }
305
309
 
306
310
  function synchronize(callback) {
@@ -19,7 +19,7 @@ module Capybara
19
19
  # to its `getLog` API. This causes Selenium to time out with a `Net::ReadTimeout` error
20
20
  page.driver.browser.switch_to.alert
21
21
  true
22
- rescue Capybara::NotSupportedByDriverError, ::Selenium::WebDriver::Error::NoSuchAlertError
22
+ rescue Capybara::NotSupportedByDriverError, ::Selenium::WebDriver::Error::NoSuchAlertError, ::Selenium::WebDriver::Error::NoSuchWindowError
23
23
  false
24
24
  end
25
25
 
@@ -1,5 +1,5 @@
1
1
  module Capybara
2
2
  module Lockstep
3
- VERSION = "2.0.0.rc1"
3
+ VERSION = "2.0.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara-lockstep
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.rc1
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henning Koch
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-19 00:00:00.000000000 Z
11
+ date: 2023-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capybara
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '3.0'
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: '2.0'
26
+ version: '3.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: selenium-webdriver
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '3'
33
+ version: '4.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '3'
40
+ version: '4.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3.2'
47
+ version: '4.2'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '3.2'
54
+ version: '4.2'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: ruby2_keywords
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -120,9 +120,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
120
120
  version: 2.4.0
121
121
  required_rubygems_version: !ruby/object:Gem::Requirement
122
122
  requirements:
123
- - - ">"
123
+ - - ">="
124
124
  - !ruby/object:Gem::Version
125
- version: 1.3.1
125
+ version: '0'
126
126
  requirements: []
127
127
  rubygems_version: 3.4.3
128
128
  signing_key: