Search code examples
htmlseleniumselenium-webdriverwebdriverwaitconstraint-validation-api

How to handle HTML constraint validation pop-up using Selenium?


Screenshot of a form with a "Please fill out this field" dialog validation message appearing below the 'Email or Username' field

After click on the "LOG IN" button, a "Please fill out this field." pop-up message appears.

I want to get the text of this pop-up message by using Selenium. Is it even possible?

Here is the HTML of the email input field:

<input autocorrect="none" autocapitalize="none" spellcheck="false" autofocus="autofocus" class="cell small-21 form-text required" data-drupal-selector="edit-name" aria-describedby="edit-name--description" type="text" id="edit-name" name="name" value="" size="60" maxlength="60" required="required" aria-required="true" placeholder="Email or Username">

When the pop-up message appears, an "event" indication in the browser DevTools inspector is shown near the email field HTML:

screenshot of HTML inspector view with the 'event' badge appended to the end


Solution

  • The popup which you are referring is the outcome of Constraint API's element.setCustomValidity() method.

    Note: HTML5 Constraint validation doesn't remove the need for validation on the server side. Even though far fewer invalid form requests are to be expected, invalid ones can still be sent by non-compliant browsers (for instance, browsers without HTML5 and without JavaScript) or by bad guys trying to trick your web application. Therefore, like with HTML4, you need to also validate input constraints on the server side, in a way that is consistent with what is done on the client side.

    Solution

    To retrieve the text which results out from the element.setCustomValidity() method, you can use either of the following Locator Strategies:

    • Using Python, Mozilla and CssSelector:

      • Code Block:

        from selenium import webdriver
        from selenium.webdriver.support.ui import WebDriverWait
        from selenium.webdriver.support import expected_conditions as EC
        from selenium.webdriver.common.by import By
        
        driver = webdriver.Firefox(executable_path=r'C:\Utility\BrowserDrivers\geckodriver.exe')
        driver.get("https://accounts.us1.advisor.ws/user/login")
        email_username = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.cell.small-21.form-text.required#edit-name[name='name']")))
        print(email_username.get_attribute("validationMessage"))
        
      • Console Output:

        Please fill out this field.
        
    • Using Java, Chrome and Xpath:

      • Code Block:

        import org.openqa.selenium.By;
        import org.openqa.selenium.WebDriver;
        import org.openqa.selenium.WebElement;
        import org.openqa.selenium.chrome.ChromeDriver;
        import org.openqa.selenium.chrome.ChromeOptions;
        import org.openqa.selenium.support.ui.ExpectedConditions;
        import org.openqa.selenium.support.ui.WebDriverWait;
        
        public class validationmessage {
        
            public static void main(String[] args) {
        
                System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
                ChromeOptions options = new ChromeOptions();
                options.addArguments("start-maximized");
                options.addArguments("disable-infobars");
                options.addArguments("--disable-extensions"); 
                WebDriver driver =  new ChromeDriver(options);
                driver.get("https://accounts.us1.advisor.ws/user/login");
                WebElement email_username = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[@class='cell small-21 form-text required' and @id='edit-name'][@name='name']")));
                System.out.println(email_username.getAttribute("validationMessage"));
            }
        }
        
      • Console Output:

        Please fill out this field.