How does readyState work? - ajax

I check the property .readyState of BrowserTestObject using RFT (Rational Functional Tester).
Sometimes before the next step in my test script I need to be sure that the page is 'ready' and all objects are loaded.
Does the .readyState == 4 mean that all objects within the browser are loaded and ready? Could any ajax call in background be still "working" or it must finish before the browser returns .readyState=4? What about a flex application?
Is that behavior browser independent or not really? I am after IE 8 (and firefox 3.6.x)

quick answer is YES if browser implementation is correct.
See here: http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#current-document-readiness

I would say no. If I understood discussion here, readyState used thus only refers to the test javascript, nothing else. To wait that the document itself is loaded, you need to hook to document.readyState and wait for it to become "complete". In that case, once the HTML parsing is complete, the document.readyState would be "complete" once and for all, and will not be affected by any XMLHttpRequest whatsoever. Flash plugins could or could not have started; most certainly there would be lots of javascript running; for example $(function() {}) construct in jquery often means that javascript code could start executing only after the browser hits the "complete" state.
To test if any asynchronous requests are going on, I suggest hooking the readyState event of all XMLHttpRequests somehow and make it update a global variable.

Related

Cypress and find the element programatically, but its there and the UI can select it

I am having issues get'ing a css selector, its on the dom, and it can even be selected via the UI.
But cypress fails to get it.
There is not async stuff going on, just the page that was loaded.
As you can see in the image thelement is there, any ideas how to get round this?
If you say that the problem is with loading the page, maybe you should pass timeout paramater to the cy.get(), to make sure that Cypress waits long enough.
cy.get('nli-block-container .block-content', {timeout: 20000})
This should wait for 20 seconds for the element. If that doesn't work, please let me know, because it means that the problem lies elsewhere

CasperJS not finding element by class when loaded via ajax

I used several methods of attack attempting to get Casper to see the element in question, which gets loaded via a 2nd GET request that returns a bunch of json to get loaded into the page's DOM.
The thing is this.waitForResource(url,....) works fine executing the success callback after about 2 seconds (I have a timeout of 20 set).
I then tried first this.click('.class-name') inside followed by this.evaluate(function(){document.getElementsByClassName('.class-name')[0].click()});
Click via casperJS returns CasperError: Cannot dispatch mousedown event on nonexistent selector: .class-name while I'm not sure what the DOM action does - my this.on('resource.received',....) call immediately after doesn't capture anything so I assume it also had no effect either. DOM code seems to fail silently in Casper sometimes.
What can be done to select elements and click them to download files only after they are loaded into the DOM via ajax?
Is there a better library than CasperJS for this?
Casper has waitForSelector and waitFor methods that will suit your need.
waitFor will wait until provided function returns true
waitForSelector will wait until provided selector is in DOM, so I guess this is the one you want to use.
Additionaly there is waitUntilVisible which wait until an element is visible on screen

Watir and Ajax requests

In my webapp I have a simple textfield. To this textfield I have a jQuery function which will be always executed on every keyup. With this function there is an Ajax request assigned which loads every time the result of the SQL-Query. My code is equivalent to the code of
RailsCasts. Now I'm testing my webapp with Selenium. With this line of code
browser.text_field(:id => 'textfield').set("Search text")
the text will be written and the content will be changed. After it should click on a link which is placed on the dynamic content with this code
browser.a(:id => "link").click
The problem now is that the click event won't be executed. Has somebody an idea what the problem could be? Or maybe an example with Watir and Ajax?
Without an example site to test against it's hard to be sure but I will throw out a few potential solutions for you
If the client side javascript is looking for onkeyup events, you may need to fire one after setting the contents of the field. You can do that via the .fire_event method
You could just be looking at a timing issue. If the nature of the link is changing as a result of the input, it's possible that Watir is firing off the two comments in rapid succession and the client side code is still in the midst of doing it's thing (especially if there is back and forth between the jquery code and the webserver that as happening as that also induces networking delays. You may need a brief sleep between commands (brute force) or to wait for a particular element to assume an expected state (a little more work but also a bit more robust and not subject to breaking is the delay exceeds your sleep duration)
I'd suggest executing the commands manually via IRB (you could just cut and paste from your script as needed) to be able to watch the state of the browser, and note any delay in updating the screen/DOM after a particular action. If stuff works properly in IRB but not when executed via a script it's often taken as confirmation of a timing issue.
If this is the original Watir/Firewatir I would try getting it to hover over the link before it attempts to click it.
I've had this problem previously with links that appear after typing into an "autocomplete" field (i.e. it attempts to guess at the text you want by filtering down from a huge list of possibilities).
Try this:
browser.wait_until{browser.link(:id => "link").present?}
browser.link(:id => "link").fire_event("onmouseover")
browser.link(:id => "link").click
If it works, try it without the .fire_event("onmouseover"), because it could just be that it's trying to click the link before it's visible and failing to do so.
If this is actually a question regarding "Selenium" (wrongly labelled Watir) then ignore all of the above, because I that is an application I've never used.
you can use capybara method.
click_link("link")
for ajax set :js => true in you test case
http://opinionatedprogrammer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/

AJAX: If you set the async to false will the whole page reload?

Does teh whole page reload when this is set to false?
My main question is what the asynchronous does. yes i know what the word means but what does it do in code?
xmlhttp.open("GET","ajax_info.txt",true);
The word "asynchronous" is best described as "done in the background" in this context. It means that if you set this parameter to true, the request will be sent in the background and the user will be able to continue interacting with the page. If you set it to false, the page will BLOCK and the user won't be able to do anything until the request returns.
Note that this is different from the whole page reloading. The amount of traffic going over the wire is still much smaller than the whole page reload, so many of the AJAX benefits are preserved.
One reason why you might want to use synchronous (blocking) AJAX requests is when there's nothing to really do on the page while the request is loading.
BTW, since we're already on this subject: I encourage you to use a javascript framework for your AJAX needs. jQuery is fantastic. Don't use the XMLHttpRequest object directly.
Having used jQuery's ajax I found some issues with IE compatibility, so if you have to support IE6, it may be a good idea to avoid that and use straight JS.
Here's a good tutorial on it:
http://daniel.lorch.cc/docs/ajax_simple/

Detect when AJAX changes HTML in a DIV in WebBrowser

After I load a page through a WebBrowser, and I click a link that fires an AJAX script, I need to detect when the AJAX java script finishes loading HTML changes into a div. Since no DocumentCompleted event is fired when the AJAX script is run, I don't know when it finish running. Is there a way I can attach an event to be raised after I know 100% that the javascript finished changing the div?
The project is in C#.
Thanks
I did something similar recently (using jQuery):
$('#mydiv').change(function(){
// do stuff
}
);
Granted, I also use jQuery to set the HTML of that div. I suppose one non-jQuery approach for you could be to set HTML through your own function, which in turn can fire an onchange event.
#New in town: From my experience that is not correct. I use this on multiple DIVs that never get focus in the first place, and it works well and consistently. The normal behavior is as you describe, and normally only applies to the INPUT and SELECT elements, but this is not the case with jQuery.
There is no event. You must patch the JavaScript callback that the browser runs when the reply for the AJAX request comes in. This will contains code like "div.innerHTML = ...". Just put your code below that.

Resources