Skip to content
This repository has been archived by the owner on Dec 16, 2023. It is now read-only.

Commit

Permalink
Added viewInBrowser which uses bcat to view page in your browser of
Browse files Browse the repository at this point in the history
choice.
  • Loading branch information
assaf committed Dec 31, 2010
1 parent b80c3e8 commit 0dc2552
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 32 deletions.
17 changes: 12 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ zombie.js-changelog(7) -- Changelog
===================================


### Version 0.8.3 2010-12-30
### Version 0.8.4 2010-12-30

Added the `field` (find an input field, textarea, etc), `link` (find a
link) and `button` (find a button) methods.
Added `browser.field` (find an input field, textarea, etc),
`browser.link` (find a link) and `browser.button` (find a button)
methods.

196 Tests
2.5 sec to complete
Added `browser.evaluate` to evaluate any arbitrary JavaScript in the
window context and return the result.

Added `browser.viewInBrowser` which uses `bcat` to view page in your
browser of choice.

197 Tests
2.6 sec to complete


### Version 0.8.3 2010-12-30
Expand Down
39 changes: 28 additions & 11 deletions doc/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ You can use the following options:
- `runScripts` -- Run scripts included in or loaded from the page.
Defaults to true.
- `userAgent` -- The User-Agent string to send to the server.

### Browser.visit(url, callback)
### Browser.visit(url, options, callback)

Expand Down Expand Up @@ -75,6 +75,13 @@ Returns the body element of the current document.
Returns the main window's document. Only valid after opening a document
(see `browser.visit`).

### browser.evaluate(expr) : Object

Evaluates a JavaScript expression in the context of the current window
and returns the result. For example:

browser.evaluate("document.title");

### browser.html(selector?, context?) : String

Returns the HTML contents of the selected elements.
Expand Down Expand Up @@ -278,16 +285,6 @@ Unchecks a checkbox. The argument can be the field name, label text or
a CSS selector.


## Notes

#### Callbacks

By convention most callback functions take two arguments. If an error
occurred, the first argument is the error and the second argument is
`null`. If everything went smoothly, the first argument is `null` and
the second argument is the relevant value (e.g. the brower, a window).


## State Management

The browser maintains state as you navigate from one page to another.
Expand Down Expand Up @@ -413,3 +410,23 @@ Returns the last response received by this browser.
Call with multiple arguments to spit them out to the console when
debugging enabled (same as `console.log`). Call with function to spit
out the result of that function call when debugging enabled.

### browser.viewInBrowser(name?)

