I have some code on CoffeeScript (run under PhantomJS):
class Loadtime
constructor: ->
#page = require('webpage').create()
check: (uri) ->
time = Date.now()
#page.open uri, (status) ->
console.log 'foo'
if 'success' is status
time = Date.now() - time
return time
else
return "FAIL to load #{uri}"
loadtime = new Loadtime()
console.log loadtime.check('http://example.com') # undefined
phantom.exit()
Class have constructor and one public method.
Line #page.open uri, (status) -> ... must call callback function, but it does not call it (line console.log 'foo' does not execute).
Why?
You're calling phantom.exit immediately, so it has no time to load the web page. Add a callback to your check function that you call at the end of the open callback, and call phantom.exit inside the callback passed to check:
class Loadtime
constructor: ->
#page = require('webpage').create()
check: (uri, cb) ->
# ...
#page.open uri, (status) ->
# ...
cb()
loadtime = new Loadtime
loadtime.check 'http://www.example.com/', (time) ->
console.log time
process.exit()
Related
I am using cucumber 3 with protractor 5.2.2. and i have given the url in my config file as baseUrl: 'https://www.linkedin.com' and i have to check whether navigated to the home page after clicking login.Instead of passing URL "https://www.linkedin.com/feed" ,i have pass "feed" and given split method in my step.js file.
my feature file is given below
When I enter "qwerty" in ".username"
And I enter "Passw0rd" in ".password"
And I click on ".login"
Then I should be at the "feed"
and in my step.js
Then(/^I should be at the "(.*)"$/, function (url) {
var geturl=browser.getCurrentUrl() + '';
var res=geturl.split("/");
var result=res[1];
return expect(result).to.eventually.equal(url);
});
My fourth step failed and getting error "TypeError: Cannot read property 'then' of undefined".where i am going wrong in my step.js file.Or how can i check the remaining part of base url when i am on inner page which having a url format of "base.com/feed/profile/profile-edit".Thanks in advance.
Explain your code issue inline at below.
Then(/^I should be at the "(.*)"$/, function (url) {
var geturl=browser.getCurrentUrl() + '';
// browser.getCurrentUrl() return a pomise which it's also a javascript object
// in javascript claculate `an object + ''`, will convert the object
// to string firstly by toString() function,
// if the object not overwrite the supper toString() function,
// it will return an string "[object Object]"
// So geturl = "[object Object]"
var res=geturl.split("/");
// there is no "/" in geturl, so the array length of res is 1
var result=res[1];
// res[1] exceed array length, so result = undefined
return expect(result).to.eventually.equal(url);
// because you used eventually at here, so chai will regard result is a promise,
// chai will check the argument of expect(xxx) is a promise or not
// by detect xxx has property: then via calling xxx.then in chai's inside code,
// but result is undefined, of course has no property: 'then'.
});
You have to consume promise eventual value in then()
Then(/^I should be at the "(.*)"$/, function (url) {
return browser.getCurrentUrl().then(function(cururl){
var parts = cururl.split("/");
return expect(parts[parts.length-1]).to.equal(url);
// dont't use eventually at here, because parts[parts.length-1] is not promise
});
});
I have the filepicker.io dialog coming up fine but on the success call back I seem to lose my 'this' context.
So my code is like this
var fileProcess ={
saveFileInfo: function () {
.....process info here
},
selectFile: function () {
filepicker.pick({ mimetype: 'image/*' }, function (Blob) {
this.saveFileInfo();
});
}
}
So is there something like "context: this" like I can do in an ajax call?
Try creating a new variable named self or me set to the current value of this OUTSIDE your callback. Then, you use closures, so you can access this from your callback through me or self.
Like:
this.mesg = "Hello";
var self = this;
function handler() {
alert(self.mesg);
}
later after a context switch...
handler(); // Will alert 'Hello'
EDIT: Oh nuts... Just realized that won't work... Try:
function handler() {
alert(this.msg);
}
var newHandler = handler.bind(this);
Later...
newHandler();
Function.prototype.bind() takes an object, and returns a function. Whenever the returned function is called, the object passed to bind() is used as this.
I would like to have some function getTagsDict() visible to broder scope, which will be responsible for some GET request to the server and returning dictionary, which can be then easily accesed in loop like:
for k,v of getTagsDict()
For now below code returns some js crap (or at least for js-newbie): http://i.imgur.com/A3YtobD.png
getTagsDict = () ->
$.get '/notifications/ajax_avalaible_search_tags/', (data) ->
data
$ ->
$('#ajax_search_input').on 'keyup', (e) ->
for k,v of getTagsDict()
console.log "#{k} and #{v}"
But when doing GET just inside the calling method everything works well:
$ ->
$('#ajax_search_input').on 'keyup', (e) ->
$.get '/notifications/ajax_avalaible_search_tags/', (data) ->
for k,v of data
console.log "#{k} and #{v}"
QUESTION: How should I use coffee's functions to be globaly and to be utilized as described?
The clue was to build getTagsDict as function with asynchronus ajax call. It can look for example like this:
getTagsDict = ->
strReturn = ""
jQuery.ajax
async: false
url: "/notifications/ajax_avalaible_search_tags/"
success: (data) ->
strReturn = data
strReturn
It would be very useful to me if you could help me fix this function:
textParseQuery = (txtSnippet) ->
queryUrl = "http://localhost:8083/txtParse/#{txtSnippet}"
console.log queryUrl
callback = (response) =>
parsed = $.parseJSON response
companies = parsed.map (obj) -> new Company(obj.name, obj.addr)
companies
res = $.get queryUrl, {}, callback
console.log res
I would like to fetch the results from the callback so that the textParseQuery function could return a value.
The point of a callback is it's asynchronous, your response comes in the callback, so you need to handle the rest of the execution from the callback (e.g., the console.log res is going to execute before your callback is called, since it's part of the same synchronous execution of your ajax call).
textParseQuery = (txtSnippet) ->
queryUrl = "http://localhost:8083/txtParse/#{txtSnippet}"
callback = (response) ->
parsed = $.parseJSON response
companies = parsed.map (obj) -> new Company(obj.name, obj.addr)
# proceed from here
console.log companies
$.get queryUrl, {}, callback
Additional note: the fat arrow is unnecessary here, it's used to rebind what this refers to, but you aren't referencing this at all in your callback. If you're learning coffee, most editors will have plugin/modules to quickly compile coffee to JS, so use that to see what a given coffee syntax compiles to in JS (e.g., take a look at the diff between using -> and => when you compile your coffee)
I have discovered IcedCoffeeScript helps streamline the asynchronous control flow with await and defer. This is what I have tried to achieve. The code structure is how I pictured it
# Search for 'keyword' on twitter, then callback 'cb'
# with the results found.
search = (keyword, cb) ->
host = "http://search.twitter.com/"
url = "#{host}/search.json?q=#{keyword}&callback=?"
await $.getJSON url, defer json
cb json.results
I am calling a simple google api using an HTTP method on the server. It appears I am getting a json object back, yet the callback on the client seems to return an undefined object.
My guess is somehow the result isn't making it to the callback in time. A bit confused.
Full code here:
if Meteor.isClient
Meteor.startup () ->
console.log "Client Started."
Meteor.call("getGeocode", 94582, (error, result) ->
console.log "GeoCode returned to client, #{result}."
Session.set("latitude", result))
Template.results.latitude = () ->
Session.get("latitude")
Template.results.longitude = () ->
"longitude"
if Meteor.isServer
Meteor.startup () ->
console.log "Server Started"
Meteor.methods
"getGeocode": (zipCode) ->
result = HTTP.call("GET", "http://maps.googleapis.com/maps/api/geocode/json?address=#{zipCode}&sensor=false")
console.log "Geocode called, returning #{result}."
Your getGeocode method is returning undefined because CoffeeScript will automatically return the result last statement in the function, which in this case is a console.log.
I don't think result is really want you want though. I recommend including util at the start of your isServer section like so:
if Meteor.isServer
util = Npm.require 'util'
Now you can call console.log util.inspect result, {depth: null} to see what it's made of. I think what you may actually want to return is result.data.results[0]. Your code could look something like:
if Meteor.isClient
Meteor.startup () ->
console.log "Client Started."
Meteor.call("getGeocode", 94582, (error, result) ->
Session.set("latitude", result.geometry.location.lat))
Template.results.latitude = () ->
Session.get("latitude")
Template.results.longitude = () ->
"longitude"
if Meteor.isServer
util = Npm.require 'util'
Meteor.startup () ->
console.log "Server Started"
Meteor.methods
"getGeocode": (zipCode) ->
result = HTTP.call("GET", "http://maps.googleapis.com/maps/api/geocode/json?address=#{zipCode}&sensor=false")
geoData = result.data.results[0]
console.log util.inspect geoData, {depth: null}
geoData