Selenium: Ajax Testing - selenium

Please brief me about the Ajax testing with selenium RC.
As in Ajax element not reflect on the view-source, but using firebug we can see the changes in HTML source code.
There are two methods associated with it Ajax testing..
1-The method "waitForCondition (java.lang.String script, java.lang.String timeout), to provide script we have to create a java script by own or it should be the same Ajax script/java script present on the web page.
Please correct me if i am wrong on below point..
2-The method "waitForElemantPresent(Locator)", We check the Element in the firebug and check the same in this method is self waitForElemantPresent(Locator).
Let me know if anything else I am missing testing Ajax application.

I got help on this from one article and with help of #Hannibal
http://agilesoftwaretesting.com/?p=111
JQuery: “jQuery.active”
Prototype: “Ajax.activeRequestCount”
Dojo: “dojo.io.XMLHTTPTransport.inFlight.length”
So if there is Ajax call we can use second option.
selenium.waitForCondition(
"selenium.browserbot.getCurrentWindow().jQuery.active == 0",
timeout);

To answer your first point, yes waitForCondition(javascript,timeout) will run the javascript till it returns a true value OR when timeout happens. You should take a look at the api documentation for this as you need to use browserbot to run the script in your application window. Link to API documentation is here
In Selenium 1, one way by which you can handle the Ajax conditions are by creating custom functions which will wait till the condition is met or till a timeout happens. While a normal Selenium.isElementPresent will fail immediately if the element is not present, your custom function will wait for some more time (the time for Ajax to load) before it fails. As an example you can refer the following custom method for isElementPresent. This is written in JAVA, you should be able to use the same logic in the programming language that you use.
public boolean AjaxIsElementPresent(String elementToLookFor, int timeOutValueInSeconds){
int timer=1;
while(timer<=timeOutValue){
if(selenium.isElementPresent(locator))
return true;
else
Thread.sleep(1000);
}
return false;
}
This method will return a boolean false if the element is not present even after the specified timeoutValue. If it finds the element within the timeoutvalue then it returns a true.
I have seen some in built functions for AjaxCondition handling in Selenium 2. But I have not used it. You can refer to Selenium 2 code base

Related

Click on element if exists

I want to use setInterval and to try for five times to check if element exists (a button). If it exists, I want to click it and to proceed after it and, if not, I want to just proceed.
How to do so?
This is not the correct way with webdriver that is the underlying API in UIVeri5. The right way is to use the browser.driver.wait() with a predicate that checks for the condition.
But such polling should not be necessary at all with UIVeri5 when working against a UI5 application because UIVeri5 handles the waiting automatically. With the limitation that this magic works only in UI5 apps because it depends on the UI5 runtime to detect when the UI5 app is ready. So when writing tests for UI5, you don't need any pollings, you just write element(by.control()).isDisplayed() and it works fine and perfectly reliable. The check will happen at the correct time - when ui5 app is fully rendered and no polling is necessary.
Based on #Max, I am just writing the answer in a more dummy proof way:
If one needs to check if a button or something else is displayed, isDisplayed() should be called. isDisplayed() is a promise and, if the element is displayed, then in the then() resolution the continuation should be called. If the element is not displayed, the callback should be called in the catch() resolution of the promise.
Example:
iCheckForElementAndContinue: function(callback) {
element.isDisplayed()
.then({
// Element is found
if (callback) {
callback();
}
})
.catch({
// Element is not found
if (callback) {
callback();
}
});
}

Selenium tests fail with azure pipeline sometimes and pass locally

Test cases fail while not finding a link or any validation messages after a button click.
I used explicit waits for page to load:
var waitForDocumentReady = new WebDriverWait(WebDriver, TimeSpan.FromSeconds(10));
waitForDocumentReady.Until((wdriver) => (WebDriver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));
For wait specific div of validation messages:
WebDriverWait wait = new WebDriverWait(WebDriver, TimeSpan.FromSeconds(10));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.ClassName("validationErrors")));
But test cases pass sometimes with pipeline and fails sometimes.
I would recommend following:
When ever your tests fail take a snapshot at that moment.
sometimes when you run your tests locally the network communication
is a bit faster than running on server. Which means a spinner or a
loading control may not appear locally because results were retrieved
fast enough but the loader will appear when there is delay from
server in sending the response to client.
If you are trying to run your tests in FF headless on remote grid
setup then it is not yet stable in my experience.
Identify the pattern in failed scenarios which frequently fail and
try and run them multiple times in a loop and identify the pattern of
failure. In one of my case there was an actual bug in the performance
of the application which used to get reproduced whenever the tests
ran immediately in bulk
I was having this issue, except my test would always fail in Azure Pipelines but pass locally. Not running in "headless" mode fixed my problem. To do this, make sure "Test mix contains UI tests" is checked in your "Visual Studio Test" task.
There are a couple of things you need to take care as follows:
Test cases fail while not finding a link or any validation messages after a button click: A lot depends on the attributes of the button. In case the button contains either of the following attributes/events the DOM Tree would be getting updated and subsequently trying to find the desired element may fail:
onclick() event:
<button onclick="myFunction()">Click me</button>
jQuery click() Event:
$("p").click(function(){
alert("The paragraph was clicked.");
});
So after a button click, to find the desired element you need to induce you have to induce WebDriverWait for the ElementExists().
You can find a relevant discussion in ExpectedConditions.ElementIsVisible returns TimeoutException even when element is present
ExecuteScript("return document.readyState").Equals("complete"): This line of code is not that effective to ensure if the desired element(s) are present/visible/interactable with in the HTML DOM.
You can find a relevant discussion in Do we have any generic function to check if page has completely loaded in Selenium
However to wait for specific div with ElementExists() should have worked. The relevant HTML would have helped us to analyze what went wrong. However, if the validationErrors related element is based on HTML5 Constraint validation then you have to use the GetAttribute() method.
You can find a relevant discussion in How to handle html5 constraint validation pop-up using Selenium?