Views the current document in a real Web browser. Uses the default
browser, or you can specify the browser by name (e.g
`viewInBrowser("chrome")`). This feature uses
[bcat](https://github.com/rtomayko/bcat/tree/master/lib); you need Ruby
and `gem install bcat`.


## Notes

#### Callbacks

By convention most callback functions take two arguments. If an error
occurred, the first argument is the error and the second argument is
`null`. If everything went smoothly, the first argument is `null` and
the second argument is the relevant value (e.g. the brower, a window).


1 change: 1 addition & 0 deletions spec/browser-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,5 @@ vows.describe("Browser").addBatch(
zombie.wants "http://localhost:3003"
"should resolve URL": (browser)-> assert.equal browser.location.href, "http://localhost:3003"
"should load page": (browser)-> assert.equal browser.text("title"), "Tap, Tap"

).export(module)
6 changes: 5 additions & 1 deletion spec/helpers.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ zombie.wants = (url, context)->
context.topic = ->
new zombie.Browser().wants url, (err, browser)=>
if topic
topic.call this, browser
try
value = topic.call this, browser
@callback null, value if value
catch err
@callback err
else
browser.wait @callback
return
Expand Down
8 changes: 8 additions & 0 deletions spec/history-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ vows.describe("History").addBatch(
topic: (window)->
window.addEventListener "popstate", (evt)=> @callback(null, evt)
window.history.back()
return
"should fire popstate event": (evt)-> assert.instanceOf evt, jsdom.dom.level3.events.Event
"should include state": (evt)-> assert.equal evt.state.is, "start"
"go forwards":
Expand All @@ -53,6 +54,7 @@ vows.describe("History").addBatch(
browser.window.history.back()
browser.window.addEventListener "popstate", (evt)=> @callback(null, evt)
browser.window.history.forward()
return
"should fire popstate event": (evt)-> assert.instanceOf evt, jsdom.dom.level3.events.Event
"should include state": (evt)-> assert.equal evt.state.is, "end"
"replaceState":
Expand Down Expand Up @@ -85,6 +87,7 @@ vows.describe("History").addBatch(
topic: (browser)->
browser.window.location = "http://localhost:3003/boo"
browser.window.document.addEventListener "DOMContentLoaded", => @callback null, browser
return
"should add page to history": (browser)-> assert.length browser.window.history, 2
"should change location URL": (browser)-> assert.equal browser.location, "http://localhost:3003/boo"
"should load document": (browser)-> assert.match browser.html(), /Eeek!/
Expand All @@ -93,6 +96,7 @@ vows.describe("History").addBatch(
topic: (browser)->
browser.window.location.pathname = "/boo"
browser.window.document.addEventListener "DOMContentLoaded", => @callback null, browser
return
"should add page to history": (browser)-> assert.length browser.window.history, 2
"should change location URL": (browser)-> assert.equal browser.location, "http://localhost:3003/boo"
"should load document": (browser)-> assert.match browser.html(), /Eeek!/
Expand All @@ -102,6 +106,7 @@ vows.describe("History").addBatch(
browser.document.innerHTML = "Wolf"
browser.window.addEventListener "hashchange", => @callback null, browser
browser.window.location.hash = "boo"
return
"should add page to history": (browser)-> assert.length browser.window.history, 2
"should change location URL": (browser)-> assert.equal browser.location, "http://localhost:3003/#boo"
"should not reload document": (browser)-> assert.match browser.document.innerHTML, /Wolf/
Expand All @@ -111,6 +116,7 @@ vows.describe("History").addBatch(
@window = browser.window
browser.window.location.assign "http://localhost:3003/boo"
browser.document.addEventListener "DOMContentLoaded", => @callback null, browser
return
"should add page to history": (browser)-> assert.length browser.window.history, 2
"should change location URL": (browser)-> assert.equal browser.location, "http://localhost:3003/boo"
"should load document": (browser)-> assert.match browser.html(), /Eeek!/
Expand All @@ -121,6 +127,7 @@ vows.describe("History").addBatch(
@window = browser.window
browser.window.location.replace "http://localhost:3003/boo"
browser.window.document.addEventListener "DOMContentLoaded", => @callback null, browser
return
"should not add page to history": (browser)-> assert.length browser.window.history, 1
"should change location URL": (browser)-> assert.equal browser.location, "http://localhost:3003/boo"
"should load document": (browser)-> assert.match browser.html(), /Eeek!/
Expand All @@ -132,6 +139,7 @@ vows.describe("History").addBatch(
browser.window.document.innerHTML = "Wolf"
browser.window.location.reload()
browser.window.document.addEventListener "DOMContentLoaded", => @callback null, browser
return
"should not add page to history": (browser)-> assert.length browser.window.history, 1
"should not change location URL": (browser)-> assert.equal browser.location, "http://localhost:3003/"
"should reload document": (browser)-> assert.match browser.html(), /Tap, Tap/
Expand Down
6 changes: 6 additions & 0 deletions spec/script-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,10 @@ vows.describe("Scripts").addBatch(
"should change location": (browser)-> assert.equal browser.location, "http://localhost:3003/living#/"
"should process event": (browser)-> assert.equal browser.document.title, "Signed up"

"evaluate":
zombie.wants "http://localhost:3003/living"
topic: (browser)->
browser.evaluate "document.title"
"should evaluate in context and return value": (title)-> assert.equal title, "The Living"

).export(module)
40 changes: 39 additions & 1 deletion src/zombie/browser.coffee
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
jsdom = require("jsdom")
vm = process.binding("evals")
require "./jsdom_patches"
require "./forms"



# Use the browser to open up new windows and load documents.
#
# The browser maintains state for cookies and localStorage.
Expand Down Expand Up @@ -34,7 +36,6 @@ class Browser extends require("events").EventEmitter
# Always start with an open window.
@open()


# Options
# -------

Expand Down Expand Up @@ -466,9 +467,46 @@ class Browser extends require("events").EventEmitter
this.sessionStorage = (host)-> storage.session(host)


# Scripts
# -------

# ### browser.evaluate(code, filename) : Object
#
# Evaluates a JavaScript expression in the context of the current window
# and returns the result. When evaluating external script, also include
# filename.
this.evaluate = (code, filename)->
# Unfortunately, using the same context in multiple scripts
# doesn't agree with jQuery, Sammy and other scripts I tested,
# so each script gets a new context.
context = vm.Script.createContext(window)
# But we need to carry global variables from one script to the
# next, so we're going to store them in window._vars and add them
# back to the new context.
if window._vars
context[v[0]] = v[1] for v in @window._vars
script = new vm.Script(code, filename || "eval")
result = script.runInContext context
window._vars = ([n,v] for n, v of context).filter((v)-> !window[v[0]])
result


# Debugging
# ---------

# ### browser.viewInBrowser(name?)
#
# Views the current document in a real Web browser. Uses the default
# browser, or you can specify by name (e.g `viewInBrowser("chrome")`).
# Uses [bcat](https://github.com/rtomayko/bcat/tree/master/lib).
this.viewInBrowser = (browser)->
args = ["--html"]
args.push "--browser=#{browser}" if browser
bcat = require("child_process").spawn("bcat", args)
bcat.stderr.on "data", (data)-> console.log data.toString()
bcat.stdin.write @html()
bcat.stdin.end()

trail = []
this.record = (request)->
trail.push pending = { request: request }
Expand Down
15 changes: 1 addition & 14 deletions src/zombie/jsdom_patches.coffee
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Fix things that JSDOM doesn't do quite right.
core = require("jsdom").dom.level3.core
URL = require("url")
vm = process.binding("evals")
http = require("http")
html5 = require("html5").HTML5

Expand Down Expand Up @@ -63,19 +62,7 @@ core.languageProcessors =
document = element.ownerDocument
window = document.parentWindow
window.browser.log -> "Running script from #{filename}" if filename
if window
# Unfortunately, using the same context in multiple scripts
# doesn't agree with jQuery, Sammy and other scripts I tested,
# so each script gets a new context.
context = vm.Script.createContext(window)
# But we need to carry global variables from one script to the
# next, so we're going to store them in window._vars and add them
# back to the new context.
if window._vars
context[v[0]] = v[1] for v in window._vars
script = new vm.Script(code, filename)
script.runInContext context
window._vars = ([n,v] for n, v of context).filter((v)-> !window[v[0]])
window.browser.evaluate code, filename

# DOMCharacterDataModified event fired when text is added to a
# TextNode. This is a crappy implementation, a good one would old and
Expand Down

0 comments on commit 0dc2552

Please sign in to comment.