apparition 0.1.0 → 0.6.0
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/README.md +40 -4
- data/lib/capybara/apparition.rb +0 -2
- data/lib/capybara/apparition/browser.rb +75 -133
- data/lib/capybara/apparition/browser/cookie.rb +4 -16
- data/lib/capybara/apparition/browser/header.rb +2 -2
- data/lib/capybara/apparition/browser/launcher.rb +25 -0
- data/lib/capybara/apparition/browser/launcher/local.rb +213 -0
- data/lib/capybara/apparition/browser/launcher/remote.rb +55 -0
- data/lib/capybara/apparition/browser/page_manager.rb +90 -0
- data/lib/capybara/apparition/browser/window.rb +29 -29
- data/lib/capybara/apparition/configuration.rb +100 -0
- data/lib/capybara/apparition/console.rb +8 -1
- data/lib/capybara/apparition/dev_tools_protocol/remote_object.rb +23 -7
- data/lib/capybara/apparition/dev_tools_protocol/session.rb +3 -4
- data/lib/capybara/apparition/driver.rb +107 -35
- data/lib/capybara/apparition/driver/chrome_client.rb +13 -8
- data/lib/capybara/apparition/driver/response.rb +1 -1
- data/lib/capybara/apparition/driver/web_socket_client.rb +1 -0
- data/lib/capybara/apparition/errors.rb +3 -3
- data/lib/capybara/apparition/network_traffic/error.rb +1 -0
- data/lib/capybara/apparition/network_traffic/request.rb +5 -5
- data/lib/capybara/apparition/node.rb +142 -50
- data/lib/capybara/apparition/node/drag.rb +165 -65
- data/lib/capybara/apparition/page.rb +180 -142
- data/lib/capybara/apparition/page/frame.rb +3 -0
- data/lib/capybara/apparition/page/frame_manager.rb +2 -1
- data/lib/capybara/apparition/page/keyboard.rb +29 -7
- data/lib/capybara/apparition/page/mouse.rb +20 -6
- data/lib/capybara/apparition/utility.rb +1 -1
- data/lib/capybara/apparition/version.rb +1 -1
- metadata +53 -23
- data/lib/capybara/apparition/dev_tools_protocol/target.rb +0 -64
- data/lib/capybara/apparition/dev_tools_protocol/target_manager.rb +0 -48
- data/lib/capybara/apparition/driver/launcher.rb +0 -217
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a8ccd4ce950f7c17f8ab0ac0c5ddcbbc13a336f428011d66f4b3cb028ced150
|
4
|
+
data.tar.gz: c524d1e955e3e4e958d0bd64350190eec6f53c7f612a6bd1b41867c05ab11427
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d772071df2776e86a611a07b718eb3c411cf9048e466d66515920261f6aa8b6705ddd1559d3fa8c8728fe3510a58b37b82986d698ad17f5add7f7399a9d4fc8
|
7
|
+
data.tar.gz: bdd2bdfba3591b9a798cc820ff4dd8ce7d90af853f79c716828e3bbb2a51810c0e2f4705c16181b9284533569bd4f050fa94d95f1b62d3c5fc2880d29d817a72
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](http://travis-ci.org/twalpole/apparition)
|
4
4
|
|
5
|
-
Apparition is a driver for [Capybara](https://github.com/
|
5
|
+
Apparition is a driver for [Capybara](https://github.com/teamcapybara/capybara). It allows you to
|
6
6
|
run your Capybara tests in the Chrome browser via CDP (no selenium or chromedriver needed) in a headless or
|
7
7
|
headed configuration. It started as a fork of Poltergeist and attempts to maintain as much compatibility
|
8
8
|
with the Poltergeist API as possible. Implementing the `capybara-webkit` specific driver methods has also begun.
|
@@ -27,7 +27,7 @@ gem 'apparition'
|
|
27
27
|
or
|
28
28
|
|
29
29
|
``` ruby
|
30
|
-
gem apparition', github: 'twalpole/apparition'
|
30
|
+
gem 'apparition', github: 'twalpole/apparition'
|
31
31
|
```
|
32
32
|
|
33
33
|
to your Gemfile and run `bundle install`.
|
@@ -82,6 +82,29 @@ same as for `save_screenshot`.
|
|
82
82
|
Sometimes its desirable to click a very specific area of the screen. You can accomplish this with
|
83
83
|
`page.driver.click(x, y)`, where x and y are the screen coordinates.
|
84
84
|
|
85
|
+
### Remote debugging (not yet implemented) ###
|
86
|
+
|
87
|
+
If you use the `:inspector => true` option (see below), remote debugging
|
88
|
+
will be enabled.
|
89
|
+
|
90
|
+
When this option is enabled, you can insert `page.driver.debug` into
|
91
|
+
your tests to pause the test and launch a browser which gives you the
|
92
|
+
WebKit inspector to view your test run with.
|
93
|
+
|
94
|
+
You can register this debugger driver with a different name and set it
|
95
|
+
as the current javascript driver. By example, in your helper file:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
Capybara.register_driver :apparition_debug do |app|
|
99
|
+
Capybara::Apparition::Driver.new(app, :inspector => true)
|
100
|
+
end
|
101
|
+
# Capybara.javascript_driver = :apparition
|
102
|
+
Capybara.javascript_driver = :apparition_debug
|
103
|
+
```
|
104
|
+
|
105
|
+
[Read more
|
106
|
+
here](https://www.jonathanleighton.com/articles/2012/poltergeist-0-6-0/)
|
107
|
+
|
85
108
|
### Manipulating request headers ###
|
86
109
|
|
87
110
|
You can manipulate HTTP request headers with these methods:
|
@@ -156,8 +179,9 @@ end
|
|
156
179
|
`options` is a hash of options. The following options are supported:
|
157
180
|
|
158
181
|
* `:headless` (Boolean) - When false, run the browser visibly
|
182
|
+
* `:remote` (Boolean) - When true, connect to remote browser instead of starting locally (see [below](#Remote Chrome Driver))
|
159
183
|
* `:debug` (Boolean) - When true, debug output is logged to `STDERR`.
|
160
|
-
* `:logger` (
|
184
|
+
* `:logger` (Ruby logger object or any object responding to `puts`) - When present, debug output is written to this object
|
161
185
|
* `:browser_logger` (`IO` object) - This is where your `console.log` statements will show up. Default: `STDOUT`
|
162
186
|
* `:timeout` (Numeric) - The number of seconds we'll wait for a response
|
163
187
|
when communicating with Chrome. Default is 30.
|
@@ -175,6 +199,18 @@ end
|
|
175
199
|
* `:browser_options` (Hash) - Extra command line options to pass to Chrome when starting
|
176
200
|
* `:skip_image_loading` (Boolean) - Don't load images
|
177
201
|
|
202
|
+
### Remote Chrome Driver ###
|
203
|
+
Apparition can connect to already running instance of chrome.
|
204
|
+
Remote mode is useful when running tests in CI and chrome is available as separate docker container.
|
205
|
+
|
206
|
+
In order to use remote browser - set up apparition in the following way:
|
207
|
+
```ruby
|
208
|
+
Capybara.register_driver :apparition do |app|
|
209
|
+
browser_options = { 'remote-debugging-address' => '127.0.0.1', 'remote-debugging-port' => 9999 }
|
210
|
+
Capybara::Apparition::Driver.new(app, remote: true, browser_options: browser_options)
|
211
|
+
end
|
212
|
+
```
|
213
|
+
|
178
214
|
### URL Blacklisting & Whitelisting ###
|
179
215
|
Apparition supports URL blacklisting, which allows you
|
180
216
|
to prevent scripts from running on designated domains:
|
@@ -205,7 +241,7 @@ test to allow sufficient time for the page to settle.
|
|
205
241
|
|
206
242
|
If you have these types of problems, read through the [Capybara
|
207
243
|
documentation on asynchronous
|
208
|
-
JavaScript](https://github.com/
|
244
|
+
JavaScript](https://github.com/teamcapybara/capybara#asynchronous-javascript-ajax-and-friends)
|
209
245
|
which explains the tools that Capybara provides for dealing with this.
|
210
246
|
|
211
247
|
### Filing a bug ###
|
data/lib/capybara/apparition.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'capybara/apparition/errors'
|
4
|
-
require 'capybara/apparition/dev_tools_protocol/target_manager'
|
5
4
|
require 'capybara/apparition/page'
|
6
5
|
require 'capybara/apparition/console'
|
6
|
+
require 'capybara/apparition/dev_tools_protocol/session'
|
7
7
|
require 'capybara/apparition/browser/header'
|
8
8
|
require 'capybara/apparition/browser/window'
|
9
9
|
require 'capybara/apparition/browser/render'
|
10
10
|
require 'capybara/apparition/browser/cookie'
|
11
11
|
require 'capybara/apparition/browser/modal'
|
12
|
+
require 'capybara/apparition/browser/page_manager'
|
12
13
|
require 'capybara/apparition/browser/frame'
|
13
14
|
require 'capybara/apparition/browser/auth'
|
14
15
|
require 'json'
|
@@ -17,6 +18,7 @@ require 'time'
|
|
17
18
|
module Capybara::Apparition
|
18
19
|
class Browser
|
19
20
|
attr_reader :client, :paper_size, :zoom_factor, :console, :proxy_auth
|
21
|
+
|
20
22
|
extend Forwardable
|
21
23
|
|
22
24
|
delegate %i[visit current_url status_code
|
@@ -30,7 +32,7 @@ module Capybara::Apparition
|
|
30
32
|
def initialize(client, logger = nil)
|
31
33
|
@client = client
|
32
34
|
@current_page_handle = nil
|
33
|
-
@
|
35
|
+
@pages = PageManager.new(self)
|
34
36
|
@context_id = nil
|
35
37
|
@js_errors = true
|
36
38
|
@ignore_https_errors = false
|
@@ -41,15 +43,12 @@ module Capybara::Apparition
|
|
41
43
|
initialize_handlers
|
42
44
|
|
43
45
|
command('Target.setDiscoverTargets', discover: true)
|
44
|
-
|
45
|
-
|
46
|
-
sleep 0.1
|
47
|
-
end
|
48
|
-
@context_id = current_target.context_id
|
46
|
+
yield self if block_given?
|
47
|
+
reset
|
49
48
|
end
|
50
49
|
|
51
50
|
def restart
|
52
|
-
puts 'handle client restart'
|
51
|
+
# puts 'handle client restart'
|
53
52
|
# client.restart
|
54
53
|
|
55
54
|
self.debug = @debug if defined?(@debug)
|
@@ -81,34 +80,43 @@ module Capybara::Apparition
|
|
81
80
|
include Auth
|
82
81
|
|
83
82
|
def reset
|
84
|
-
current_page_targets = @targets.of_type('page').values
|
85
|
-
|
86
83
|
new_context_id = command('Target.createBrowserContext')['browserContextId']
|
87
84
|
new_target_response = client.send_cmd('Target.createTarget', url: 'about:blank', browserContextId: new_context_id)
|
88
85
|
|
89
|
-
|
90
|
-
begin
|
91
|
-
client.send_cmd('Target.disposeBrowserContext', browserContextId: target.context_id).discard_result
|
92
|
-
rescue WrongWorld
|
93
|
-
puts 'Unknown browserContextId'
|
94
|
-
end
|
95
|
-
@targets.delete(target.id)
|
96
|
-
end
|
86
|
+
@pages.reset
|
97
87
|
|
98
88
|
new_target_id = new_target_response['targetId']
|
99
89
|
|
90
|
+
session_id = command('Target.attachToTarget', targetId: new_target_id)['sessionId']
|
91
|
+
session = Capybara::Apparition::DevToolsProtocol::Session.new(self, client, session_id)
|
92
|
+
|
93
|
+
@pages.create(new_target_id, session, new_context_id,
|
94
|
+
ignore_https_errors: ignore_https_errors,
|
95
|
+
js_errors: js_errors, extensions: @extensions,
|
96
|
+
url_blacklist: @url_blacklist,
|
97
|
+
url_whitelist: @url_whitelist).send(:main_frame).loaded!
|
98
|
+
|
100
99
|
timer = Capybara::Helpers.timer(expire_in: 10)
|
101
|
-
until @
|
100
|
+
until @pages[new_target_id].usable?
|
102
101
|
if timer.expired?
|
103
102
|
puts 'Timedout waiting for reset'
|
104
|
-
raise TimeoutError
|
103
|
+
raise TimeoutError, 'reset'
|
105
104
|
end
|
106
105
|
sleep 0.01
|
107
106
|
end
|
107
|
+
console.clear
|
108
108
|
@current_page_handle = new_target_id
|
109
109
|
true
|
110
110
|
end
|
111
111
|
|
112
|
+
def refresh_pages(opener:)
|
113
|
+
@pages.refresh(opener: opener,
|
114
|
+
ignore_https_errors: ignore_https_errors,
|
115
|
+
js_errors: js_errors,
|
116
|
+
url_blacklist: @url_blacklist,
|
117
|
+
url_whitelist: @url_whitelist)
|
118
|
+
end
|
119
|
+
|
112
120
|
def resize(width, height, screen: nil)
|
113
121
|
current_page.set_viewport width: width, height: height, screen: screen
|
114
122
|
end
|
@@ -127,20 +135,16 @@ module Capybara::Apparition
|
|
127
135
|
def extensions=(filenames)
|
128
136
|
@extensions = filenames
|
129
137
|
Array(filenames).each do |name|
|
130
|
-
|
131
|
-
current_page.command('Page.addScriptToEvaluateOnNewDocument', source: File.read(name))
|
132
|
-
rescue Errno::ENOENT
|
133
|
-
raise ::Capybara::Apparition::BrowserError.new('name' => "Unable to load extension: #{name}", 'args' => nil)
|
134
|
-
end
|
138
|
+
current_page(allow_nil: true)&.add_extension(name)
|
135
139
|
end
|
136
140
|
end
|
137
141
|
|
138
142
|
def url_whitelist=(whitelist)
|
139
|
-
|
143
|
+
@url_whitelist = @pages.whitelist = whitelist
|
140
144
|
end
|
141
145
|
|
142
146
|
def url_blacklist=(blacklist)
|
143
|
-
|
147
|
+
@url_blacklist = @pages.blacklist = blacklist
|
144
148
|
end
|
145
149
|
|
146
150
|
attr_writer :debug
|
@@ -149,7 +153,7 @@ module Capybara::Apparition
|
|
149
153
|
current_page.command('Network.clearBrowserCache')
|
150
154
|
end
|
151
155
|
|
152
|
-
def command(name, params
|
156
|
+
def command(name, **params)
|
153
157
|
result = client.send_cmd(name, params).result
|
154
158
|
log result
|
155
159
|
|
@@ -166,8 +170,14 @@ module Capybara::Apparition
|
|
166
170
|
raise
|
167
171
|
end
|
168
172
|
|
169
|
-
def current_page
|
170
|
-
|
173
|
+
def current_page(allow_nil: false)
|
174
|
+
@pages[@current_page_handle] || begin
|
175
|
+
puts "No current page: #{@current_page_handle} : #{caller}" if ENV['DEBUG']
|
176
|
+
@current_page_handle = nil
|
177
|
+
raise NoSuchWindowError unless allow_nil
|
178
|
+
|
179
|
+
@current_page_handle
|
180
|
+
end
|
171
181
|
end
|
172
182
|
|
173
183
|
def console_messages(type = nil)
|
@@ -176,115 +186,47 @@ module Capybara::Apparition
|
|
176
186
|
|
177
187
|
private
|
178
188
|
|
179
|
-
def current_target
|
180
|
-
@targets.get(@current_page_handle) || begin
|
181
|
-
puts "No current page: #{@current_page_handle}"
|
182
|
-
puts caller
|
183
|
-
@current_page_handle = nil
|
184
|
-
raise NoSuchWindowError
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
189
|
def log(message)
|
189
|
-
@logger
|
190
|
-
end
|
191
|
-
|
192
|
-
# KEY_ALIASES = {
|
193
|
-
# command: :Meta,
|
194
|
-
# equals: :Equal,
|
195
|
-
# control: :Control,
|
196
|
-
# ctrl: :Control,
|
197
|
-
# multiply: 'numpad*',
|
198
|
-
# add: 'numpad+',
|
199
|
-
# divide: 'numpad/',
|
200
|
-
# subtract: 'numpad-',
|
201
|
-
# decimal: 'numpad.',
|
202
|
-
# left: 'ArrowLeft',
|
203
|
-
# right: 'ArrowRight',
|
204
|
-
# down: 'ArrowDown',
|
205
|
-
# up: 'ArrowUp'
|
206
|
-
# }.freeze
|
207
|
-
#
|
208
|
-
# def normalize_keys(keys)
|
209
|
-
# keys.map do |key_desc|
|
210
|
-
# case key_desc
|
211
|
-
# when Array
|
212
|
-
# # [:Shift, "s"] => { modifier: "shift", keys: "S" }
|
213
|
-
# # [:Shift, "string"] => { modifier: "shift", keys: "STRING" }
|
214
|
-
# # [:Ctrl, :Left] => { modifier: "ctrl", key: 'Left' }
|
215
|
-
# # [:Ctrl, :Shift, :Left] => { modifier: "ctrl,shift", key: 'Left' }
|
216
|
-
# # [:Ctrl, :Left, :Left] => { modifier: "ctrl", key: [:Left, :Left] }
|
217
|
-
# keys_chunks = key_desc.chunk do |k|
|
218
|
-
# k.is_a?(Symbol) && %w[shift ctrl control alt meta command].include?(k.to_s.downcase)
|
219
|
-
# end
|
220
|
-
# modifiers = modifiers_from_chunks(keys_chunks)
|
221
|
-
# letters = normalize_keys(_keys.next[1].map { |k| k.is_a?(String) ? k.upcase : k })
|
222
|
-
# { modifier: modifiers, keys: letters }
|
223
|
-
# when Symbol
|
224
|
-
# symbol_to_desc(key_desc)
|
225
|
-
# when String
|
226
|
-
# key_desc # Plain string, nothing to do
|
227
|
-
# end
|
228
|
-
# end
|
229
|
-
# end
|
230
|
-
#
|
231
|
-
# def modifiers_from_chunks(chunks)
|
232
|
-
# if chunks.peek[0]
|
233
|
-
# chunks.next[1].map do |k|
|
234
|
-
# k = k.to_s.downcase
|
235
|
-
# k = 'control' if k == 'ctrl'
|
236
|
-
# k = 'meta' if k == 'command'
|
237
|
-
# k
|
238
|
-
# end.join(',')
|
239
|
-
# else
|
240
|
-
# ''
|
241
|
-
# end
|
242
|
-
# end
|
243
|
-
#
|
244
|
-
# def symbol_to_desc(symbol)
|
245
|
-
# if symbol == :space
|
246
|
-
# res = ' '
|
247
|
-
# else
|
248
|
-
# key = KEY_ALIASES.fetch(symbol.downcase, symbol)
|
249
|
-
# if (match = key.to_s.match(/numpad(.)/))
|
250
|
-
# res = { keys: match[1], modifier: 'keypad' }
|
251
|
-
# elsif !/^[A-Z]/.match?(key)
|
252
|
-
# key = key.to_s.split('_').map(&:capitalize).join
|
253
|
-
# end
|
254
|
-
# end
|
255
|
-
# res || { key: key }
|
256
|
-
# end
|
190
|
+
return unless @logger && ENV['DEBUG']
|
257
191
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
if !@targets.target?(target_info['targetId'])
|
263
|
-
# @targets.add(target_info['targetId'], DevToolsProtocol::Target.new(self, target_info))
|
264
|
-
@targets.add(target_info['targetId'], target_info)
|
265
|
-
puts "**** Target Added #{info}" if ENV['DEBUG']
|
266
|
-
elsif ENV['DEBUG']
|
267
|
-
puts "Target already existed #{info}"
|
268
|
-
end
|
269
|
-
@current_page_handle ||= target_info['targetId'] if target_info['type'] == 'page'
|
192
|
+
if @logger.respond_to?(:puts)
|
193
|
+
@logger.puts(message)
|
194
|
+
else
|
195
|
+
@logger.debug(message)
|
270
196
|
end
|
197
|
+
end
|
271
198
|
|
272
|
-
|
273
|
-
|
274
|
-
|
199
|
+
def initialize_handlers
|
200
|
+
# @client.on 'Target.targetCreated' do |info|
|
201
|
+
# byebug
|
202
|
+
# puts "Target Created Info: #{info}" if ENV['DEBUG']
|
203
|
+
# target_info = info['targetInfo']
|
204
|
+
# if !@pages.key?(target_info['targetId'])
|
205
|
+
# @pages.add(target_info['targetId'], target_info)
|
206
|
+
# puts "**** Target Added #{info}" if ENV['DEBUG']
|
207
|
+
# elsif ENV['DEBUG']
|
208
|
+
# puts "Target already existed #{info}"
|
209
|
+
# end
|
210
|
+
# @current_page_handle ||= target_info['targetId'] if target_info['type'] == 'page'
|
211
|
+
# end
|
212
|
+
|
213
|
+
@client.on 'Target.targetDestroyed' do |target_id:, **info|
|
214
|
+
puts "**** Target Destroyed Info: #{target_id} - #{info}" if ENV['DEBUG']
|
215
|
+
@pages.delete(target_id)
|
275
216
|
end
|
276
217
|
|
277
|
-
@client.on 'Target.targetInfoChanged' do |info|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
end
|
218
|
+
# @client.on 'Target.targetInfoChanged' do |info|
|
219
|
+
# byebug
|
220
|
+
# puts "**** Target Info Changed: #{info}" if ENV['DEBUG']
|
221
|
+
# target_info = info['targetInfo']
|
222
|
+
# page = @pages[target_info['targetId']]
|
223
|
+
# if page
|
224
|
+
# page.update(target_info)
|
225
|
+
# else
|
226
|
+
# puts '****No target for the info change- creating****' if ENV['DEBUG']
|
227
|
+
# @pages.add(target_info['targetId'], target_info)
|
228
|
+
# end
|
229
|
+
# end
|
288
230
|
end
|
289
231
|
end
|
290
232
|
end
|
@@ -6,18 +6,9 @@ module Capybara::Apparition
|
|
6
6
|
class Browser
|
7
7
|
module Cookie
|
8
8
|
def cookies
|
9
|
-
CookieJar.new(
|
10
|
-
# current_page.command('Network.getCookies')['cookies'].map { |c| Cookie.new(c) }
|
11
|
-
self
|
12
|
-
)
|
13
|
-
end
|
14
|
-
|
15
|
-
def all_cookies
|
16
|
-
CookieJar.new(
|
17
|
-
# current_page.command('Network.getAllCookies')['cookies'].map { |c| Cookie.new(c) }
|
18
|
-
self
|
19
|
-
)
|
9
|
+
CookieJar.new(self)
|
20
10
|
end
|
11
|
+
alias :all_cookies :cookies
|
21
12
|
|
22
13
|
def get_raw_cookies
|
23
14
|
current_page.command('Network.getAllCookies')['cookies'].map do |c|
|
@@ -26,12 +17,9 @@ module Capybara::Apparition
|
|
26
17
|
end
|
27
18
|
|
28
19
|
def set_cookie(cookie)
|
29
|
-
if cookie[:expires]
|
30
|
-
# cookie[:expires] = cookie[:expires].to_i * 1000
|
31
|
-
cookie[:expires] = cookie[:expires].to_i
|
32
|
-
end
|
20
|
+
cookie[:expires] = cookie[:expires].to_i if cookie[:expires]
|
33
21
|
|
34
|
-
current_page.command('Network.setCookie', cookie)
|
22
|
+
current_page.command('Network.setCookie', **cookie)
|
35
23
|
end
|
36
24
|
|
37
25
|
def remove_cookie(name)
|
@@ -8,7 +8,7 @@ module Capybara::Apparition
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def headers=(headers)
|
11
|
-
@
|
11
|
+
@pages.each do |page|
|
12
12
|
page.perm_headers = headers.dup
|
13
13
|
page.temp_headers = {}
|
14
14
|
page.temp_no_redirect_headers = {}
|
@@ -23,7 +23,7 @@ module Capybara::Apparition
|
|
23
23
|
|
24
24
|
def add_header(header, permanent: true, **_options)
|
25
25
|
if permanent == true
|
26
|
-
@
|
26
|
+
@pages.each do |page|
|
27
27
|
page.perm_headers.merge! header
|
28
28
|
page.update_headers
|
29
29
|
end
|