I'm writing code that involves jQuery in CasperJS. By chance, could someone point out the error I've made in including jQuery? (After 45 minutes of searching, I'm starting to think it's a local problem.)
I have tried both of the following:
casper.page.injectJs('C:\sweeps\jquery-1.10.2.min.js');
and
var casper = require('casper').create({
clientScripts: ["C:\sweeps\jquery-1.10.2.min.js"]
});
Code:
// sample.js
var casper = require('casper').create();
var login = "some username";
var password = "some password";
casper.start('https://www.paypal.com/us/home', function() {
this.fillXPath('form.login', {
'//input[#name="login_email"]': login,
'//input[#name="login_password"]': password,
}, true);
});
casper.page.injectJs('C:\sweeps\jquery-1.10.2.min.js');
$("input[name='submit.x']").click();
setTimeout(function(){
setTimeout(function(){
casper.run(function() {
this.captureSelector('example2.png', '#page');
this.echo('Done.').exit();
});
}, 30000); }, 1);
Output:
ReferenceError: Can't find cariable: jQuery
C:/sweeps/test2.js:21
The same result comes when "jQuery" is switched to "$".
EDIT: I've also tried relative pathing.
My reference is: Can I use jQuery with CasperJS?
Read this Casper#evaluate()
The concept behind this method is probably the most difficult to understand when discovering CasperJS. As a reminder, think of the evaluate() method as a gate between the CasperJS environment and the one of the page you have opened; everytime you pass a closure to evaluate(), you’re entering the page and execute code as if you were using the browser console.
casper.evaluate(function() {
$("input[name='submit.x']").click();
});
You need to use the jQuery selector as if you were in a browser.
Your path to the javascript file should be a URI relative to your HTML file, not a file-system path. Assuming your files are in the c:\sweepstakes folder, try
var casper = require('casper').create({
clientScripts: ["jquery-1.10.2.min.js"]
});
Also, use your browser's network/dev tools to see if your jQuery library is being downloaded or not.
Related
I'm currently making my first effort into porting a webpage to Wordpress, so forgive my inexperience on the subject.
In my page, I have the following code:
function workLoad() {
$.ajaxSetup({ cache: false });
$('.thumb-unit').click(function() {
var $this = $(this),
newTitle = $this.find('strong').text(),
newFolder = $this.data('folder'),
spinner = 'Loading...',
newHTML = 'work/'+ newFolder +'.html';
$('.project-load').html(spinner).load(newHTML);
$('.project-title').text(newTitle);
});
}
In the past, this has worked fine hosted both locally and on Github. However, running my wordpress build locally through MAMP gives me the following error:
jquery-2.1.1.min.js:4 GET http://localhost/work/proj-1.html?_=1485348127113 404 (Not Found)
The URL should be fine, except for the part where it adds the ?_=(number). I'm not familiar with this behavior or what causes it. I tried changing work/ to /work/, since the dir is in the root folder, but that didn't solve it. I also have tried changing the variable to
newHTML = '< ?php bloginfo('template_directory')' + '/work/'+ newFolder +'.html';without the space after the opening bracket but to no avail. I also tried putting that bit in its own var, but it keeps adding ?_=1485348127113 to the URL of the html file I want to load, resulting in a 404 error.
What causes this? Thanks in advance for any advice you could share.
This timestamp is added for You to obtain the latest version of the file using ajax load.
If You want to disable this behaviour, You should set
$.ajaxSetup({
cache: true
});
This will enable caching and Your request would not contain the ?_=1485348127113 part anymore. This parameter should not cause the 404 not found error. Please check your path.
This question already has an answer here:
CasperJS bind issue
(1 answer)
Closed 8 years ago.
I'm having troubles trying to scrap the price of this webpage: http://www.voyages-bateau.com
It looks easy but any of the scraping services/tools I try seems to work with this page. Its content is loaded via ajax and the price appear later with an animation. I try the wait() and waitFor() helpers with no luck...
Here's the code I used to fetch this bad boy:
var casper = require('casper').create({
verbose: true,
logLevel: "debug"
});
casper.start('http://voyages-bateau.com', function() {
console.log(this.getHTML()); // no content loaded yet
});
casper.waitForSelector('//*[#id="WRchTxt0-3cb"]/h2[3]/span', function() {
var res = this.getHTML();
this.echo(res);
});
casper.run();
All I got is the error: "Wait timeout of 5000ms expired, exiting.". Any ideas ?
The main issue is that PhantomJS 1.x has no support for Function.prototype.bind. The workaround can be found here: CasperJS bind issue. Because of this none of the JavaScript runs, since there is a page error and you see nothing, because it is a JS driven page.
You can verify this by registering to the page.error event:
casper.on("page.error", function(pageErr){
this.echo("page.err: " + JSON.stringify(pageErr));
});
This yields this
page.err: "TypeError: 'undefined' is not a function (evaluating 'b.bind(a)')"
page.err: "TypeError: 'undefined' is not a function (evaluating 'c.bind(null,\"margin\")')"
page.err: "TypeError: 'undefined' is not a function (evaluating 'RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\\d_.\\-]*$/)')"
Which otherwise doesn't pop up with debug output or verbose enabled.
The other issue is that you forgot to use the XPath utility for XPaths:
var x = require('casper').selectXPath;
somewhere at the top and later:
casper.waitForSelector(x('//*[#id="WRchTxt0-3cb"]/h2[3]/span'), function() {
var res = this.getHTML();
this.echo(res);
});
Without the XPath utility, it tries to interpret this as a CSS selector. Since you have verbose: true, you have to have seen
[error] [remote] findAll(): invalid selector provided "//*[#id="WRchTxt0-3cb"]/h2[3]/span":Error: SYNTAX_ERR: DOM Exception 12
I am trying to make use of the new 1.1 eachThen() API in casperJS however I am finding some strange behaviour with it.
Below follows a simple application
var casper = require('casper').create({
verbose: true,
logLevel: "error"
});
var urls = ['http://google.com/'];
casper.start();
var testvar = "";
casper.then(function() {
urls = ['http://yahoo.com/', 'http://www.youtube.com/'];
});
casper.eachThen(urls, function(response) {
console.log("Opening: "+response.data);
this.thenOpen(response.data, function(response) {
testvar = response.url;
});
});
casper.run();
The way I understand it is that this application should open yahoo.com followed youtube.com however the array assignment on the step before does not seem to be taken in consideration at all and the output will be "Opening: http://google.com/".
Is anybody aware of any limitation on doing this or is this possible a bug in the current (beta) version of casperJS. I am using the latest 1.1.0-DEV
To answer my own question, wrapping the whole thing in a then() step does the job as explained by hexid in the comments however it seems that doing it as a "standalone" is not possible (Either due to a bug or by design, uncertain to me at the moment).
I'm using CasperJS 1.0.2 under PhantomJS 1.8.1 on Windows 8.
Trying to write a test for a web site. The site is heavily reliant on JS and the coding principals are quite unusual, which may be creating some problems but I'm not sure.
Here is the code I'm using to test login and search function:
var url = 'http://www.testsite.com/';
var casper = require('casper').create();
casper.start();
casper.start(url, function() {
this.echo('Page: ' + this.getTitle());
this.capture('start.png');
if (this.exists('input#TxtUserName')) {
this.sendKeys('input#TxtUserName', 'testlogin');
this.sendKeys('input#TxtPassword', 'testpass');
this.click('input#BtnLogin');
this.capture('loggedin.png');
}
});
casper.then(function() {
this.capture('beforesearch.png');
this.sendKeys("input#txtSearch", '1002');
this.click("input#cmdSubmit");
this.echo('Searching');
this.capture('aftersearch.png');
});
casper.run();
When I run this code, every page on the screen capture is the same with the exception that the login information is filled in on login.png. At no point does it actually login (using my real login credentials) after the click event. The search results also don't show after that click is fired.
Any clue what could be causing this?
Here is my waitFor code after submitting the search:
casper.waitForText("Part:", function() {
this.capture('searchresults.png');
});
You should use casper.waitFor to make sure the next page has been loaded. Otherwise phantom will take the screenshot before the form submit has been answered.
This is what I am trying to accomplish:
Get the static content of an 'external' url and check it for certain keywords for example, "User Guide" or "page not found".
I tried to use Ajax, dojo.xhr etc., but they don't support cross domain. In my case it is an external url. Also, I cannot use jQuery.
I also looked at dojo.io.iframe but I couldn't find useful example to accomplish this.
A dojo.io.iframe example would be really helpful.
Please help.
Thanks!
Modern browsers restrict the use of cross-domain scripting. If you're the maintainer of the server, read Access-Control-Allow-Origin to get knowledge on how to enable cross-site scripting on your website.
EDIT: To check whether an external site is down or not, you could use this method. That external site is required to have an image file. Most sites have a file called favicon.ico at their root directory.
Example, testing whether http://www.google.com/ is online or not.
var test = new Image();
//If you're sure that the element is not a JavaScript file
//var test = document.createElement("script");
//If you're sure that the external website is reliable, you can use:
//var test = document.createElement("iframe");
function rmtmp(){if(tmp.parentNode)tmp.parentNode.removeChild(tmp);}
function online(){
//The website is likely to be up and running.
rmtmp();
}
function offline(){
//The file is not a valid image file, or the website is down.
rmtmp();
alert("Something bad happened.");
}
if (window.addEventListener){
test.addEventListener("load", online, true);
test.addEventListener("error", offline, true);
} else if(window.attachEvent){
test.attachEvent("onload", online);
test.attachEvent("onerror", offline);
} else {
test.onload = online;
test.onerror = offline;
}
test.src = "http://www.google.com/favicon.ico?"+(new Date).getTime();
/* "+ (new Date).getTime()" is needed to ensure that every new attempt
doesn't get a cached version of the image */
if(/^iframe|script$/i.test(test.tagName)){
test.style.display = "none";
document.body.appendChild(test);
}
This will only work with image resources. Read the comments to see how to use other sources.
Try this:
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js.uncompressed.js" type="text/javascript" djConfig="parseOnLoad:true"></script>
<script>
dojo.require("dojo.io.script");
</script>
<script>
dojo.addOnLoad(function(){
dojo.io.script.get({
url: "http://badlink.google.com/",
//url: "http://www.google.com/",
load: function(response, ioArgs) {
//if no (http) error, it means the link works
alert("yes, the url works!")
}
});
});
</script>