Handling a javascript popup occurring on a keyup event
Asked Answered
T

2

7

I have a text-field on a HTML page which checks whether you have entered a value between 1 to 365. If the user enters an invalid value like a non-numeric character or a value which does not fall inside the range, it shows a popup. I saw on the watir wiki that there is a select_no_wait method which is used to dismiss popups when you select an invalid value from the list.

What is a good way to handle a popup occurring on a keyup event? Do i need to proceed along the lines the way select_no_wait method is implemented or can we launch a different process which will dismiss the popups which might occur when the set method is called.

A sample example of the HTML file with a validate function in Javascript would be:

<html>
<head>
<script type="text/javascript">
var num = 0
function validate(e)
{
 var charPressed = String.fromCharCode(e.keyCode);
if(charPressed >= '0' && charPressed<= '9')
{
  num = parseInt(document.getElementById('foo').value);
   if ((document.getElementById('foo').value).length <= 3 && (num > 365 || num==0))
    alert ("Values can only be from to 1 to 365");
    }
  else
  {
  alert("Invalid character entered");
  document.getElementById('foo').value = "";
  }
}
</script>
</head>
<body>
<label id="code"> Sample </label>
<input type="text" id ="foo" onkeyup="validate(event)" maxLength="3"/>
</body>
</html>

I would really appreciate any pointers on this issue. Thanks in advance.

