views:

359

answers:

2

One script we have asks the user for a few values via successive JavaScript calls to window.prompt(). Selenium records this action, both the prompt texts and the values I typed in, but it doesn't seem to be able to play it back properly. It 'succeeds' in that no errors occur, but only the first prompt value actually makes it back to my script. Furthermore, the default ordering Selenium records makes the second value get returned in the first one's spot, and the rest still blank:

# [info] Executing: |answerOnNextPrompt | TEXT1 | |
# [info] Executing: |select | id | label=mychoice |
# [info] Executing: |answerOnNextPrompt | TEXT2 | |
# [info] Executing: |assertPrompt | Please enter a value for q1 | |
# [info] Executing: |answerOnNextPrompt | TEXT3 | |
# [info] Executing: |assertPrompt | Please enter a value for q2 | |
# [info] Executing: |answerOnNextPrompt | TEXT4 | |
# [info] Executing: |assertPrompt | Please enter a value for q3 | |
# [info] Executing: |assertPrompt | Please enter a value for q4 | |

I reordered it into what seems more sensible to me:

# [info] Executing: |answerOnNextPrompt | TEXT1 | |
# [info] Executing: |select | id | label=mychoice |
# [info] Executing: |assertPrompt | Please enter a value for q1 | |
# [info] Executing: |answerOnNextPrompt | TEXT2 | |
# [info] Executing: |assertPrompt | Please enter a value for q2 | |
# [info] Executing: |answerOnNextPrompt | TEXT3 | |
# [info] Executing: |assertPrompt | Please enter a value for q3 | |
# [info] Executing: |answerOnNextPrompt | TEXT4 | |
# [info] Executing: |assertPrompt | Please enter a value for q4 | |

After that I get TEXT1 as the first value, but the rest still blank.

I also tried waitForPrompt in place of each assertPrompt, but no dice.

My guess is that Selenium can't actually handle this situation because answerOnNextPrompt seems to need to come before the action that triggers the prompt, but it is the action that triggers the next prompt, so after the first one triggered by select there's no way to do it because they don't stack.

I'd like to be proven wrong, though...any ideas?

(If not, I might report it as a bug / something they need to change in the API, maybe by combining answerOnNextPrompt with assertPrompt: it could just take an optional argument with how the prompt ought to be answered.)

Platform is Selenium IDE 1.0.2 on Firefox 3.5.3 on win32.

A: 

How about this one:

# [info] Executing: |select | id | label=mychoice |
# [info] Executing: |answerOnNextPrompt | TEXT1 | |
# [info] Executing: |assertPrompt | Please enter a value for q1 | |
# [info] Executing: |answerOnNextPrompt | TEXT2 | |
# [info] Executing: |assertPrompt | Please enter a value for q2 | |
# [info] Executing: |answerOnNextPrompt | TEXT3 | |
# [info] Executing: |assertPrompt | Please enter a value for q3 | |
# [info] Executing: |answerOnNextPrompt | TEXT4 | |
# [info] Executing: |assertPrompt | Please enter a value for q4 | |

BTW, why not using a regular HTML form instead so many of those annoying javascript prompts?

Santi
I just tried that, it just puts TEXT1 in the first value and blanks the rest still.We're emulating a UI that everyone is already used to in this context. It will change some day, don't worry. :P
Kev
+3  A: 

This definately looks like a limitation in Selenium. The following is from the source of selenium-browserbot.js:

windowToModify.prompt = function(message) {
    browserBot.recordedPrompts.push(message);
    var result = !browserBot.nextConfirmResult ? null : browserBot.nextPromptResult;
    browserBot.nextConfirmResult = true;
    browserBot.nextPromptResult = '';
    self.relayBotToRC.call(self, "browserbot.recordedPrompts");
    return result;
};

It appears to process all prompts when the window is 'modified', and after each it sets the next answer to empty. I would raise a request for an improvement. Without giving it much thought I would suggest allowing stacking of the anwerOnNextPrompt command so that you can queue up the answers you want to give to each prompt in turn.

Update:

Something similar will also happen for consecutive JavaScript confirmations. The first will use the response set by choose*OnNextConfirmation, and all following confirmations will automatically select OK (true).

windowToModify.confirm = function(message) {
    browserBot.recordedConfirmations.push(message);
    var result = browserBot.nextConfirmResult;
    browserBot.nextConfirmResult = true;
    self.relayBotToRC.call(self, "browserbot.recordedConfirmations");
    return result;
};
Dave Hunt