Check if "Please enter an email address" message appears
Asked Answered
C

3

8

Given a simple page:

<form>
  <input type="email">
  <button>click</button>
</form>

If I enter anything in text field that is not e-mail and click the button, Please enter an email address message appears.

Is there a way to to check if the message appears using Selenium or Watir? As far as I see, nothing new appears in browser DOM.

Since the page is using e-mail check that is built in feature of a browser, does it even make sense to check that error message appears? It is at the same level as checking if browser scroll bar works. We are no longer checking the web application, but the platform (browser).

An earlier related question here on SO is: How do I test error conditions in HTML5 pages with cucumber?

Christchurch answered 26/3, 2013 at 12:8 Comment(11)
Does the warning appear on the page? My first guess would be get its ID via firebug and then use it later onNunci
The warning appears on the page - you see it in browser window, but it does not appear on the page - nothing new appears in DOM. Magic. :)Robertoroberts
I actually think it doesn't make sense because that means testing 3rd party, not web app.Washery
well, does it mean that the warning was always there buit its made invisible by the page? If not then I agree with @Washery - it dioes not make sense to me also to test 3rd party appNunci
@PavelJanicek it's not related to page at all, it's popup added by browserWashery
Typically warnings like these are either alerts, or divs that get placed on top of the existing page. If nothing new appears on the DOM, check for existing items that have a different text value or have just become visible.Shimmy
@Farlan: it is not a div or any kind of standard alert, try it yourself, I have provided HMTL that reproduces the problemRobertoroberts
What browser are you using?Shimmy
@Farlan: I have tried it with the latest Chrome and Firefox.Robertoroberts
Guys this is different. It's not a javascript client side validation thing, it's a new HTML5 feature where the browser does validation based on the input 'type' and if the field has the new 'required' attribute defined. So the actual presentation to the user is highly subjective, and can be reinforced via CSS stuff if the developer codes that in (I think using psuedoclasses?) See the-art-of-web.com/html/html5-form-validation/#.UVIWfFtATu0 for more infoTwana
FYI I created a new feature request as a result of discussion here github.com/watir/watir-webdriver/issues/189Twana
T
4

I'd agree that this is starting to get close to 'testing the browser', otoh if your code depends on that browser feature, then the site needs to produce the proper html(5) code so that the browser knows you want that level of validation, and that is something you can validate.

Some good background on this at art of the web

