capybara-lockstep 0.2.2 → 0.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 58ff0d51fafccaca566a89722c750b18db169331d57070c5db7d5de32620d648
4
- data.tar.gz: f6f859ded650d9b2dba0c43bbb7b19333e505ed57aa0d883b0a2981e5928f1a8
3
+ metadata.gz: aa8ccde381bb125f66222689d93c93008ec2137cfabc664a6ce83ff0701cd7a8
4
+ data.tar.gz: 7485b88104f0c4b43387f252e600ad7dc23a917eac28914249b8f279d5ab9df3
5
5
  SHA512:
6
- metadata.gz: 4c1ba4546483509650a7423d04e0acffaf286db556ae431152076478e5d2ca7611a915e9f666c077d9c9c205cb4703d2cf29341e52a0b39493c4b11b78e6a883
7
- data.tar.gz: 1e890d3d985af8ce4d623778781cfc06a1242d83d1c93b98bc550997e3044066544dc15100ccdb28e89090e1b865d7720200a84f8461984655b0f87fcf795281
6
+ metadata.gz: 19f52ab1ca0e9f30fe8be0e791b66bcefe9992d958a104a30c602987e310363587f075f7af19bebf8248e76836a008601c700092bc3b1d53fff3fda5b764dcdc
7
+ data.tar.gz: e6380494b6940092842f87e54c898e6a2da9311aa2fd1951a602fb193fb44c7ee6f96907704d80382bd1cc2ccc31a7e0b433e27da8906f889aa6f7178fcd2dff
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- capybara-lockstep (0.2.2)
4
+ capybara-lockstep (0.2.3)
5
5
  activesupport (>= 3.2)
6
6
  capybara (>= 2.0)
7
7
  selenium-webdriver (>= 3)
@@ -9,11 +9,12 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activesupport (5.2.4.3)
12
+ activesupport (6.1.3)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
- i18n (>= 0.7, < 2)
15
- minitest (~> 5.1)
16
- tzinfo (~> 1.1)
14
+ i18n (>= 1.6, < 2)
15
+ minitest (>= 5.1)
16
+ tzinfo (~> 2.0)
17
+ zeitwerk (~> 2.3)
17
18
  addressable (2.7.0)
18
19
  public_suffix (>= 2.0.2, < 5.0)
19
20
  capybara (3.35.3)
@@ -25,13 +26,15 @@ GEM
25
26
  regexp_parser (>= 1.5, < 3.0)
26
27
  xpath (~> 3.2)
27
28
  childprocess (3.0.0)
28
- concurrent-ruby (1.1.7)
29
+ concurrent-ruby (1.1.8)
29
30
  diff-lcs (1.3)
30
- i18n (1.8.2)
31
+ i18n (1.8.9)
31
32
  concurrent-ruby (~> 1.0)
32
33
  mini_mime (1.0.2)
33
- minitest (5.14.1)
34
- nokogiri (1.11.1-x86_64-linux)
34
+ mini_portile2 (2.5.0)
35
+ minitest (5.14.4)
36
+ nokogiri (1.11.1)
37
+ mini_portile2 (~> 2.5.0)
35
38
  racc (~> 1.4)
36
39
  public_suffix (4.0.6)
37
40
  racc (1.5.2)
@@ -53,15 +56,15 @@ GEM
53
56
  diff-lcs (>= 1.2.0, < 2.0)
54
57
  rspec-support (~> 3.7.0)
55
58
  rspec-support (3.7.0)
56
- rubyzip (1.3.0)
59
+ rubyzip (2.3.0)
57
60
  selenium-webdriver (3.142.7)
58
61
  childprocess (>= 0.5, < 4.0)
59
62
  rubyzip (>= 1.2.2)
60
- thread_safe (0.3.6)
61
- tzinfo (1.2.7)
62
- thread_safe (~> 0.1)
63
+ tzinfo (2.0.4)
64
+ concurrent-ruby (~> 1.0)
63
65
  xpath (3.2.0)
64
66
  nokogiri (~> 1.8)
67
+ zeitwerk (2.4.2)
65
68
 
66
69
  PLATFORMS
67
70
  ruby
