casperjs capturing a "loading.gif" on ajax call - casperjs

I use casperjs 1.1 (phantom 1.9.8) for loggin a website.
After login, there's the spinning throbber and I have:
<div id=throbber style='display: block'></div>
<div id=main style='display: none'></div>
Some dynamic content is loaded in the main div, so after loading:
<div id=throbber style='display: none'></div>
<div id=main style='display: block'>some content</div>
I tried to get a screenshot of the loaded content, since I need to perform clicks and operations, but I always get the throbber picture. I tried to wait 30 seconds, to waitforselector, waitfor document.getElementById('throbber').style.display == 'none' but without luck...
I use the alwex/php-casperjs wrapper (with some handmade additions) so my last try looks like this:
$casper->click('button[type="submit"]');
$casper->waitFor("document.getElementById('throbber').style.display == 'none'"); //implicit 5000 timeout
$casper->capture($screenshot_large, time().'.png');
This particular try returns "'null' is not an object (evaluating 'document.getElementById('throbber').style')" but I'm opened to any alternative.
Thank you for any suggestion or alternative.

casperjs demonstrated to be unreliable with such webpages.
A different solution based on Selenium perfectly worked.

Related

web scraper/crawler that works with ajax

I need to crawl a site and get all the links from it, the problem is - this site uses ajax, and Go's standart http.Get(..) will return something like:
<body>
//javascript here
<div class="content"></div>
//javascript here
</body>
Div is empty. Is there some solution with golang?
http.Get(Url) just get the response of the Url.
resp.Content is like:
<body>
//javascript here
<div class="content"></div>
//javascript here
</body>
if you want to get the content in the div, you need to analysis the javascript and know how the ajax to get data. Then you can simulate the processes the get what you want.
You must use one of the headless webbrowsers.
Without checking i'm saying that there is no Go binding for the three remaining browser engines (Webkit/Firefox,IE).
Switch to python and javascript.

Grails formRemote redirects rather than to just call method

