ask-web-fetch 0.5.2 → 0.5.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 +4 -4
- data/lib/ask/web_fetch/backends/attached_browser.rb +53 -7
- data/lib/ask/web_fetch/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed798fddd5578a39814ea41425937d4e539827dae6c66a8e9bc1621007f5dcda
|
|
4
|
+
data.tar.gz: 698add682f0ce4f056acfee23130748bb6d359acb8004a07efc6b862dcc462da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0aa82e97aef13e08d736024d4927a96a72a554ec1cda21292d501884787ad82e756c51522a179ebfd81bdbcd5baadef6965254957613044e088e511accdfb4f1
|
|
7
|
+
data.tar.gz: e5d46eef13701008e7c4557675d372b6c4776f38f19b75be4559943b675def5d9370006cb9ef10416a7b70f6a3897f54b7c14f4afff409afd590dee0fa068ac7
|
|
@@ -50,6 +50,9 @@ module Ask
|
|
|
50
50
|
@session = @client.session(
|
|
51
51
|
@client.command('Target.attachToTarget', targetId: @target_id, flatten: true)['sessionId']
|
|
52
52
|
)
|
|
53
|
+
# Subscribed BEFORE any navigation so the idle wait sees the
|
|
54
|
+
# page's real load traffic (lazy SPAs render in waves).
|
|
55
|
+
@network = Network.new(self)
|
|
53
56
|
end
|
|
54
57
|
|
|
55
58
|
# Navigates and does not return until the document has actually
|
|
@@ -65,7 +68,6 @@ module Ask
|
|
|
65
68
|
|
|
66
69
|
wait_for_load
|
|
67
70
|
end
|
|
68
|
-
|
|
69
71
|
def title
|
|
70
72
|
evaluate('document.title')
|
|
71
73
|
end
|
|
@@ -78,11 +80,11 @@ module Ask
|
|
|
78
80
|
evaluate('document.documentElement.outerHTML') || ''
|
|
79
81
|
end
|
|
80
82
|
|
|
81
|
-
# Minimal network facade for the Browser backend
|
|
82
|
-
#
|
|
83
|
-
#
|
|
83
|
+
# Minimal network facade for the Browser backend: status from the
|
|
84
|
+
# Navigation Timing API, idle from CDP Network events (subscribed
|
|
85
|
+
# in the constructor, before navigation).
|
|
84
86
|
def network
|
|
85
|
-
@network
|
|
87
|
+
@network
|
|
86
88
|
end
|
|
87
89
|
|
|
88
90
|
def close
|
|
@@ -122,10 +124,22 @@ module Ask
|
|
|
122
124
|
nil
|
|
123
125
|
end
|
|
124
126
|
|
|
125
|
-
#
|
|
127
|
+
# Real network-idle detection for the attached browser, via CDP's
|
|
128
|
+
# Network domain events. The launched-browser path gets idle
|
|
129
|
+
# waiting from Ferrum's network; the attached path previously
|
|
130
|
+
# skipped it entirely (a no-op), which read lazy-loading SPAs too
|
|
131
|
+
# early — reddit's post list renders in waves, and the fetch saw
|
|
132
|
+
# only the first 2.6k of an 8k+ body. Tracks requestStarted /
|
|
133
|
+
# requestFinished events on the page session and waits until the
|
|
134
|
+
# network has been quiet for +duration+, capped at +timeout+.
|
|
126
135
|
class Network
|
|
127
136
|
def initialize(page)
|
|
128
137
|
@page = page
|
|
138
|
+
@session = page.instance_variable_get(:@session)
|
|
139
|
+
@in_flight = 0
|
|
140
|
+
@quiet_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
141
|
+
@mutex = Mutex.new
|
|
142
|
+
subscribe
|
|
129
143
|
end
|
|
130
144
|
|
|
131
145
|
def status
|
|
@@ -137,7 +151,39 @@ module Ask
|
|
|
137
151
|
0
|
|
138
152
|
end
|
|
139
153
|
|
|
140
|
-
def wait_for_idle(
|
|
154
|
+
def wait_for_idle(duration:, timeout:)
|
|
155
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout
|
|
156
|
+
loop do
|
|
157
|
+
quiet = @mutex.synchronize { @in_flight.zero? }
|
|
158
|
+
if quiet && Process.clock_gettime(Process::CLOCK_MONOTONIC) - @quiet_since >= duration
|
|
159
|
+
return
|
|
160
|
+
end
|
|
161
|
+
raise Ferrum::TimeoutError, "network did not go idle within #{timeout}s" if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline
|
|
162
|
+
|
|
163
|
+
sleep 0.1
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
private
|
|
168
|
+
|
|
169
|
+
# CDP events arrive on the session's message loop; Ferrum's
|
|
170
|
+
# session dispatches them to subscribed handlers. Track the
|
|
171
|
+
# request lifecycle so "quiet" means no request has been in
|
|
172
|
+
# flight for the duration — the signal lazy SPAs settle on.
|
|
173
|
+
# Defensive: a minimal/mock session without event support
|
|
174
|
+
# (some test doubles) just skips subscription — the load-wait
|
|
175
|
+
# in go_to is still the floor.
|
|
176
|
+
def subscribe
|
|
177
|
+
return unless @session.respond_to?(:on)
|
|
178
|
+
|
|
179
|
+
@session.on('Network.requestWillBeSent') { @mutex.synchronize { @in_flight += 1 } }
|
|
180
|
+
@session.on('Network.responseReceived') { @mutex.synchronize { @quiet_since = Process.clock_gettime(Process::CLOCK_MONOTONIC) } }
|
|
181
|
+
@session.on('Network.loadingFinished') { @mutex.synchronize { @in_flight -= 1 if @in_flight.positive? } }
|
|
182
|
+
@session.on('Network.loadingFailed') { @mutex.synchronize { @in_flight -= 1 if @in_flight.positive? } }
|
|
183
|
+
@session.command('Network.enable')
|
|
184
|
+
rescue Ferrum::Error
|
|
185
|
+
# Some attached browsers reject Network.enable (unlikely);
|
|
186
|
+
# fall back to the load-wait already done in go_to.
|
|
141
187
|
nil
|
|
142
188
|
end
|
|
143
189
|
end
|