data/README.md CHANGED
@@ -59,7 +59,7 @@ Installation
59
59
  Check if your application satisfies all requirements for capybara-lockstep:
60
60
 
61
61
  - Capybara 2 or higher.
62
- - Your Capybara driver must use [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/). capybara-headless deactivates itself for any other driver.
62
+ - Your Capybara driver must use [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/). capybara-lockstep deactivates itself for any other driver.
63
63
  - 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.
64
64
  - This gem was only tested with Rails, but there's no Rails dependency.
65
65
 
@@ -1,24 +1,38 @@
1
1
  module Capybara
2
2
  module Lockstep
3
3
  module VisitWithWaiting
4
- def visit(*args, **kwargs, &block)
5
- super(*args, **kwargs, &block).tap do
4
+ def visit(*args, &block)
5
+ visiting_remote_url = !args[0].start_with?('data:')
6
+
7
+ Capybara::Lockstep.catch_up
8
+
9
+ super(*args, &block).tap do
6
10
  # There is a step that changes drivers mid-scenario.
7
11
  # It works by creating a new Capybara session and re-visits the
8
12
  # URL from the previous session. If this happens before a URL is ever
9
13
  # loaded, it re-visits the URL "data:", which will never "finish"
10
14
  # initializing.
11
- unless args[0].start_with?('data:')
15
+ if visiting_remote_url
12
16
  Capybara::Lockstep.await_initialized
13
17
  end
14
18
  end
15
19
  end
16
20
  end
21
+ end
22
+ end
17
23
 
24
+
25
+ Capybara::Session.class_eval do
26
+ prepend Capybara::Lockstep::VisitWithWaiting
27
+ end
28
+
29
+ module Capybara
30
+ module Lockstep
18
31
  module AwaitIdle
19
32
  def await_idle(meth)
20
33
  mod = Module.new do
21
34
  define_method meth do |*args, &block|
35
+ Capybara::Lockstep.catch_up
22
36
  super(*args, &block).tap do
23
37
  Capybara::Lockstep.await_idle
24
38
  end
@@ -30,10 +44,6 @@ module Capybara
30
44
  end
31
45
  end
32
46
 
33
- Capybara::Session.class_eval do
34
- prepend Capybara::Lockstep::VisitWithWaiting
35
- end
36
-
37
47
  # Capybara 3 has driver-specific Node classes which sometimes
38
48
  # super to Capybara::Selenium::Node, but not always.