I'm new to Grails and got some problem with the g:formRemote command..
I want a g:textArea box send a message to my controller and save this messages.
After that the page should be updated via the formRemote Ajax, so that the messages appear on the page.
But instead of updating the page, the formRemote call assumes the given url to be a real link and wants me to redirect to this (non-existing) .jsp site.
The Method I want to start is called in my controller tho
I tried many solutions offered in similar problems, but it seems this problem is different from theirs
Heres the code:
<div id="history">
<g:render template="posts" collection="${ messages }" var="message" />
</div>
<div class="postMessageForm">
<g:formRemote name="postChatMessage" url="[controller: 'meetingRoom',
action: 'postMessage']" update="history">
<div class="msg_box">
<g:textArea name="message" value="" style="width: 630px"/><br/>
</div>
<div style="float: right;">
<g:submitButton name="Send" style="width: 90px; height: 40px;"/>
</div>
</g:formRemote>
</div>
and this is the Action which is called in my MeetingRoomController:
def postMessage() {
if (params.message != "") {
def thisUser = lookUpUser()
def thisRoom = thisUser.joinedRoom
def chatPost = new ChatPost(
message: params.message,
author: thisUser
)
thisRoom.addToChatHistory(chatPost)
}
// def messages = currentChatHistory()
// render template: 'posts', collection: messages, var: 'message'
I saw this kind of approach in Jeff Browns Twitter tutorial.
Possible failures i am seeing:
the out-commented render template command has something to do with the Ajax (When I do not comment it the only thing that happens is that the template posts will be rendered on the redirected page
usage of both Ajax and jQuery (But i dont believe that can be the point because I just have used g: and groovy stuff and havent even imported a jQuery lib)
this could be easier with remoteFunction (I dont really know how to get the remoteFunction work in this case tho)
I hope this information is enough to let someone see what I am missing
When the submit button is clicked on your form, the data is sent to the method listed in the url parameter of the formRemote tag. Then you are inside that method, you get to the commented out render tag that outputs data back to the gsp page in the div mentioned in the update tag of the formRemote tag.
formRemote relies upon a javascript library to handle the ajax stuff as mentioned in the grails documentation:
7.7.1 Ajax Support
By default Grails ships with the jQuery library, but through the
Plugin system provides support for other frameworks such as Prototype,
Dojo:http://dojotoolkit.org/, Yahoo UI:http://developer.yahoo.com/yui/
and the Google Web Toolkit. This section covers Grails' support for
Ajax in general. To get started, add this line to the tag of
your page:
You can replace jQuery with any
other library supplied by a plugin you have installed. This works
because of Grails' support for adaptive tag libraries. Thanks to
Grails' plugin system there is support for a number of different Ajax
libraries including (but not limited to):
jQuery Prototype Dojo YUI MooTools
So remove what is in the history div, uncomment the two lines in your postMessage method, and include one of the referenced javascript libraries.

How to store to browser auto-complete/auto-fill when using AJAX calls

I've noticed that browsers do not store form values until the form is submitted, which means that if you're using AJAX instead of a standard form submit, your browser's auto-fill is never populated. Is there a way to force populate your browsers auto-fill/auto-complete so that I can have this convenience with forms that are submitted via AJAX? It's annoying to go to my AJAX page and have to type in the same things in the form fields every time because the browser doesn't remember them.
My question is pretty much identical to the this one, except that only a work around in FireFox is provided as the accepted answer to that question. I'm looking for a solution that works in all major browsers (at least Chrome, FF, and IE), if there is one.
Note: I am not talking about AJAX auto-complete plugins, which is what almost always pops up when googling this question. I am talking about your browser's built-in auto-complete or auto-fill that helps you fill out forms by remembering what you entered in the past.
For anyone who's still trying to solve this, seem like I've found the answer.
Chromium tries to recognize the submit event, even if you preventDefault and handle the actual submission yourself.
That's it, you need to preventDefault the submit event, not the click event.
This worked on Chrome, Edge and IE 11 at the time of writing (I'm too lazy to download and test it on Firefox).
Here's your form:
<form method="POST" id="my-form">
<label>Email</label>
<input autocomplete="email" type="email" name="email">
<button type="submit">Subscribe</button>
</form>
Notice the autocomplete attribute. These are all the possible values that you can use for autocomplete.
In JavaScript, simply do this:
$("#my-form").on("submit", function (ev) {
ev.preventDefault();
// Do AJAX stuff here
});
The browser will remember whatever email you've entered on clicking subscribe button.
I have also come across this; there doesn't seem to be a great solution, certainly not a cross browser one, but here is one for IE I haven't seen anyone mention:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<SCRIPT>
function subForm()
{
window.external.AutoCompleteSaveForm(f1);
f1.submit();
}
</script>
</HEAD>
<BODY>
<FORM id=f1>
User ID : <input type=text name=id></input><br>
Password :<input type=password name=pw></input><br>
E-mail :<input type = text VCARD_NAME = "vCard.Email"> <br>
<input type=button value=submit onclick="subForm()">
</FORM>
</BODY>
</HTML>
From: http://support.microsoft.com/kb/329156
Use this Method:
AutoCompleteSaveForm = function(form){
var iframe = document.createElement('iframe');
iframe.name = 'uniqu_asdfaf';
iframe.style.cssText = 'position:absolute; height:1px; top:-100px; left:-100px';
document.body.appendChild(iframe);
var oldTarget = form.target;
var oldAction = form.action;
form.target = 'uniqu_asdfaf';
form.action = '/favicon.ico';
form.submit();
setTimeout(function(){
form.target = oldTarget;
form.action = oldAction;
document.body.removeChild(iframe);
});
}
Tested with ie10, ff latest, chrome latest
Test yourself: http://jsbin.com/abuhICu/1
Have you try the answer of my question that you mention?
The answer is using hidden iframe but seems he claim the idea is not working on IE and Chrome on that time.
Try to take the idea, and instead of using hidden iframe, just put the username/password/submit visible input element in a form POST, in an iframe. So user will enter login details directly into iframe. With proper Javascript you can put loading image, get success or denied from server and update the parent or the whole page. I believe it should work on any browser.
Or if you still want to use AJAX since you probably implemented the API on server side. You can make the iframe to just send a dummy POST at the same time send the real user/pass to AJAX URL.
Or back to use hidden iframe, not to hide it but move it to the invisible area like top: -1000px.
After several hours searching, I found a solution at Trigger autocomplete without submitting a form.
Basically, it uses a hidden iframe in the same page, set the action of your form to the 'src' of the iframe, and add a hidden submit button inside the form, when user clicks your button which triggers AJAX requests, you should programmatically click the hidden button before sending the AJAX request. see example below:
In your form page:
<iframe id="hidden_iframe" name="hidden_iframe" class="hidden" src="/content/blank"></iframe>
<form target="hidden_iframe" method="post" action="/content/blank" class="form-horizontal">
<input type="text" name="name">
<input type="text" name="age">
....
<button id="submit_button" type="submit" class="hidden"></button>
<button id="go_button" type="submit" class="hidden">Go</button>
</form>
Then java script:
$('#go_button').click(function(event){
//submit the form to the hidden iframe
$('#submit_button').click();
//do your business here
$.ajax(function(){
//whatever you want here
}})
);
Hope this helps.

load webpage in several parts using ajax

I want to load a webpage in several parts, maybe using jquery ajax or just simple javascript ajax functions so the user can start interacting with the webpage withouth having to wait for the whole page to load. Just like gmail does.
How can I achieve such a thing?
Generally you need to dedicate some div containers for inserting dynamically loaded contents.
<div id="header"></div>
<div id="content"></div>
<div id="sidebar"></div>
<div id="footer"></div>
Then you can load other pages on startup.
$(function(){
$('#content').load('content.php');
$('#content').load('sidebar.php');
});
Of course this is only a start. You have to check for errors on loading and retry. Also using hash value you can dynamically load content & sidebar. etc..

jQTouch AJAX Form Callback

I've got a simple AJAX POST form set up in a jQTouch application. We're talking out-of-the-box simple here:
<form id="contact" class="topPage" method="post" action="/process/mobile-submit.cfm">
<!-- Various form guts go here -->
</form>
And this works just great. My users punch in their info, my server-side script does its job and gobbles up the lead data and spits back an out-of-the-box simple response.
<div>
<div class="toolbar">
Back
</div>
<div class="info">
<strong>Thank You For Your Submission</strong><br />
We have received your inquiry, and blah blah blah jibber jabber.
</div>
</div>
Everyone's happy... except those of us who are trying to track the conversion in Google Analytics. Now, I've got virtual pageviews set up on each panel in this application using the pageAnimationEnd event, which is easy as pie when you know what selectors those are going to be attached to in advance, but when jQTouch creates a new segment from the form return, it has a generic serialized ID like #page-N.
I've tried adding a loose script block into the form return. That works fine for Firefox on my desktop, not so much for Safari on my phone.
Since I've allowed jQTouch to handle the AJAX particulars for me in this instance, is there a straightforward way to attach a success handler to it? Or am I better off trying to bind a pageAnimationEnd handler on $('[id^=page-]') and hope the business doesn't want me to do anything else with ad hoc form returns until we replace this app with one written in jQuery Mobile?
Worked it out.
The return fragment can declare its own ID, naturally, and jQTouch will then treat it as though it were an original part of the document. I had previously assumed jQTouch didn't give a toss about what attributes I gave the fragment; I was wrong.
This means that you could goTo it like any other portion of the document. It also means that you can bind a pageAnimationEnd handler on the return fragment either by ID or by class name and it will behave as expected. Thus:
<div class="formResult">
<div class="toolbar">
Back
</div>
<div class="info">
<strong>Thank You For Your Submission</strong><br />
We have received your inquiry, and blah blah blah jibber jabber.
</div>
And:
$('.formReturn').live('pageAnimationEnd', function(evt, info) {
if (info.direction == 'in') {
// Goal completion code
} else {
$(this).remove();
}
});

Resources