Merge pull request #56 from Roejames12/master

Port coffeescripts to PhantomJS 1.2
1.2
Ariya Hidayat 2011-06-03 12:27:04 -07:00
commit ff10a7af4d
6 changed files with 185 additions and 78 deletions

View File

@ -1,8 +1,8 @@
t = 10
while t > 0
console.log t
phantom.sleep 1000
t = t - 1
console.log 'BLAST OFF'
phantom.exit()
interval = setInterval ->
if t > 0
console.log t--
else
console.log 'BLAST OFF!'
phantom.exit()
, 1000

12
examples/post.coffee Normal file
View File

@ -0,0 +1,12 @@
# Example using HTTP POST operation
page = new WebPage()
server = 'http://posttestserver.com/post.php?dump'
data = 'universe=expanding&answer=42'
page.open server, 'post', data, (status) ->
if status isnt 'success'
console.log 'Unable to post!'
else
console.log page.content
phantom.exit()

View File

@ -0,0 +1,48 @@
# Render Multiple URLs to file
# FIXME: For now it is fine with pure domain names: don't think it would work with paths and stuff like that
# Extend the Array Prototype with a 'foreach'
Array.prototype.forEach = (action) ->
for i, j in this
action j, i, _len
# Render a given url to a given file
# @param url URL to render
# @param file File to render to
# @param callback Callback function
renderUrlToFile = (url, file, callback) ->
page = new WebPage()
page.viewportSize = { width: 800, height : 600 }
page.settings.userAgent = 'Phantom.js bot'
page.open url, (status) ->
if status isnt 'success'
console.log "Unable to render '#{url}'"
else
page.render file
delete page
callback url, file
# Read the passed args
if phantom.args.length > 0
arrayOfUrls = phantom.args
else
# Default (no args passed)
console.log 'Usage: phantomjs render_multi_url.coffee [domain.name1, domain.name2, ...]'
arrayOfUrls = [
'www.google.com',
'www.bbc.co.uk',
'www.phantomjs.org'
]
# For each URL
arrayOfUrls.forEach (pos, url, total) ->
file_name = "./#{url}.png"
# Render to a file
renderUrlToFile "http://#{url}", file_name, (url, file) ->
console.log "Rendered '#{url}' at '#{file}'"
if pos is total - 1
# Close Phantom if it's the last URL
phantom.exit()

View File

@ -1,8 +1,30 @@
if phantom.state.length == 0
phantom.state = 'tweets'
phantom.open 'http://mobile.twitter.com/sencha'
# Get twitter status for given account (or for the default one, "sencha")
page = new WebPage()
twitterId = 'sencha' #< default value
# Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
page.onConsoleMessage = (msg) ->
console.log msg
# Print usage message, if no twitter ID is passed
if phantom.args.length < 1
console.log 'Usage: tweets.coffee [twitter ID]'
else
list = document.querySelectorAll 'span.status'
for elem, index in list
console.log((index + 1) + ': ' + elem.innerHTML.replace(/<.*?>/g, ''))
twitterId = phantom.args[0]
# Heading
console.log "*** Latest tweets from @#{twitterId} ***\n"
# Open Twitter Mobile and, onPageLoad, do...
page.open encodeURI("http://mobile.twitter.com/#{twitterId}"), (status) ->
# Check for page load success
if status isnt 'success'
console.log 'Unable to access network'
else
# Execute some DOM inspection within the page context
page.evaluate ->
list = document.querySelectorAll 'span.status'
for i, j in list
console.log "#{j + 1}: #{i.innerHTML.replace /<.*?>/g, ''}"
phantom.exit()

View File

