poltergeist 1.7.0 → 1.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 440dc77fc5ba49d78d8e7af8134da82b93a500cd
4
- data.tar.gz: afc6fba6b9d6be96866c9810cb1b9a729dddc4a8
3
+ metadata.gz: 80b33a1ca12aebf206487179bd97bde02aaf2934
4
+ data.tar.gz: 4b1545c216c97fd54b9673516e5a7d854daf86d9
5
5
  SHA512:
6
- metadata.gz: 704dea9cd5162c277fd8b5b9ee2f816beec71d4deabd64616a7ebe87d64d6c8a922a9fd9ba1d9b71b05be8b28eeaacc6aad225140ee47be19c4d8c1536726eb6
7
- data.tar.gz: 6ba1c737813c8a09c47a51e31032626ad21e251f1de4a7e05e758057d99702720313950c307d04b458be52ffc665eae5e892ac256e536afdf4baf399bf37b5df
6
+ metadata.gz: 27e4dbb8868f7dfc18daaec1beae92d7afef23c61d4b720fa4a1f9f6352a1d0eb8909053a0a5c920103507ef1a135965061a3874b74c649554823004cc655459
7
+ data.tar.gz: cb0ed5f12f3cddd189277ee37802fc45b2fc9f157a41812882d14da9de21a135d699a4ffd6d6441919206305b60ee650766e514db2e6fc83d49953cbd27c33f5
data/README.md CHANGED
@@ -9,7 +9,7 @@ provided by [PhantomJS](http://phantomjs.org/).
9
9
  **If you're viewing this at https://github.com/teampoltergeist/poltergeist,
10
10
  you're reading the documentation for the master branch.
11
11
  [View documentation for the latest release
12
- (1.7.0).](https://github.com/teampoltergeist/poltergeist/tree/v1.7.0)**
12
+ (1.8.0).](https://github.com/teampoltergeist/poltergeist/tree/v1.8.0)**
13
13
 
14
14
  ## Getting help ##
15
15
 
@@ -1,4 +1,5 @@
1
1
  require "capybara/poltergeist/errors"
2
+ require "capybara/poltergeist/command"
2
3
  require 'multi_json'
3
4
  require 'time'
4
5
 
@@ -78,6 +79,10 @@ module Capybara::Poltergeist
78
79
  command 'delete_text', page_id, id
79
80
  end
80
81
 
82
+ def property(page_id, id, name)
83
+ command 'property', page_id, id, name.to_s
84
+ end
85
+
81
86
  def attributes(page_id, id)
82
87
  command 'attributes', page_id, id
83
88
  end
@@ -124,7 +129,7 @@ module Capybara::Poltergeist
124
129
 
125
130
  def within_frame(handle, &block)
126
131
  if handle.is_a?(Capybara::Node::Base)
127
- command 'push_frame', handle[:name] || handle[:id]
132
+ command 'push_frame', [handle.native.page_id, handle.native.id]
128
133
  else
129
134
  command 'push_frame', handle
130
135
  end
@@ -154,11 +159,17 @@ module Capybara::Poltergeist
154
159
  command 'close_window', handle
155
160
  end
156
161
 
157
- def within_window(name, &block)
162
+ def find_window_handle(locator)
163
+ return locator if window_handles.include? locator
164
+
165
+ handle = command 'window_handle', locator
166
+ raise noSuchWindowError unless handle
167
+ return handle
168
+ end
169
+
170
+ def within_window(locator, &block)
158
171
  original = window_handle
159
- handle = command 'window_handle', name
160
- handle = name if handle.nil? && window_handles.include?(name)
161
- raise NoSuchWindowError unless handle
172
+ handle = find_window_handle(locator)
162
173
  switch_to_window(handle)
163
174
  yield
164
175
  ensure
@@ -322,10 +333,10 @@ module Capybara::Poltergeist
322
333
  end
323
334
 
324
335
  def command(name, *args)
325
- message = JSON.dump({ 'name' => name, 'args' => args })
326
- log message
336
+ cmd = Command.new(name, *args)
337
+ log cmd.message
327
338
 
328
- response = server.send(message)
339
+ response = server.send(cmd)
329
340
  log response
330
341
 
331
342
  json = JSON.load(response)
@@ -1,6 +1,10 @@
1
1
  # This is injected into each page that is loaded
2
2
 
3
3
  class PoltergeistAgent
4
+ # Since this code executes in the sites browser space - copy needed JSON functions
5
+ # in case user code messes with JSON (early mootools for instance)
6
+ @.JSON ||= { parse: JSON.parse, stringify: JSON.stringify }
7
+
4
8
  constructor: ->
5
9
  @elements = []
6
10
  @nodes = {}
@@ -13,7 +17,7 @@ class PoltergeistAgent
13
17
 
14
18
  @stringify: (object) ->
15
19
  try
16
- JSON.stringify object, (key, value) ->
20
+ PoltergeistAgent.JSON.stringify object, (key, value) ->
17
21
  if Array.isArray(this[key])
18
22
  return this[key]
19
23
  else
@@ -120,6 +124,8 @@ class PoltergeistAgent.Node
120
124
  # from the parent SELECT
121
125
  if @element.nodeName == 'OPTION'
122
126
  element = @element.parentNode
127
+ element = element.parentNode if element.nodeName == 'OPTGROUP'
128
+ element
123
129
  else
124
130
  element = @element
125
131
 
@@ -172,9 +178,12 @@ class PoltergeistAgent.Node
172
178
  window.getSelection().addRange(range)
173
179
  window.getSelection().deleteFromDocument()
174
180
 
181
+ getProperty: (name) ->
182
+ @element[name]
183
+
175
184
  getAttributes: ->
176
185
  attrs = {}
177
- for attr, i in @element.attributes
186
+ for attr in @element.attributes
178
187
  attrs[attr.name] = attr.value.replace("\n","\\n");
179
188
  attrs
180
189
 
@@ -186,6 +195,10 @@ class PoltergeistAgent.Node
186
195
 
187
196
  scrollIntoView: ->
188
197
  @element.scrollIntoViewIfNeeded()
198
+ #Sometimes scrollIntoViewIfNeeded doesn't seem to work, not really sure why.
199
+ #Just calling scrollIntoView doesnt work either, however calling scrollIntoView
200
+ #after scrollIntoViewIfNeeded when element is not in the viewport does appear to work
201
+ @element.scrollIntoView() unless this.isInViewport()
189
202
 
190
203
  value: ->
191
204
  if @element.tagName == 'SELECT' && @element.multiple
@@ -199,8 +212,8 @@ class PoltergeistAgent.Node
199
212
  if (@element.maxLength >= 0)
200
213
  value = value.substr(0, @element.maxLength)
201
214
 
202
- @element.value = ''
203
215
  this.trigger('focus')
216
+ @element.value = ''
204
217
 
205
218
  if @element.type == 'number'
206
219
  @element.value = value
@@ -244,14 +257,24 @@ class PoltergeistAgent.Node
244
257
  @element.tagName
245
258
 
246
259
  isVisible: (element) ->
247
- element = @element unless element
260
+ element ||= @element
248
261
 
249
- if window.getComputedStyle(element).display == 'none'
250
- false
251
- else if element.parentElement
252
- this.isVisible element.parentElement
253
- else
254
- true
262
+ while (element)
263
+ style = window.getComputedStyle(element)
264
+ return false if style.display == 'none' or
265
+ style.visibility == 'hidden' or
266
+ parseFloat(style.opacity) == 0
267
+ element = element.parentElement
268
+
269
+ return true
270
+
271
+ isInViewport: ->
272
+ rect = @element.getBoundingClientRect();
273
+
274
+ rect.top >= 0 &&
275
+ rect.left >= 0 &&
276
+ rect.bottom <= window.innerHeight &&
277
+ rect.right <= window.innerWidth
255
278
 
256
279
  isDisabled: ->
257
280
  @element.disabled || @element.tagName == 'OPTION' && @element.parentNode.disabled
@@ -340,12 +363,14 @@ class PoltergeistAgent.Node
340
363
  el = el.parentNode
341
364
 
342
365
  { status: 'failure', selector: origEl && this.getSelector(origEl) }
343
-
344
366
  getSelector: (el) ->
345
367
  selector = if el.tagName != 'HTML' then this.getSelector(el.parentNode) + ' ' else ''
346
368
  selector += el.tagName.toLowerCase()
347
369
  selector += "##{el.id}" if el.id
348
- for className in el.classList
370
+
371
+ #PhantomJS < 2.0 doesn't support classList for SVG elements - so get classes manually
372
+ classes = el.classList || (el.getAttribute('class')?.trim()?.split(/\s+/)) || []
373
+ for className in classes when className != ''
349
374
  selector += ".#{className}"
350
375
  selector
351
376
 
@@ -1,5 +1,5 @@
1
1
  class Poltergeist.Browser
2
- constructor: (@owner, width, height) ->
2
+ constructor: (width, height) ->
3
3
  @width = width || 1024
4
4
  @height = height || 768
5
5
  @pages = []
@@ -57,9 +57,10 @@ class Poltergeist.Browser
57
57
  getPageByHandle: (handle) ->
58
58
  @pages.filter((p) -> !p.closed && p.handle == handle)[0]
59
59
 
60
- runCommand: (name, args) ->
60
+ runCommand: (command) ->
61
+ @current_command = command
61
62
  @currentPage.state = 'default'
62
- this[name].apply(this, args)
63
+ this[command.name].apply(this, command.args)
63
64
 
64
65
  debug: (message) ->
65
66
  if @_debug
@@ -68,18 +69,9 @@ class Poltergeist.Browser
68
69
  setModalMessage: (msg) ->
69
70
  @processed_modal_messages.push(msg)
70
71
 
71
- sendResponse: (response) ->
72
- errors = @currentPage.errors
73
- @currentPage.clearErrors()
74
-
75
- if errors.length > 0 && @js_errors
76
- @owner.sendError(new Poltergeist.JavascriptError(errors))
77
- else
78
- @owner.sendResponse(response)
79
-
80
72
  add_extension: (extension) ->
81
73
  @currentPage.injectExtension extension
82
- this.sendResponse 'success'
74
+ @current_command.sendResponse 'success'
83
75
 
84
76
  node: (page_id, id) ->
85
77
  if @currentPage.id == page_id
@@ -88,6 +80,7 @@ class Poltergeist.Browser
88
80
  throw new Poltergeist.ObsoleteNode
89
81
 
90
82
  visit: (url) ->
83
+
91
84
  @currentPage.state = 'loading'
92
85
  #reset modal processing state when changing page
93
86
  @processed_modal_messages = []
@@ -105,59 +98,63 @@ class Poltergeist.Browser
105
98
  if /#/.test(url) && prevUrl.split('#')[0] == url.split('#')[0]
106
99
  # Hash change occurred, so there will be no onLoadFinished
107
100
  @currentPage.state = 'default'
108
- this.sendResponse(status: 'success')
101
+ @current_command.sendResponse(status: 'success')
109
102
  else
103
+ command = @current_command
110
104
  @currentPage.waitState 'default', =>
111
105
  if @currentPage.statusCode == null && @currentPage.status == 'fail'
112
- @owner.sendError(new Poltergeist.StatusFailError)
106
+ command.sendError(new Poltergeist.StatusFailError(url))
113
107
  else
114
- this.sendResponse(status: @currentPage.status)
108
+ command.sendResponse(status: @currentPage.status)
115
109
 
116
110
  current_url: ->
117
- this.sendResponse @currentPage.currentUrl()
111
+ @current_command.sendResponse @currentPage.currentUrl()
118
112
 
119
113
  status_code: ->
120
- this.sendResponse @currentPage.statusCode
114
+ @current_command.sendResponse @currentPage.statusCode
121
115
 
122
116
  body: ->
123
- this.sendResponse @currentPage.content()
117
+ @current_command.sendResponse @currentPage.content()
124
118
 
125
119
  source: ->
126
- this.sendResponse @currentPage.source
120
+ @current_command.sendResponse @currentPage.source
127
121
 
128
122
  title: ->
129
- this.sendResponse @currentPage.title()
123
+ @current_command.sendResponse @currentPage.title()
130
124
 
131
125
  find: (method, selector) ->
132
- this.sendResponse(page_id: @currentPage.id, ids: @currentPage.find(method, selector))
126
+ @current_command.sendResponse(page_id: @currentPage.id, ids: @currentPage.find(method, selector))
133
127
 
134
128
  find_within: (page_id, id, method, selector) ->
135
- this.sendResponse this.node(page_id, id).find(method, selector)
129
+ @current_command.sendResponse this.node(page_id, id).find(method, selector)
136
130
 
137
131
  all_text: (page_id, id) ->
138
- this.sendResponse this.node(page_id, id).allText()
132
+ @current_command.sendResponse this.node(page_id, id).allText()
139
133
 
140
134
  visible_text: (page_id, id) ->
141
- this.sendResponse this.node(page_id, id).visibleText()
135
+ @current_command.sendResponse this.node(page_id, id).visibleText()
142
136
 
143
137
  delete_text: (page_id, id) ->
144
- this.sendResponse this.node(page_id, id).deleteText()
138
+ @current_command.sendResponse this.node(page_id, id).deleteText()
139
+
140
+ property: (page_id, id, name) ->
141
+ @current_command.sendResponse this.node(page_id, id).getProperty(name)
145
142
 
146
143
  attribute: (page_id, id, name) ->
147
- this.sendResponse this.node(page_id, id).getAttribute(name)
144
+ @current_command.sendResponse this.node(page_id, id).getAttribute(name)
148
145
 
149
146
  attributes: (page_id, id, name) ->
150
- this.sendResponse this.node(page_id, id).getAttributes()
147
+ @current_command.sendResponse this.node(page_id, id).getAttributes()
151
148
 
152
149
  parents: (page_id, id) ->
153
- this.sendResponse this.node(page_id, id).parentIds()
150
+ @current_command.sendResponse this.node(page_id, id).parentIds()
154
151
 
155
152
  value: (page_id, id) ->
156
- this.sendResponse this.node(page_id, id).value()
153
+ @current_command.sendResponse this.node(page_id, id).value()
157
154
 
158
155
  set: (page_id, id, value) ->
159
156
  this.node(page_id, id).set(value)
160
- this.sendResponse(true)
157
+ @current_command.sendResponse(true)
161
158
 
162
159
  # PhantomJS only allows us to reference the element by CSS selector, not XPath,
163
160
  # so we have to add an attribute to the element to identify it, then remove it
@@ -168,56 +165,71 @@ class Poltergeist.Browser
168
165
  @currentPage.beforeUpload(node.id)
169
166
  @currentPage.uploadFile('[_poltergeist_selected]', value)
170
167
  @currentPage.afterUpload(node.id)
171
-
172
- this.sendResponse(true)
168
+ if phantom.version.major == 2
169
+ # In phantomjs 2 - uploadFile only fully works if executed within a user action
170
+ # It does however setup the filenames to be uploaded, so if we then click on the
171
+ # file input element the filenames will get set
172
+ @click(page_id, id)
173
+ else
174
+ @current_command.sendResponse(true)
173
175
 
174
176
  select: (page_id, id, value) ->
175
- this.sendResponse this.node(page_id, id).select(value)
177
+ @current_command.sendResponse this.node(page_id, id).select(value)
176
178
 
177
179
  tag_name: (page_id, id) ->
178
- this.sendResponse this.node(page_id, id).tagName()
180
+ @current_command.sendResponse this.node(page_id, id).tagName()
179
181
 
180
182
  visible: (page_id, id) ->
181
- this.sendResponse this.node(page_id, id).isVisible()
183
+ @current_command.sendResponse this.node(page_id, id).isVisible()
182
184
 
183
185
  disabled: (page_id, id) ->
184
- this.sendResponse this.node(page_id, id).isDisabled()
186
+ @current_command.sendResponse this.node(page_id, id).isDisabled()
185
187
 
186
188
  path: (page_id, id) ->
187
- this.sendResponse this.node(page_id, id).path()
189
+ @current_command.sendResponse this.node(page_id, id).path()
188
190
 
189
191
  evaluate: (script) ->
190
- this.sendResponse @currentPage.evaluate("function() { return #{script} }")
192
+ @current_command.sendResponse @currentPage.evaluate("function() { return #{script} }")
191
193
 
192
194
  execute: (script) ->
193
195
  @currentPage.execute("function() { #{script} }")
194
- this.sendResponse(true)
196
+ @current_command.sendResponse(true)
195
197
 
196
198
  frameUrl: (frame_name) ->
197
199
  @currentPage.frameUrl(frame_name)
198
200
 
199
- push_frame: (name, timeout = new Date().getTime() + 2000) ->
201
+ pushFrame: (command, name, timeout) ->
202
+ if Array.isArray(name)
203
+ frame = this.node(name...)
204
+ name = frame.getAttribute('name') || frame.getAttribute('id')
205
+ unless name
206
+ frame.setAttribute('name', "_random_name_#{new Date().getTime()}")
207
+ name = frame.getAttribute('name')
208
+
200
209
  if @frameUrl(name) in @currentPage.blockedUrls()
201
- this.sendResponse(true)
210
+ command.sendResponse(true)
202
211
  else if @currentPage.pushFrame(name)
203
212
  if @currentPage.currentUrl() == 'about:blank'
204
213
  @currentPage.state = 'awaiting_frame_load'
205
214
  @currentPage.waitState 'default', =>
206
- this.sendResponse(true)
215
+ command.sendResponse(true)
207
216
  else
208
- this.sendResponse(true)
217
+ command.sendResponse(true)
209
218
  else
210
219
  if new Date().getTime() < timeout
211
- setTimeout((=> this.push_frame(name, timeout)), 50)
220
+ setTimeout((=> @pushFrame(command, name, timeout)), 50)
212
221
  else
213
- @owner.sendError(new Poltergeist.FrameNotFound(name))
222
+ command.sendError(new Poltergeist.FrameNotFound(name))
223
+
224
+ push_frame: (name, timeout = (new Date().getTime()) + 2000) ->
225
+ @pushFrame(@current_command, name, timeout)
214
226
 
215
227
  pop_frame: ->
216
- this.sendResponse(@currentPage.popFrame())
228
+ @current_command.sendResponse(@currentPage.popFrame())
217
229
 
218
230
  window_handles: ->
219
231
  handles = @pages.filter((p) -> !p.closed).map((p) -> p.handle)
220
- this.sendResponse(handles)
232
+ @current_command.sendResponse(handles)
221
233
 
222
234
  window_handle: (name = null) ->
223
235
  handle = if name
@@ -226,31 +238,32 @@ class Poltergeist.Browser
226
238
  else
227
239
  @currentPage.handle
228
240
 
229
- this.sendResponse(handle)
241
+ @current_command.sendResponse(handle)
230
242
 
231
243
  switch_to_window: (handle) ->
244
+ command = @current_command
232
245
  page = @getPageByHandle(handle)
233
246
  if page
234
247
  if page != @currentPage
235
248
  page.waitState 'default', =>
236
249
  @currentPage = page
237
- this.sendResponse(true)
250
+ command.sendResponse(true)
238
251
  else
239
- this.sendResponse(true)
252
+ command.sendResponse(true)
240
253
  else
241
254
  throw new Poltergeist.NoSuchWindowError
242
255
 
243
256
  open_new_window: ->
244
257
  this.execute 'window.open()'
245
- this.sendResponse(true)
258
+ @current_command.sendResponse(true)
246
259
 
247
260
  close_window: (handle) ->
248
261
  page = @getPageByHandle(handle)
249
262
  if page
250
263
  page.release()
251
- this.sendResponse(true)
264
+ @current_command.sendResponse(true)
252
265
  else
253
- this.sendResponse(false)
266
+ @current_command.sendResponse(false)
254
267
 
255
268
  mouse_event: (page_id, id, name) ->
256
269
  # Get the node before changing state, in case there is an exception
@@ -262,14 +275,16 @@ class Poltergeist.Browser
262
275
 
263
276
  @last_mouse_event = node.mouseEvent(name)
264
277
 
278
+ command = @current_command
279
+
265
280
  setTimeout =>
266
281
  # If the state is still the same then navigation event won't happen
267
282
  if @currentPage.state == 'mouse_event'
268
283
  @currentPage.state = 'default'
269
- this.sendResponse(position: @last_mouse_event)
284
+ command.sendResponse(position: @last_mouse_event)
270
285
  else
271
286
  @currentPage.waitState 'default', =>
272
- this.sendResponse(position: @last_mouse_event)
287
+ command.sendResponse(position: @last_mouse_event)
273
288
  , 5
274
289
 
275
290
  click: (page_id, id) ->
@@ -286,30 +301,30 @@ class Poltergeist.Browser
286
301
 
287
302
  click_coordinates: (x, y) ->
288
303
  @currentPage.sendEvent('click', x, y)
289
- this.sendResponse(click: { x: x, y: y })
304
+ @current_command.sendResponse(click: { x: x, y: y })
290
305
 
291
306
  drag: (page_id, id, other_id) ->
292
307
  this.node(page_id, id).dragTo this.node(page_id, other_id)
293
- this.sendResponse(true)
308
+ @current_command.sendResponse(true)
294
309
 
295
310
  drag_by: (page_id, id, x, y) ->
296
311
  this.node(page_id, id).dragBy(x, y)
297
- this.sendResponse(true)
312
+ @current_command.sendResponse(true)
298
313
 
299
314
  trigger: (page_id, id, event) ->
300
315
  this.node(page_id, id).trigger(event)
301
- this.sendResponse(event)
316
+ @current_command.sendResponse(event)
302
317
 
303
318
  equals: (page_id, id, other_id) ->
304
- this.sendResponse this.node(page_id, id).isEqual(this.node(page_id, other_id))
319
+ @current_command.sendResponse this.node(page_id, id).isEqual(this.node(page_id, other_id))
305
320
 
306
321
  reset: ->
307
322
  this.resetPage()
308
- this.sendResponse(true)
323
+ @current_command.sendResponse(true)
309
324
 
310
325
  scroll_to: (left, top) ->
311
326
  @currentPage.setScrollPosition(left: left, top: top)
312
- this.sendResponse(true)
327
+ @current_command.sendResponse(true)
313
328
 
314
329
  send_keys: (page_id, id, keys) ->
315
330
  target = this.node(page_id, id)
@@ -330,19 +345,19 @@ class Poltergeist.Browser
330
345
  else
331
346
  @currentPage.sendEvent('keypress', key)
332
347
 
333
- this.sendResponse(true)
348
+ @current_command.sendResponse(true)
334
349
 
335
350
  render_base64: (format, full, selector = null)->
336
351
  this.set_clip_rect(full, selector)
337
352
  encoded_image = @currentPage.renderBase64(format)
338
- this.sendResponse(encoded_image)
353
+ @current_command.sendResponse(encoded_image)
339
354
 
340
355
  render: (path, full, selector = null) ->
341
356
  dimensions = this.set_clip_rect(full, selector)
342
357
  @currentPage.setScrollPosition(left: 0, top: 0)
343
358
  @currentPage.render(path)
344
359
  @currentPage.setScrollPosition(left: dimensions.left, top: dimensions.top)
345
- this.sendResponse(true)
360
+ @current_command.sendResponse(true)
346
361
 
347
362
  set_clip_rect: (full, selector) ->
348
363
  dimensions = @currentPage.validatedDimensions()
@@ -361,31 +376,31 @@ class Poltergeist.Browser
361
376
 
362
377
  set_paper_size: (size) ->
363
378
  @currentPage.setPaperSize(size)
364
- this.sendResponse(true)
379
+ @current_command.sendResponse(true)
365
380
 
366
381
  set_zoom_factor: (zoom_factor) ->
367
382
  @currentPage.setZoomFactor(zoom_factor)
368
- this.sendResponse(true)
383
+ @current_command.sendResponse(true)
369
384
 
370
385
  resize: (width, height) ->
371
386
  @currentPage.setViewportSize(width: width, height: height)
372
- this.sendResponse(true)
387
+ @current_command.sendResponse(true)
373
388
 
374
389
  network_traffic: ->
375
- this.sendResponse(@currentPage.networkTraffic())
390
+ @current_command.sendResponse(@currentPage.networkTraffic())
376
391
 
377
392
  clear_network_traffic: ->
378
393
  @currentPage.clearNetworkTraffic()
379
- this.sendResponse(true)
394
+ @current_command.sendResponse(true)
380
395
 
381
396
  get_headers: ->
382
- this.sendResponse(@currentPage.getCustomHeaders())
397
+ @current_command.sendResponse(@currentPage.getCustomHeaders())
383
398
 
384
399
  set_headers: (headers) ->
385
400
  # Workaround for https://code.google.com/p/phantomjs/issues/detail?id=745
386
401
  @currentPage.setUserAgent(headers['User-Agent']) if headers['User-Agent']
387
402
  @currentPage.setCustomHeaders(headers)
388
- this.sendResponse(true)
403
+ @current_command.sendResponse(true)
389
404
 
390
405
  add_headers: (headers) ->
391
406
  allHeaders = @currentPage.getCustomHeaders()
@@ -398,40 +413,40 @@ class Poltergeist.Browser
398
413
  this.add_headers(header)
399
414
 
400
415
  response_headers: ->
401
- this.sendResponse(@currentPage.responseHeaders())
416
+ @current_command.sendResponse(@currentPage.responseHeaders())
402
417
 
403
418
  cookies: ->
404
- this.sendResponse(@currentPage.cookies())
419
+ @current_command.sendResponse(@currentPage.cookies())
405
420
 
406
421
  # We're using phantom.addCookie so that cookies can be set
407
422
  # before the first page load has taken place.
408
423
  set_cookie: (cookie) ->
409
424
  phantom.addCookie(cookie)
410
- this.sendResponse(true)
425
+ @current_command.sendResponse(true)
411
426
 
412
427
  remove_cookie: (name) ->
413
428
  @currentPage.deleteCookie(name)
414
- this.sendResponse(true)
429
+ @current_command.sendResponse(true)
415
430
 
416
431
  clear_cookies: () ->
417
432
  phantom.clearCookies()
418
- this.sendResponse(true)
433
+ @current_command.sendResponse(true)
419
434
 
420
435
  cookies_enabled: (flag) ->
421
436
  phantom.cookiesEnabled = flag
422
- this.sendResponse(true)
437
+ @current_command.sendResponse(true)
423
438
 
424
439
  set_http_auth: (user, password) ->
425
440
  @currentPage.setHttpAuth(user, password)
426
- this.sendResponse(true)
441
+ @current_command.sendResponse(true)
427
442
 
428
443
  set_js_errors: (value) ->
429
444
  @js_errors = value
430
- this.sendResponse(true)
445
+ @current_command.sendResponse(true)
431
446
 
432
447
  set_debug: (value) ->
433
448
  @_debug = value
434
- this.sendResponse(true)
449
+ @current_command.sendResponse(true)
435
450
 
436
451
  exit: ->
437
452
  phantom.exit()
@@ -444,34 +459,36 @@ class Poltergeist.Browser
444
459
  throw new Error('zomg')
445
460
 
446
461
  go_back: ->
462
+ command = @current_command
447
463
  if @currentPage.canGoBack
448
464
  @currentPage.state = 'loading'
449
465
  @currentPage.goBack()
450
466
  @currentPage.waitState 'default', =>
451
- this.sendResponse(true)
467
+ command.sendResponse(true)
452
468
  else
453
- this.sendResponse(false)
469
+ command.sendResponse(false)
454
470
 
455
471
  go_forward: ->
472
+ command = @current_command
456
473
  if @currentPage.canGoForward
457
474
  @currentPage.state = 'loading'
458
475
  @currentPage.goForward()
459
476
  @currentPage.waitState 'default', =>
460
- this.sendResponse(true)
477
+ command.sendResponse(true)
461
478
  else
462
- this.sendResponse(false)
479
+ command.sendResponse(false)
463
480
 
464
481
  set_url_blacklist: ->
465
482
  @currentPage.urlBlacklist = Array.prototype.slice.call(arguments)
466
- @sendResponse(true)
483
+ @current_command.sendResponse(true)
467
484
 
468
485
  set_confirm_process: (process) ->
469
486
  @confirm_processes.push process
470
- @sendResponse(true)
487
+ @current_command.sendResponse(true)
471
488
 
472
489
  set_prompt_response: (response) ->
473
490
  @prompt_responses.push response
474
- @sendResponse(true)
491
+ @current_command.sendResponse(true)
475
492
 
476
493
  modal_message: ->
477
- @sendResponse(@processed_modal_messages.shift())
494
+ @current_command.sendResponse(@processed_modal_messages.shift())