Theatrical answered 17/11, 2011 at 8:22 Comment(7)
Just off the top of my head, I'll bet that validation fails to alert if the user enters a 4 (or more) digit number where first three digits are less than 366. e.g. if you enter 1111 or 2222 or 3651Ingot
Chuck the text-field only accepts 3 characters, that's why I've used the maxLength = 3 attributeTheatrical
so if you believe the value will never be more than three digits, why have that check for the length <=3 anded with your other terms? It's not serving any function, and if someone later makes the field longer, it will just serve to cause the check to NOT activate on a subset of 'too big' numbers. It's a bug waiting to happen.Ingot
The security tester in me also wants to ask "you do have server side validation also right? Because from a security perspective, client side validation is just to make life easier for your customer, you should never trust it to protect you against an attacker who would just bypass it in a few heartbeats."Ingot
Chuck, yes we have server side validation. I was just trying to come up with a small example. The length<=3 check is redundant. If a guy types 000, he'll have to dismiss 2 popups which is highly inefficient. Thanks for the tips btw.Theatrical
I think you are missing my point with regard to the length<=3 check being anded with your other terms. Currently, as long as the browser works correctly, you'd never ever have more than 3 characters in that input field, so that check is always true. However, if someone later changes the HTML and raises that field length, then if someone types 2000, then that check goes to failing. since it is anded with the check for (n<1||n>365) the IF statement is not executed, and despite the fact that 2000 is more than 365, the alert never fires. What you want is length>3||n<0||n>365.Ingot
by the way (sorry, the tester in me can't help it) test that logic with cut and paste. (both via ctrl-v or right mouse context menu) does it allow someone to paste in a valid value? and will it warn if they try to paste in something like "-25"Ingot
I
9

For Watir:

There are some actions that currently wait for a pageload, such as .click, .select, because after such actions the page is often updated via a postback or form post. The _no_wait variant exists for those , as a way to tell the script to proceed without waiting for the page load to occur when a popup will be occurring.

Currently .set has no wait for page load logic (as far as I know anyway) and thus no _no_wait variant of the method. So you can probably just proceed straight from setting the value, to looking for the popup.

Note that if you don't see the popup after using .set, you may need to fire the 'onkeyup' event to trigger your client side scripting. Also be sure it's really a JS popup, there's lots of other ways of doing stuff that looks like the JS popups, but are really just things like divs etc.

Since this is a Javascript Popup, you should be able to get rid of it via code similar to the examples in the Watir Wiki

browser.javascript_dialog.button('OK').click


For Watir-Webdriver:

If you are using Watir-Webdriver then things are a bit different. I'm going into a bit more detail here because this info is not as easily available (yet)

Webdriver has an Alerts API, and Watir-Webdriver has an alerts helper which makes use of that, with a few different methods in it to deal with various styles of javascript popups. The methods are described in the RDoc for watir-webdriver look for 'alerthelper' under the main watir class. These are the examples given there.

require "watir-webdriver/extensions/alerts"   #add to require section at top of script)

browser.alert do
  browser.button(:value => "Alert").click
end #=> "the alert message"

browser.confirm(true) do
  browser.button(:value => "Confirm").click
end #=> "the confirm message"

browser.prompt("hello") do
  browser.button(:value => "Prompt").click
end #=> { :message => "foo", :default_value => "bar" }

Note that these examples are taken pretty much straight from the rspec tests for the alerthelper code. As such they may not make perfect sense to you without knowing this particular little detail. The click method inside the loop is the action that makes the alert appear. The test webpage has three buttons, with values Alert, Confirm, Prompt, which cause the popups to appear as the tests run against that page.

To use this stuff in your code, replace that middle line with whatever action in your script is causing the popup. For example in one of my scripts I click a button to delete the user's credit card, and there is a confirm dialog that pops up. So my code ends up looking like this (note this code is designed to work for both watir and watir-webdriver, $webdriver gets set to true or false depending on which is being used.

if $webdriver #watir-webdriver
  $browser.confirm(true) do
    $browser.div(:id => 'credit_cards').link(:text =>'Delete').click
  end 
else #watir
  $browser.div(:id => 'credit_cards').link(:text =>'Delete').click_no_wait
  $browser.javascript_dialog.button('OK').click
end

BTW the comment after 'end' in each of those examples? That's what you get back if you assign the output from the loop to a variable

confirm_message = browser.confirm(true) do
  browser.link(:text => "Add Lasers").click
end 

puts confirm_message
> "do you really want to put lasers on sharks?"
Ingot answered 17/11, 2011 at 19:12 Comment(8)
Chuck the behavior I observed say for an invalid string was. If i use the set method to type in "abc", it'll type in a, the popup is fired [I dismiss it manually], b is typed in, the pop up is fired and manually dismissed and it continues. Thus, its kind of a stop and go interaction which is taking place.Theatrical
well that is what you'd expect. I'm not sure I'd have test cases that tried to enter more than a single invalid character before looking to verify that the popup is there. unless you want to do it a character at a timeIngot
well, a popup is being produced. I need a way to dismiss it. But essentially, if we have more than 1 invalid characters, the call to set is a blocking one. Thus, I was wondering as to how to dismiss the popup. I was thinking on the lines of launching a popup dismisser script in a different process before calling the set method. Would it be right to think along those lines?Theatrical
Added stuff on watir-webdriver's alerthelper class to my answerIngot
Cool, I will take a look into it and I will definitely post a better Javascript code for validating. Also, I cannot use the first method since I am not allowed to change the javascript code. I am designing for a requirement which states that any invalid char entered into the text-field will produce a popup with the error message xx,xxxTheatrical
Thank you. Your explanation that the command inside the confirm, alert, prompt block should be the command that spawns the JS popup helped me greatly.Peddle
Yeah I banged my head against the wall on that one for a while trying to get it to work, then decided "ok time to go look at the tests" once I saw what the tests were doing it suddenly all made sense. Validation that tests as documentation works, but also that you should not not copy test code verbatim and present it (sans context) as an example of how to do something. In the context of the tests, where you can see the page being tested, the inner command makes sense, abscent of that, it's too easy to interpret as static code that would not change.Ingot
FYI, the mentioned watir-webdriver example is using deprecated API. Instead, watirwebdriver.com/javascript-dialogs should be used.Feldman
L
0

I've found that wrapping the browser.javascript_dialog.button('OK').click command within a sleep(3) do, helps speedy browsers finish the command.

Levileviable answered 1/10, 2013 at 21:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.