tags:

views:

1762

answers:

1

I am writing a Selenium test in PHP to check the performance of a web application in Firefox. I want to use this as a base-line for comparing different performance enhancements (upgrading JQuery, PHP 5.3, etc.). The web application is very AJAX intense and so far I have only run into one problem.

I have an AJAX call that loads content into an existing div. To test if the call is complete I am using the following line of code:

$selenium->waitForCondition('$(\'div[id="divId"]\').height() > 100', $timeout);

This is working as I expected, but when I attempt to type into any input loaded into the div, selenium throws the error "Element input[@id="inputId"] not found".

I have verified that the id for the input is correct and I have tried with other input elements that are loaded inside the div and none of them work. I have also attempted to add a sleep(30) so that i know for sure the elements are in the DOM and on the screen, but again it made no difference.

I am really stuck at this point and can't move on until I get this issue resolved. Any help is greatly appreciated.

Thanks, James Armes

+2  A: 

I'd look at a few things:

  1. Make sure that the condition you're checking against isn't true before the items are loaded. Checking height seems suspicious, for example -- wouldn't it be better to test if there are any children present inside the div?

  2. Depending on how you write the selector, Selenium may be thinking that input[@id='inputId'] is the actual identifier for the selector (and not just inputId). Make sure that this isn't the case. Try just using inputId, which should be sufficient since it's an identifier.

  3. Selenium can be finicky. Try different browsers to see if you get different results. If so, it may represent an area that Selenium's not covering well. Although these are generally few and far between, it's possible. But we'd need to see more code before it'd be sure that this is the case.

John Feminella
Number 2 fixed my problem here. As far as number 1 is concerned, it doesn't appear to work as I expected. I am checking height because the div already has children, more specifically a table. The AJAX call adds rows to the table (it actually replaces it with a new one with the same id). Any idea how I might better detect this? I've read about waitForElement* functions, but I don't see them available to me.
JamesArmes
JamesArmes: If the call adds rows, just store the number of rows before you make the call. Then compare the number of rows and see if it's changed, i.e. something like `$("#tableId tr").size() > [old size here]`.
John Feminella
John Feminella: I tried this, but it just seems to continue execution as if the evaluation evaluated to true right away. I even tried entering a literal value instead of a variable that I knew was more than the original table and less than the new one with no difference. Just to see what would happen I also set it to a number much higher than either table would be and it just continued execution.
JamesArmes
Can you see what happens if you try to evaluate the negation of the expression (e.g., something that should always be false)?
John Feminella
I am still getting the same results. However, I set it to just "false" and it times out as I would expect. I really don't want to resort to adding a call to sleep(), as it would somewhat defeat the purpose of my test.
JamesArmes
That's strange. How can the height be both less than 100 and more than 100?
John Feminella
Exactly, it makes no sense. I have since tried some other conditions, such as '$("#inputId").length > 0' and '$("div#divId table tbody tr td #inputId").length > 0' which should only pass once the new element is in the DOM, and at the correct location, but I still get the same results. I ran both of these selectors in firebug and they return the results I expect to see.
JamesArmes
Although not ideal and a bit of a hack, I have found that I can do the following to achieve the results I am expecting: $attr = $selenium->getAttribute('inputId@attr); while (strpos($attr, 'not found') !== false) { $attr = $selenium->getAttribute('inputId@attr'); }
JamesArmes