Using Watir on Peoplesoft App: each text field reloads the page

1k Views Asked by At

I'm using Watir 1.6.7.

I'm working on developing some regression tests for a PeopleSoft App using Watir and Cucumber. I have run into a few issues with forms in the application.

First, when entering a value into a text_field, the page refreshes when the user clicks outside the text_field. Waiting for the next text_field element to exist is problematic because it may locate the element before the page reloads, or after the page reloads as expected. Increasing the wait time never feels like a good solution, even though it "works".

The second issue is that the page refresh is not triggered until the user clicks outside the current field. In this case, that happens when the script tries to access the next text_field to be populated. One solution here would be to send a or keystroke, but I can feel the script becoming more brittle with every addition like this.

Are there any other approaches that would be less brittle, and not require 2-3 extra commands in between each text_field action?

The play-by-play looks like:

  • Browser navigates to page that contains the form.
  • Browser fills in first form field. (fix: send keystroke to cause page refresh, wait_until second field is visible again)
  • Browser selects the second form field to be filled out. (again, keystroke & wait_until)
  • Page refreshes, script fails. (resolved)
  • Browser selects the third form field...
3

There are 3 best solutions below

0
On BEST ANSWER

The application started exceeding the 5 second sleep duration, and I did not want to increase the wait time any longer. I wanted to see what would happen if I populated the text field faster using "element.value =" rather than character by character with "element.set ".

This change completely resolved all complications. The page no longer refreshes when entering text, and no long requires a send_keys statement to use TAB or ENTER to move to another field. The form is storing all of the data entered even though there are no refreshes or state saves between fields.

Previous method:

def enter_text(element, text)
    element.set text
    @browser.send_keys("+{TAB}")
    sleep 5
    Watir:Wait.until { element.exists? }
end

New method:

def enter_text(element, text)
    element.value = text
end
6
On

Firstly, there are interesting Wait methods here: How do I use Watir::Waiter::wait_until to force Chrome to wait?

Overall, I don't quite understand your problem. As I understand it your script is working. If you could be a bit clearer about your desires compared to what you already have that would help, as would some sample source code.

If you're looking for ideas on custom waiting you could check for changes in the HTML of your page, form or text field. You could check that the text field is .visible?. You could try accessing the next text_field (clicking it, or setting the value for example), then catch the exception if it can't find the text_field and retry until it doesn't break, which would solve both your problems at once.

Why would clicking outside the current field be a bad solution? Do you absolutely need the next step to be a text_field access? I haven't gotten my head around how the next field only exists when you click outside the current field, but you cause this refresh by accessing the next field.

Edit: Most welcome, and thank you for clearing that up, I think I now understand better. If you allow Watir to invoke its page wait, or force it to, then it will wait for the refresh and you can then find the new text_field. Keystrokes do not invoke ie.wait, so if you send a single keystroke, then invoke a wait then the rest of your script will be responding to the post-refresh state.

I highly recommend the OpenQA page on waiting in Watir. If what you're doing to invoke the refresh does not appear on the list of things that invoke Watir page waits then you need to invoke your own page wait... but you need to do it before the page refreshes, so the cause of the refresh should end before the end of the refresh itself.

1
On

I don't know peoplesoft's app well enough to know this, but Does the app display anything for the user while it's processing.. like some kind of little 'loading' graphic or anything that you might be able to key off of to tell when it's done?

I've seen apps that do this, and the item is just an animated gif or png and it is displayed by altering the visibility attribute of the div that contains the graphic. In that instance you can tell if the app is still loading by using the .visible? method on that element and sleeping for a while if it's still there.

for the app I'm testing (which has one of those 'icons') I created a simple method I called sleepwhileloading. all it that is does is use a one second sleep wrapped in a while loop that looks to see if the loading icon is visible. works like a charm