mirror of
https://github.com/teampoltergeist/poltergeist.git
synced 2022-11-09 12:05:00 -05:00
144 lines
3.8 KiB
CoffeeScript
144 lines
3.8 KiB
CoffeeScript
class Poltergeist.Browser
|
|
constructor: (@owner) ->
|
|
@awaiting_response = false
|
|
this.resetPage()
|
|
|
|
resetPage: ->
|
|
@page.release() if @page?
|
|
|
|
@page = new Poltergeist.WebPage
|
|
@page.onLoadFinished = (status) =>
|
|
if @awaiting_response
|
|
@owner.sendResponse(status)
|
|
@awaiting_response = false
|
|
|
|
visit: (url) ->
|
|
@awaiting_response = true
|
|
@page.open(url)
|
|
|
|
current_url: ->
|
|
@owner.sendResponse @page.currentUrl()
|
|
|
|
body: ->
|
|
@owner.sendResponse @page.content()
|
|
|
|
source: ->
|
|
@owner.sendResponse @page.source()
|
|
|
|
find: (selector, id) ->
|
|
@owner.sendResponse @page.find(selector, id)
|
|
|
|
text: (id) ->
|
|
@owner.sendResponse @page.get(id).text()
|
|
|
|
attribute: (id, name) ->
|
|
@owner.sendResponse @page.get(id).getAttribute(name)
|
|
|
|
value: (id) ->
|
|
@owner.sendResponse @page.get(id).value()
|
|
|
|
set: (id, value) ->
|
|
@page.get(id).set(value)
|
|
@owner.sendResponse(true)
|
|
|
|
# PhantomJS only allows us to reference the element by CSS selector, not XPath,
|
|
# so we have to add an attribute to the element to identify it, then remove it
|
|
# afterwards.
|
|
#
|
|
# PhantomJS does not support multiple-file inputs, so we have to blatently cheat
|
|
# by temporarily changing it to a single-file input. This obviously could break
|
|
# things in various ways, which is not ideal, but it works in the simplest case.
|
|
select_file: (id, value) ->
|
|
element = @page.get(id)
|
|
|
|
multiple = element.isMultiple()
|
|
|
|
element.removeAttribute('multiple') if multiple
|
|
element.setAttribute('_poltergeist_selected', '')
|
|
|
|
@page.uploadFile('[_poltergeist_selected]', value)
|
|
|
|
element.removeAttribute('_poltergeist_selected')
|
|
element.setAttribute('multiple', 'multiple') if multiple
|
|
|
|
@owner.sendResponse(true)
|
|
|
|
select: (id, value) ->
|
|
@owner.sendResponse @page.get(id).select(value)
|
|
|
|
tag_name: (id) ->
|
|
@owner.sendResponse @page.get(id).tagName()
|
|
|
|
visible: (id) ->
|
|
@owner.sendResponse @page.get(id).isVisible()
|
|
|
|
evaluate: (script) ->
|
|
@owner.sendResponse @page.evaluate("function() { return #{script} }")
|
|
|
|
execute: (script) ->
|
|
@page.execute("function() { #{script} }")
|
|
@owner.sendResponse(true)
|
|
|
|
push_frame: (id) ->
|
|
@page.pushFrame(id)
|
|
@owner.sendResponse(true)
|
|
|
|
pop_frame: ->
|
|
@page.popFrame()
|
|
@owner.sendResponse(true)
|
|
|
|
click: (id) ->
|
|
load_detected = false
|
|
|
|
# Detect if the click event triggers a page load. If it does, don't send
|
|
# a response here, because the response will be sent once the page has loaded.
|
|
@page.onLoadStarted = =>
|
|
@awaiting_response = true
|
|
load_detected = true
|
|
|
|
@page.get(id).click()
|
|
|
|
# Use a timeout in order to let the stack clear, so that the @page.onLoadStarted
|
|
# callback can (possibly) fire, before we decide whether to send a response.
|
|
setTimeout(
|
|
=>
|
|
@page.onLoadStarted = null
|
|
@owner.sendResponse(true) unless load_detected
|
|
,
|
|
10
|
|
)
|
|
|
|
drag: (id, other_id) ->
|
|
@page.get(id).dragTo(@page.get(other_id))
|
|
@owner.sendResponse(true)
|
|
|
|
trigger: (id, event) ->
|
|
@page.get(id).trigger(event)
|
|
@owner.sendResponse(event)
|
|
|
|
reset: ->
|
|
this.resetPage()
|
|
@owner.sendResponse(true)
|
|
|
|
render: (path, full) ->
|
|
dimensions = @page.validatedDimensions()
|
|
document = dimensions.document
|
|
viewport = dimensions.viewport
|
|
|
|
if full
|
|
@page.setScrollPosition(left: 0, top: 0)
|
|
@page.setClipRect(left: 0, top: 0, width: document.width, height: document.height)
|
|
@page.render(path)
|
|
@page.setScrollPosition(left: dimensions.left, top: dimensions.top)
|
|
else
|
|
@page.setClipRect(left: 0, top: 0, width: viewport.width, height: viewport.height)
|
|
@page.render(path)
|
|
|
|
@owner.sendResponse(true)
|
|
|
|
resize: (width, height) ->
|
|
@page.setViewportSize(width: width, height: height)
|
|
@owner.sendResponse(true)
|
|
|
|
exit: ->
|
|
phantom.exit()
|