lib/capybara/poltergeist/client/browser.coffee in poltergeist-1.0.3 vs lib/capybara/poltergeist/client/browser.coffee in poltergeist-1.1.0

- old
+ new

@@ -3,10 +3,12 @@ @width = width || 1024 @height = height || 768 @state = 'default' @page_stack = [] @page_id = 0 + @js_errors = true + @_debug = false this.resetPage() resetPage: -> if @page? @@ -15,61 +17,75 @@ @page = new Poltergeist.WebPage @page.setViewportSize(width: @width, height: @height) @page.onLoadStarted = => - @state = 'loading' if @state == 'clicked' + this.setState 'loading' if @state == 'clicked' @page.onNavigationRequested = (url, navigation) => - @state = 'loading' if @state == 'clicked' && navigation == 'FormSubmitted' + this.setState 'loading' if @state == 'clicked' && navigation == 'FormSubmitted' @page.onLoadFinished = (status) => if @state == 'loading' this.sendResponse(status: status, click: @last_click) - @state = 'default' + this.setState 'default' else if @state == 'awaiting_frame_load' this.sendResponse(true) - @state = 'default' + this.setState 'default' @page.onInitialized = => @page_id += 1 @page.onPageCreated = (sub_page) => if @state == 'awaiting_sub_page' name = @page_name - @state = 'default' @page_name = null + this.setState 'default' + # At this point subpage isn't fully initialized, so we can't check # its name. Instead, we just schedule another attempt to push the # window. setTimeout((=> this.push_window(name)), 0) + debug: (message) -> + if @_debug + console.log "poltergeist [#{new Date().getTime()}] #{message}" + + setState: (state) -> + this.debug "state #{@state} -> #{state}" + @state = state + sendResponse: (response) -> errors = @page.errors() + @page.clearErrors() - if errors.length > 0 - @page.clearErrors() + if errors.length > 0 && @js_errors @owner.sendError(new Poltergeist.JavascriptError(errors)) else @owner.sendResponse(response) + add_extension: (extension) -> + @page.injectExtension extension + this.sendResponse 'success' + node: (page_id, id) -> if page_id == @page_id @page.get(id) else throw new Poltergeist.ObsoleteNode visit: (url) -> - @state = 'loading' + this.setState 'loading' + prev_url = @page.currentUrl() @page.open(url) if /#/.test(url) && prev_url.split('#')[0] == url.split('#')[0] # hashchange occurred, so there will be no onLoadFinished - @state = 'default' + this.setState 'default' this.sendResponse 'success' current_url: -> this.sendResponse @page.currentUrl() @@ -103,15 +119,15 @@ # 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. select_file: (page_id, id, value) -> - node = this.node(page_id, id) + node = this.node(page_id, id) - node.setAttribute('_poltergeist_selected', '') + @page.beforeUpload(node.id) @page.uploadFile('[_poltergeist_selected]', value) - node.removeAttribute('_poltergeist_selected') + @page.afterUpload(node.id) this.sendResponse(true) select: (page_id, id, value) -> this.sendResponse this.node(page_id, id).select(value) @@ -130,11 +146,11 @@ this.sendResponse(true) push_frame: (name) -> if @page.pushFrame(name) if @page.currentUrl() == 'about:blank' - @state = 'awaiting_frame_load' + this.setState 'awaiting_frame_load' else this.sendResponse(true) else # There's currently no PhantomJS callback available for frame creation, # so we have to poll @@ -156,33 +172,40 @@ @page = sub_page @page_id += 1 this.sendResponse(true) else @page_name = name - @state = 'awaiting_sub_page' + this.setState 'awaiting_sub_page' pop_window: -> prev_page = @page_stack.pop() @page = prev_page if prev_page this.sendResponse(true) - click: (page_id, id) -> + click: (page_id, id, event = 'click') -> # Get the node before changing state, in case there is an exception node = this.node(page_id, id) # If the click event triggers onNavigationRequested, we will transition to the 'loading' # state and wait for onLoadFinished before sending a response. - @state = 'clicked' + this.setState 'clicked' - @last_click = node.click() + @last_click = node.click(event) setTimeout => if @state != 'loading' - @state = 'default' + this.setState 'default' this.sendResponse(@last_click) , 5 + double_click: (page_id, id) -> + this.click page_id, id, 'doubleclick' + + click_coordinates: (x, y) -> + @page.sendEvent('click', x, y) + this.sendResponse({ click: { x: x, y: y } }) + drag: (page_id, id, other_id) -> this.node(page_id, id).dragTo this.node(page_id, other_id) this.sendResponse(true) trigger: (page_id, id, event) -> @@ -237,9 +260,17 @@ phantom.addCookie(cookie) this.sendResponse(true) remove_cookie: (name) -> @page.deleteCookie(name) + this.sendResponse(true) + + set_js_errors: (value) -> + @js_errors = value + this.sendResponse(true) + + set_debug: (value) -> + @_debug = value this.sendResponse(true) exit: -> phantom.exit()