@ -1,40 +1,52 @@
###
Wait until the test condition is true or a timeout occurs. Useful for waiting
on a server response or for a ui change (fadeIn, etc.) to occur.
@param testFx javascript condition that evaluates to a boolean,
it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
as a callback function.
@param message a message describing e.g. the ui change
@param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
###
waitFor = (testFx, message, maxtimeOutMillis = 3000) ->
##
# Wait until the test condition is true or a timeout occurs. Useful for waiting
# on a server response or for a ui change (fadeIn, etc.) to occur.
#
# @param testFx javascript condition that evaluates to a boolean,
# it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
# as a callback function.
# @param onReady what to do when testFx condition is fulfilled,
# it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
# as a callback function.
# @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
##
waitFor = (testFx, onReady, timeOutMillis=3000) ->
start = new Date().getTime()
condition = false
while (new Date().getTime() - start) < maxtimeOutMillis
phantom.sleep(250)
if typeof(testFx) is "string"
condition = eval testFx
f = ->
if (new Date().getTime() - start < timeOutMillis) and not condition
# If not time-out yet and condition not yet fulfilled
condition = (if typeof testFx is 'string' then eval testFx else testFx()) #< defensive code
else
condition = testFx()
if condition
break
if not condition
console.log "Timeout: " + message
phantom.exit 1
if not condition
# If condition still not fulfilled (timeout but condition is 'false')
console.log "'waitFor()' timeout"
phantom.exit(1)
else
# Condition fulfilled (timeout and/or condition is 'true')
console.log "'waitFor()' finished in #{new Date().getTime() - start}ms."
if typeof onReady is 'string' then eval onReady else onReady() #< Do what it's supposed to do once the condition is fulfilled
clearInterval interval #< Stop this interval
interval = setInterval f, 250 #< repeat check every 250ms
page = new WebPage()
# Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
page.onConsoleMessage = (msg) ->
console.log msg
# Open Twitter on 'sencha' profile and, onPageLoad, do...
page.open 'http://twitter.com/#!/sencha', (status) ->
# Check for page load success
if status isnt 'success'
console.log 'Unable to access network'
else
console.log message
console.log "+++ waitUntil finished in " + (new Date().getTime() - start) + " millis."
# example use:
if not phantom.state
# load a twitter page
phantom.state = "loaded"
phantom.open "http://twitter.com/#!/senchainc"
else
# click the "sign in" link
$(".signin-link").click()
# wait for the sign in dialog to pop up
waitFor (-> $("#signin-dropdown").is ":visible"), "The sign-in dialog should be visible"
phantom.exit()
# Wait for 'signin-dropdown' to be visible
waitFor ->
# Check in the page if a specific element is now visible
page.evaluate ->
$('#signin-dropdown').is ':visible'
, ->
console.log 'The sign-in dialog should be visible now.'
phantom.exit()

View File

@ -1,35 +1,48 @@
if phantom.state.length is 0
city = 'Mountain View'
if phantom.args.length > 0
city = phantom.args.join ' '
phantom.state = city
console.log "Loading #{ city }"
phantom.open encodeURI "http://www.google.com/ig/api?weather=#{ city }"
# Get weather info for given address (or for the default one, "Mountain View")
page = new WebPage()
address = 'Mountain View' #< default value
# Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
page.onConsoleMessage = (msg) ->
console.log msg
# Print usage message, if no twitter ID is passed
if phantom.args.length < 1
console.log 'Usage: weather.coffee [address]'
else
if phantom.loadStatus is 'fail'
address = phantom.args.join ' '
# Heading
console.log "*** Loading weather information for '#{address}' ***\n"
# Open Google "secret" Weather API and, onPageLoad, do...
page.open encodeURI("http://www.google.com/ig/api?weather=#{address}"), (status) ->
# Check for page load success
if status isnt 'success'
console.log 'Unable to access network'
else
if document.querySelectorAll('problem_cause').length > 0
console.log "No data available for #{ phantom.state }"
else
data = (s, e) ->
e = e or document
el = e.querySelector s
if el then el.attributes.data.value else null
# Execute some DOM inspection within the page context
page.evaluate ->
if document.querySelectorAll('problem_cause').length > 0
console.log "No data available for #{address}"
else
data = (s, e) ->
e = e or document
el = e.querySelector s
if el then el.attributes.data.value else undefined
console.log ''
console.log 'City: ' + data 'weather > forecast_information > city'
console.log 'Current condition ' + data 'weather > current_conditions > condition'
console.log 'Temperature: ' + data('weather > current_conditions > temp_f') + ' F'
console.log data 'weather > current_conditions > humidity'
console.log data 'weather > current_conditions > wind_condition'
console.log ''
forecasts = document.querySelectorAll 'weather > forecast_conditions'
for f in forecasts
console.log "#{ data 'day_of_week', f }: " +
"#{ data 'low', f }-" +
"#{ data 'high', f } F " +
"#{ data 'condition', f }"
console.log """City: #{data 'weather > forecast_information > city'}
Current condition: #{data 'weather > current_conditions > condition'}
Temperature: #{data 'weather > current_conditions > temp_f'} F
#{data 'weather > current_conditions > humidity'}
#{data 'weather > current_conditions > wind_condition'}\n
"""
forecasts = document.querySelectorAll 'weather > forecast_conditions'
for i in forecasts
console.log "#{ data 'day_of_week', i }: " +
"#{ data 'low', i }-" +
"#{ data 'high', i } F " +
"#{ data 'condition', i }"
phantom.exit()