39
49
  node_classes = [
@@ -69,3 +79,19 @@ node_classes.each do |node_class|
69
79
  await_idle :trigger
70
80
  end
71
81
  end
82
+
83
+ module Capybara
84
+ module Lockstep
85
+ module SynchronizeWithCatchUp
86
+ def synchronize(*args, &block)
87
+ Capybara::Lockstep.catch_up
88
+
89
+ super(*args, &block)
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ Capybara::Node::Base.class_eval do
96
+ prepend Capybara::Lockstep::SynchronizeWithCatchUp
97
+ end
@@ -5,25 +5,28 @@ module Capybara
5
5
  include Configuration
6
6
 
7
7
  def await_idle
8
+ @delay_await_idle = false
8
9
  return unless enabled?
9
10
 
10
- ignoring_alerts do
11
- # evaluate_async_script also times out after Capybara.default_max_wait_time
12
- with_max_wait_time(timeout) do
13
- message_from_js = evaluate_async_script(<<~JS)
14
- let done = arguments[0]
15
- if (window.CapybaraLockstep) {
16
- CapybaraLockstep.awaitIdle(done)
17
- } else {
18
- done('Cannot synchronize: Capybara::Lockstep was not included in page')
19
- }
20
- JS
21
- log(message_from_js)
22
- end
11
+ with_max_wait_time(timeout) do
12
+ message_from_js = evaluate_async_script(<<~JS)
13
+ let done = arguments[0]
14
+ if (window.CapybaraLockstep) {
15
+ CapybaraLockstep.awaitIdle(done)
16
+ } else {
17
+ done('Cannot synchronize: Capybara::Lockstep was not included in page')
18
+ }
19
+ JS
20
+ log(message_from_js)
23
21
  end
22
+ rescue ::Selenium::WebDriver::Error::UnexpectedAlertOpenError
23
+ log 'Cannot synchronize: Alert is open'
24
+ @delay_await_idle = true
24
25
  end
25
26
 
26
27
  def await_initialized
28
+ @delay_await_initialized = false
29
+ @delay_await_idle = false # since we're also waiting for idle
27
30
  return unless enabled?
28
31
 
29
32
  # We're retrying the initialize check every few ms.
@@ -41,6 +44,29 @@ module Capybara
41
44
  raise Busy, reason
42
45
  end
43
46
  end
47
+ rescue ::Selenium::WebDriver::Error::UnexpectedAlertOpenError
48
+ log 'Cannot synchronize: Alert is open'
49
+ @delay_await_initialized = true
50
+ end
51
+
52
+ def catch_up
53
+ return if @catching_up
54
+
55
+ begin
56
+ @catching_up = true
57
+ if @delay_await_initialized
58
+ log 'Retrying synchronization'
59
+ await_initialized
60
+ # elsif browser_made_full_page_load?
61
+ # log 'Browser loaded new page'
62
+ # await_initialized
63
+ elsif @delay_await_idle
64
+ log 'Retrying synchronization'
65
+ await_idle
66
+ end
67
+ ensure
68
+ @catching_up = false
69
+ end
44
70
  end
45
71
 
46
72
  def idle?
@@ -72,31 +98,34 @@ module Capybara
72
98
 
73
99
  private
74
100
 
101
+ def browser_made_full_page_load?
102
+ # Page change without visit()
103
+ page.has_css?('body[data-hydrating]')
104
+ end
105
+
75
106
  def initialize_reason
76
- ignoring_alerts do
77
- execute_script(<<~JS)
78
- if (location.href.indexOf('data:') == 0) {
79
- return 'Requesting initial page'
80
- }
107
+ execute_script(<<~JS)
108
+ if (location.href.indexOf('data:') == 0) {
109
+ return 'Requesting initial page'
110
+ }
81
111
 
82
- if (document.readyState !== "complete") {
83
- return 'Document is loading'
84
- }
112
+ if (document.readyState !== "complete") {
113
+ return 'Document is loading'
114
+ }
85
115
 
86
- // The application layouts render a <body data-initializing>.
87
- // The [data-initializing] attribute is removed by an Angular directive or Unpoly compiler (frontend).
88
- // to signal that all elements have been activated.
89
- if (document.querySelector('body[data-initializing]')) {
90
- return 'DOM is being hydrated'
91
- }
116
+ // The application layouts render a <body data-initializing>.
117
+ // The [data-initializing] attribute is removed by an Angular directive or Unpoly compiler (frontend).
118
+ // to signal that all elements have been activated.
119
+ if (document.querySelector('body[data-initializing]')) {
120
+ return 'DOM is being hydrated'
121
+ }
92
122
 
93
- if (window.CapybaraLockstep && CapybaraLockstep.isBusy()) {
94
- return 'JavaScript or AJAX requests are running'
95
- }
123
+ if (window.CapybaraLockstep && CapybaraLockstep.isBusy()) {
124
+ return 'JavaScript or AJAX requests are running'
125
+ }
96
126
 
97
- return false
98
- JS
99
- end
127
+ return false
128
+ JS
100
129
  end
101
130
 
102
131
  def page
@@ -105,12 +134,6 @@ module Capybara
105
134
 
106
135
  delegate :evaluate_script, :evaluate_async_script, :execute_script, :driver, to: :page
107
136
 
108
- def ignoring_alerts(&block)
109
- block.call
110
- rescue ::Selenium::WebDriver::Error::UnexpectedAlertOpenError
111
- # noop
112
- end
113
-
114
137
  def with_max_wait_time(seconds, &block)
115
138
  old_max_wait_time = Capybara.default_max_wait_time
116
139
  Capybara.default_max_wait_time = seconds
@@ -1,5 +1,5 @@
1
1
  module Capybara
2
2
  module Lockstep
3
- VERSION = "0.2.2"
3
+ VERSION = "0.2.3"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara-lockstep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henning Koch