The browser side validation is triggered by the combination of the specific input type (which you could check via watir's .type method) and the new required attribute (which might be tricker to check) Given this I think I actually see a pretty good cause here for a new feature in Watir. I'm thinking we could use a .required? method which should be supported for all input elements which support the new 'required' attribute, and would return true if that 'required' attribute is present.

So at the moment what you could do is if you know you are running on an HTML5 browser that supports this feature, you could both check that the input type is 'email' and also that the 'required' attribute is there. (I don't offhand have an idea for how to do that, but perhaps someone else can suggest a way).

The other thing to be sure of would be to provide an invalid value, and make sure that the form will not allow itself to be submitted. e.g. is the validation enforced, or merely advisory. (and don't forget to check the server side by submitting invalid data anyway using something like curl or httparty, since a hostile user could easily bypass any inbrowser validation and submit that form with bogus or even 'hostile' values designed to cause a buffer overflow or injection attack. No site should depend exclusively on client side validation.)

The other thing to consider of course is what if the user is on a browser that does NOT support that particular validation feature, what does the page do then? I'd presume some kind of client side javascript and a message that is displayed.

In that case it really depends on the way in which the message is made to 'appear'. In the app I am testing, messages of that sort happen to be in a handy divs with unique classes which are controlled by css to normally be hidden, and then set to displayed when the client side JS detects the need to display a message for the user. So of course I have tests for stuff like that. Here's an example of one for someone agreeing to our terms and conditions. (Note: we use Cucumber, and the Test-Factory gem to do page objects and data objects)

Lets start with the message, and what right-click.examine-element reveals

The message as it appears on our registration page

The scenario on the grower_selfregister.feature file looks like this

Scenario: self registering grower is required to agree to terms and conditions
  Given I am a unregistered grower visiting www.climate.com
  When I try to self-register without agreeing to the terms and conditions
  Then I am informed that Acceptance of the terms and conditions is required
  And I remain on the register page

The critical Cucumber steps are:

When /^I try to self-register without agreeing to the terms and conditions$/ do
  @my_user.self_register(:agree_to_terms => FALSE)
end

Then /^I am informed that Acceptance of the terms and conditions is required$/ do
  on Register do |page|
    page.agree_to_terms_required_message.should be_visible
  end
end

Then /^I remain on the register page$/ do
  on Register do |page|
    #ToDo change this to checking the page title (or have the page object do it) once we get titles
    page.url.should == "#{$test_site}/preso/register.html"
  end
end

The relevant portions of the register.rb page object are

class Register < BasePage

  #bunch of other element definitions removed for brevity

  element(:agree_to_terms_required_message) {|b|b.div(:class => "terms-error")}

end

Does that help provide an example?

Note: it could easily be argued that the second validation (staying on the page) is redundant since I'm unlikely to see the message if I'm not still on the page. But it adds clarity to the expected user experience described in the scenario Also, it could be very important if the implemntation where to change, for example if it was decided to use something like an javascript alert, then it may well be important to validate that once dismissed (something the "I see the message" step would likely do) the user did not proceed into the site anyway.

Twana answered 26/3, 2013 at 21:24 Comment(0)
E
5

You could try like this

JavascriptExecutor js = (JavascriptExecutor) driver;
driver.findElement(By.cssSelector("input[type='email']")).sendKeys("asd");
Object s=js.executeScript("return document.getElementById(\"a\").validity.valid");
System.out.println(s);
driver.findElement(By.cssSelector("input[type='email']")).sendKeys("[email protected]");
s=js.executeScript("return document.getElementById(\"a\").validity.valid");
System.out.println(s);

Output for above line is

false
true

So based on that you can conclude that whether the given value is valid or not.

Below javascript logic will return true/false based on the validity of the field

document.getElementById(\"a\").validity.valid

P.s : I assume input tag has id "a"

Erst answered 26/3, 2013 at 16:35 Comment(0)
T
4

I'd agree that this is starting to get close to 'testing the browser', otoh if your code depends on that browser feature, then the site needs to produce the proper html(5) code so that the browser knows you want that level of validation, and that is something you can validate.

Some good background on this at art of the web

The browser side validation is triggered by the combination of the specific input type (which you could check via watir's .type method) and the new required attribute (which might be tricker to check) Given this I think I actually see a pretty good cause here for a new feature in Watir. I'm thinking we could use a .required? method which should be supported for all input elements which support the new 'required' attribute, and would return true if that 'required' attribute is present.

So at the moment what you could do is if you know you are running on an HTML5 browser that supports this feature, you could both check that the input type is 'email' and also that the 'required' attribute is there. (I don't offhand have an idea for how to do that, but perhaps someone else can suggest a way).

The other thing to be sure of would be to provide an invalid value, and make sure that the form will not allow itself to be submitted. e.g. is the validation enforced, or merely advisory. (and don't forget to check the server side by submitting invalid data anyway using something like curl or httparty, since a hostile user could easily bypass any inbrowser validation and submit that form with bogus or even 'hostile' values designed to cause a buffer overflow or injection attack. No site should depend exclusively on client side validation.)

The other thing to consider of course is what if the user is on a browser that does NOT support that particular validation feature, what does the page do then? I'd presume some kind of client side javascript and a message that is displayed.

In that case it really depends on the way in which the message is made to 'appear'. In the app I am testing, messages of that sort happen to be in a handy divs with unique classes which are controlled by css to normally be hidden, and then set to displayed when the client side JS detects the need to display a message for the user. So of course I have tests for stuff like that. Here's an example of one for someone agreeing to our terms and conditions. (Note: we use Cucumber, and the Test-Factory gem to do page objects and data objects)

Lets start with the message, and what right-click.examine-element reveals

The message as it appears on our registration page

The scenario on the grower_selfregister.feature file looks like this

Scenario: self registering grower is required to agree to terms and conditions
  Given I am a unregistered grower visiting www.climate.com
  When I try to self-register without agreeing to the terms and conditions
  Then I am informed that Acceptance of the terms and conditions is required
  And I remain on the register page

The critical Cucumber steps are:

When /^I try to self-register without agreeing to the terms and conditions$/ do
  @my_user.self_register(:agree_to_terms => FALSE)
end

Then /^I am informed that Acceptance of the terms and conditions is required$/ do
  on Register do |page|
    page.agree_to_terms_required_message.should be_visible
  end
end

Then /^I remain on the register page$/ do
  on Register do |page|
    #ToDo change this to checking the page title (or have the page object do it) once we get titles
    page.url.should == "#{$test_site}/preso/register.html"
  end
end

The relevant portions of the register.rb page object are

class Register < BasePage

  #bunch of other element definitions removed for brevity

  element(:agree_to_terms_required_message) {|b|b.div(:class => "terms-error")}

end

Does that help provide an example?

Note: it could easily be argued that the second validation (staying on the page) is redundant since I'm unlikely to see the message if I'm not still on the page. But it adds clarity to the expected user experience described in the scenario Also, it could be very important if the implemntation where to change, for example if it was decided to use something like an javascript alert, then it may well be important to validate that once dismissed (something the "I see the message" step would likely do) the user did not proceed into the site anyway.

Twana answered 26/3, 2013 at 21:24 Comment(0)
D
2

I haven't found a way to check for the actual error message. However, you can check that the input field is invalid after entering a non-email, using the :invalid CSS pseudo-selector.

WebElement invalidInput = driver.findElement(By.cssSelector("input:invalid"));
assertThat(invalidInput.isDisplayed(), is(true));
Dinodinoflagellate answered 9/4, 2015 at 20:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.