Behat / Mink / Selenium: intercepting AJAX calls possible?

I am using Behat/Mink with Selenium for acceptance testing. I need to determine if my web page is making a badly formed call to the server via Ajax. The problem is, the server will attempt to "correct" badly-formed code and return valid data nonetheless.
Is there a way to "intercept" and validate ajax calls made from my website?
Right now my FeatureContext class looks like:
public function performAnAction()
{
$this->enterInField('test', 'field');
$this->hitOKButton();
$this->assertResponseContains('success');
}
I would like to do something like:
public function performAnAction()
{
$this->enterInField('test', 'field');
$this->hitOKButton();
$ajax = $this->getAllAjaxCalls();
foreach ($ajax as $call) {
// perform some validation
}
$this->assertResponseContains('success');
}
Here are two great resources for doing checks on ajax calls
The behat mink way
http://docs.behat.org/cookbook/behat_and_mink.html#defining-our-own-featurecontext
This is a neat solution using _before and _after overrides to getting deeper inside the base functionality and is very interesting but reading through it will help you get a better understanding of what the framework is really doing under the covers
http://blog.scur.pl/2012/06/ajax-callback-support-behat-mink/
I think you could simply use the built in wait function with the js callback to get what you want in your custom step def by putting your response into a jquery data[] object on any html element and verify your expected output that way.
$this->getSession()->wait(5000,
"$('.someCssClassSelectorToElementWithResponseStuff').length > 0"
);
If your element were a js object that would work
Or if it comes back as a jquery object you could use .size() instead of length
just make sure your injected js evaluates to true of false to get your pass/fail

How to get WatiN to scan dynamically loaded content?

The situation is that I have a page that uses some AJAX calls to retrieve content from the server, then puts those results into a chunk of html generated by another script. The problem is, I can't select with watin any of the elements of this new piece of html. It can be viewed in the browser, and comes up when I hit F12 and scan through the code, but still WatiN can't see it.
Is this because WatiN only scans through the html source of the page, and not the current version of the HTML? I think a similar situation would be:
html -
<script type="text/javascript">
$('#foo').html("gak");
</script>
...
<div id="foo">bar</div>
then when I try and assert -
Assert.IsTrue(browser.Div("foo")).ContainsText("gak"));
it will return false.
Any ideas on this? or is my best option to just write a bunch of jQuery, and browser.Eval() it?
I test AJAX pages quite a bit. The key is to wait until the asnyc postback has completed. If you have
Assert.IsFalse(browser.Div("foo")).ContainsText("gak");
browser_action_that_changes_bar_to_gak
>> Here you need to wait <<
Assert.IsTrue(browser.Div("foo")).ContainsText("gak");
In the "wait" section you can do a System.Threading.Thread.Sleep(numberOfMilliseconds) <- this is not the best way, but it is really simple. Once you determine that waiting is what you need to do, a better way to wait is to poll the status rather than way numberOfMilliseconds each time. I believe different AJAX libraries do things differently, but what works for me is really similar to this: http://pushpontech.blogspot.com/2008/04/ajax-issues-with-watin.html
I put the JavaScript into an Eval() in a helper function in the my base Page class rather than having to inject it into every page like the article did.
.
my Base Page class contains:
public bool IsInAsyncPostBack()
{
const string isAsyncPostBackScript = "Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()";
return bool.Parse(this.Document.Eval(isAsyncPostBackScript));
}
And then my WaitForAsyncPostback is basically the same as in the linked post, but I added a max wait time. Before going to Page classes (awesome; do it!) I made these static functions somewhere else and it worked too.
This is almost surely a timing issue. The jQuery has not updated when you test. Rather than introducing any artificial pause or wait it's best to wait for something to show that your AJAX has worked as expected.
In this case a WaitUntil should do the job nicely:
Assert.IsTrue(browser.Div("foo")).WaitUntil(c => c.Text.Contains("gak")));
This works for most updates and the like. Another common waiting pattern is on data loading say, where you'd have a spinning wheel displayed. Then you could wait until this wheel is gone with a something like:
WaitUntil(c => c.Style.Display == "none");

How would you verify that a certain css element on a page is a certain image with selenium

I have a page that I want to check with selenium that uses a certain background image for one element. I want to ensure that this image still exists on the page connected to the element. How would I do this with selenium. If this changes anything I am using browsermob.com to do the testing once I get it running through selenium ide.
Well aside from the suggested things on the almos duplicate issue... You could check if the property of your body element is set to the image.
By if getAttribute returns a valid value or not. Like:
new Wait()
{
public boolean until()
{
return selenium.getAttribute("ElementLocator")
+ "#class").equals("active");
}
}.wait("The menu item did not get active.",
defaultTimeOutValue);
This will wait for the attribute #class to have the value "active".
Or simply use an If statement after you are sure that the page got loaded.
Hope this helps,
Cheers,
Gergely.