I'm trying to test a page using CasperJS, in particular I want to poke the data model a bunch. Let's say I've got a basic function called taxes, and I want to ensure that it uses the right tax rate. So I'd like something like:
this.test.assert(taxes(100, 'Ontario') === 15, "Check ontario tax rate");
Rather than filling out a form and seeing what it prints. That taxes method exists in the global scope, so I'm able to execute it quite easily from anywhere (including from the console in firebug or Chrome). But it's not in the right scope for that to work inside CasperJS (I think? I'm getting ReferenceError: Can't find variable: taxes.
It seems like I'm missing something simple.
TL;DR: How do I execute an on-page bit of JS directly inside a CasperJS test?
Have you tried using evaluate()?
relevant quote: "execute code as if you were using the browser console."
something along the lines of:
casper.evaluate(function(amount, province) {
return taxes(amount, province);
}, {100, 'Ontario'});
Use assertEvalEquals() method.
If you're calling the method via a jQuery-style reference, make sure to explicitly include the library, lest you'll get the ReferenceError:
var casper = require('casper').create({
clientScripts: ['js/jquery-1.7.2.js']
});
...
casper.start('foo.php',
function() {
console.log(this.evaluate(function() {
return $('taxes').text();
}));
});
casper.run();
See: https://groups.google.com/forum/#!msg/casperjs/2uyUOqdzShw/bHWrJYXni40J
If you're calling it implicitly in the global scope (i.e., straight javascript, rather than, for example, $('taxes')), you might have to explicitly prepend the window or document namespace to the reference:
document.querySelector('#taxes').value = taxes_text;
Related
I'm trying to modify/limit/prevent access to certain JS commands of my browser. For example commands like navigator.clipboard; However, I'm not sure how to approach this.
Is it possible to override these commands with user-defined javascript injected in the page, or do i have to edit the browser's javascript compiler and re-compile it from source for this?
I'm not really familiar with browsers and want to save time by knowing a general direction to follow. Thanks
First of all navigator.clipboard is not a function, but here is an example using the read function of navigator.clipboard:
navigator.clipboard.read = function (originalFunction) {
return function (yourParamsYouWantForThisFunction) {
// Do Stuff you wanna do before the real call. For example:
console.log(yourParamsYouWantForThisFunction);
// Call the original function
return originalFunction.call();
};
}(navigator.clipboard.read); // Pass the original function reference as a parameter
You may wonder, why there are two function statements:
The first one is there, so that we can pass the original function at runtime. If we would not do that, we would not be able to access the original navigator.clipboard.read function.
The second function is the actual function, that you will be using later, when you call navigator.clipboard.read().
carts.js.coffee
$(document).ready ->
add_book: () ->
alert "hihi!!"
I have tried to invoke window.add_book(); and add_book(); in
add_to_cart.js.erb
But both can not work.
add_book();
window.add_book();
And there didn't display the error on Firebug or Webrick console
By the way, I can not understand
What is the meaning when vars or functions in
(function() {})
or when function embraced by {{ }}
({
add_book: function() {
return alert("poc123!!");
}
});
Is there any tutorial or keyword term can let me find related resources?
Thanks in advance
The reason is you can't use $(document).ready in js erb or coffee erb.
When you deliver this js erb through Ajax, document has been ready for a long time. The functions inside your erb will never get chance to be called if they are under document ready.
So the simple fix is, remove document ready, and invoke the functions directly.
I'm not sure what you expect using add_book: inside a function, but that's certainly not what you wanted. Here is the generated javascript for your code :
$(document).ready(function() {
return {
add_book: function() {
return alert("hihi!!");
}
};
});
You are returning an object containing the function, but no one can access it since it's not referenced by anyone.
What you want is a variable, able to contain a reference :
$(document).ready ->
window.add_book = () ->
alert "hihi!!"
Now, you can use it anywhere (after domready, of course), calling directly add_book().
If your use chrome, this extension may help you to spot coffeescript problems : it's a live shell that let you see the computed js and run coffeescript code.
On a side note, I would recommend against using coffeescript until you feel fluent with javascript.
I'm trying to use tripleflap.js in my app. My view is calling the function:
<script type='text/javascript' charset='utf-8'>
TwitterBird();
</script>
So, in application.js:
function TwitterBird() {
var twitterAccount = 'ulmicru';
var showTweet = false;
var birdSprite='http://127.0.0.1/birdsprite.png';
tripleflapInit();
}
Then I'm trying to run it, and Javascript debugger says me:
Uncaught ReferenceError: birdSprite is not defined
In precompiled application.js in /public/assets/ I'm watching this:
function TwitterBird()
{var e="ulmicru",t=!1,n="http://127.0.0.1/birdsprite.png";tripleflapInit()}
It seems Rails precompiler had renamed variables, and tripleflap.js cannot find them.
Is it possible to disable variable renaming in assets?
Try to move the variable definitions outside of the function, or just remove the var from in front of them, like this:
function TwitterBird() {
twitterAccount = 'ulmicru';
showTweet = false;
birdSprite='http://127.0.0.1/birdsprite.png';
tripleflapInit();
}
I googled the tripleflapInit script and took a look at it. Basically it defines a bunch of configuration variables directly on the window and expects you to overwrite them; a pretty kludgy script all in all, but that's beside the point.
Because you're defining birdSprite inside a function with var, you're actually defining a new variable local to that function. Even if it was not renamed by the minifier, the window-defined tripleflapInit would still not use it, but rather look to the variable defined on the window.
I'm not sure why you're getting the error that birdSprite is not defined, but it's possible that the compiler became confused and removed it, thinking it was unused.
I am trying to use javascript to run AS3 functions. When I attempt to compile I'm getting an "Access of undefined property" error message.
I've read a few things online about this but I'm still not understanding it. I want to have the flash file always listening for javascript.
Here is my AS3 code:
ExternalInterface.addCallback("song4", PauseMusicExt);
And my Javascript & HTML:
function returnVar3(song3) { return this[song3]; }
<input type="submit" name="playButton" id="playButton" value="Submit" onClick="returnVar('song3')"/>
Edit: Here is the pauseMusic function:
function pauseMusicExt():void
{
songPosition = channel.position;
channelSilence.stop();
channel.stop();
channel2.stop();
btnPlay.mouseEnabled = true;
}
I'm not sure about the extend of your app but you've got your addCallback function parameters mixed up..
See the doc, the first parameter is the name you want to expose the function as to javascript, the second is the actual internal AS3 function you want to trigger.
So the declaration should likely be something like:
ExternalInterface.addCallback("song4", pauseMusic);
(assuming that your function in the same scope as where you call addCallback)
That statement will create a "song4" method that you can call on your flash dom object
var fl = document.getElementById('myflashobject');
fl.song4()
After there's the issue that pauseMusic want a parameter (looks like you've made it a mouse event handler). You probably want to have a clean method that doesn't require a parameter like an internal as3 event param. Rewrite pauseMusic so it doesn't require it (you might need to create another method to handle the mouse event internally - like onPause(evt:MouseEvent), which then calls pauseMusic.
Edit: I don't know if a lot of people thought about doing that, but you can also totally use external interface to call firebug's console.log function to send messages to Firebug from flash (it's really helpful for debugging ExternalInterface issues, or any other flash problems - see the ExternalInterface.call function)
Hope u want to pause the audio player.
AS code :
ExternalInterface.addCallback("sndToAS",rcvdFmJS);
function rcvdFmJS(val){
if (val == "pause"){
audioPause();
}
}
JS code :
document.getElementById("movie").sndToAS("pause");
My Javascript knowledge is less experienced, so I might use wrong descriptions in the following.
I have an object in a static .js file:
var Info = {
methodA: function() {
// Call methodB.
this.methodB('test');
},
methodB: function(value) {
// Do stuff
}
}
Now, in an .aspx file, I create a function methodC(value) with varying contents (depending on some data), which I want to insert instead of the above definition of methodB(value):
...
var methodC = function(value) {
// Do different stuff
}
...
My idea has so far been to replace methodB with methodC in the following fashion:
...
Info.methodB = methodC;
...
Using IE's buildin developer tool, I get the following error when calling this.methodB('test'); from Info.methodA():
Object doesn’t support this property
or method
Removing the 'this' from this.methodB('test') results in the error:
Object expected
I don't get any errors using FireBug - probably because I use various frameworks, which might catch the error.
How should I do this or should I use a completely different approach?
Regards, Casper
It should work, you are doing it the right way. The problem lays elsewhere.
update:
This should still work as long as you call methodA on an object, eg Info.methodA().
Maybe you are not understanding the error messages ?
"Object doesn’t support this property or method" means that in the expression "this.methodB()", this doesn't have a property named "methodB". So it means that this is not Info when the code of methodA is executed.
"Object expected" means that the variable methodB is unknown in the current execution context. Of course it is, since methodB is never a variable, only a property of Info.
To debug your problem, you need to know what is this when a code is executed, and why it's not what you think it should be. When you call Info.methodA(), this is set to be Info when methodA begins its execution.