如何使用Selenium处理html5约束验证弹出窗口?

问题描述 投票:2回答:3

enter image description here

图片说明了一切。点击“登录”按钮后,“请填写此字段”。弹出消息出现。它看起来像一些javascript的东西。我想通过使用Selenium获取此弹出消息的文本。它甚至可能吗?这是电子邮件输入字段的html:

<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">

附:当弹出消息出现时,浏览器开发工具中的“事件”指示显示在电子邮件字段html附近。 enter image description here

html5 selenium selenium-webdriver webdriverwait constraint-validation
3个回答
2
投票

你所指的弹出窗口是Constraint API's element.setCustomValidity()方法的结果。

注意:HTML5约束验证不会消除服务器端验证的需要。尽管可以预期的无效表单请求要少得多,但仍然可以通过不兼容的浏览器(例如,没有HTML5且没有JavaScript的浏览器)或者试图欺骗您的Web应用程序的坏人发送无效的表单请求。因此,与HTML4一样,您还需要在服务器端验证输入约束,其方式与客户端的操作一致。

要检索从element.setCustomValidity()方法得到的文本,您可以使用以下任一Locator Strategies

  • 使用Python,Mozilla和CssSelector: 代码块: 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")) 控制台输出: Please fill out this field.
  • 使用Java,Chrome和Xpath: 代码块: 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")); } } 控制台输出: Please fill out this field.

1
投票

没有看到HTML,我无法充满信心地告诉你。

但是,它应该非常容易(编辑:着名的遗言)。这是两件事之一:

1)输入字段的title属性。将鼠标悬停在具有title属性的元素上,或者(如果设计为)将焦点放在具有title属性的框中。虽然盒子肯定是风格化的。

2)这是一个自定义div /其他html,它连接到涉及该输入字段的“焦点”事件的事件。

两者都需要不同的方式来获取文本。因为它们不同,我需要知道所涉及的html。请打开浏览器的开发者工具,然后检查电子邮件字段。然后,复制此元素周围的html,包括上面显示的工具提示文本。

粘贴该HTML后,答案很简单。

编辑:我绝对难过。我查看了html,搜索了事件列表和javascript文件。没有参考该工具提示中显示的文本。

此外,它呈现为基于“标题”属性的工具提示。它不是一个div。然而,标题并不仅仅存在于元素的DOM中。我不知道开发人员为这个页面做了多少魔术才能完成所有这些。我是一名网络开发人员以及一名自动化工程师,这超出了我的范畴。它可能不是我以前遇到的东西,或者我可能只是遗漏了一些东西,一旦我看到它也会让我感到愚蠢。

因此,我强烈建议您直接询问此页面的开发人员他们所做的事情,以使此标题显示为原样(不存在于html中,并且javascript中没有任何引用)。

编辑#2:这是我提到的最后一个图像识别。它使用AForge,它很容易作为dll拉入。如果使用Visual Studio,您可以将其作为nuget包获取。

using AForge.Imaging;
using System.Drawing;
using System.IO;
using OpenQA.Selenium;

public static class AssertImages
{

    //97.5% match expected. 100% is too strict, and practicly impossible. The lower the value you provide, the more possibly it is for a false match.
    //Never go below 75%. False matches above 75% are generally only possible if the baseline image is very generic, such as a basic shape or colored item.
    public const float BASE_EXPECTED_MATCH_PERCENT = 0.975f; 

    /// <summary>
    /// Determines if a provided baseline image exists within a screenshot of the current browser window .
    /// </summary>
    /// <param name="relativePathToBaseline"> Pass the relative url to the baseline image we are searching for.</param>
    /// <param name="matchExpected">Optional parameter that modifies the expected percent match. Use this when a baseline image may be stretched, different colored, or otherwise slightly modified from provided baseline.</param>
    /// <returns></returns>
    public static bool DoesScreenshotContain(string relativePathToBaseline, float matchExpected = BASE_EXPECTED_MATCH_PERCENT)
    {

        //Save screenhot as source image in jpeg format. Then, read jpeg as bitmap.
        Screenshot ss = ((ITakesScreenshot)BaseTest.Driver).GetScreenshot();
        string tempFile = Path.Combine(Path.GetTempPath(), "temp_screenshot.jpg");
        ss.SaveAsFile(tempFile, ScreenshotImageFormat.Jpeg);
        Bitmap sourceImage = new Bitmap(new MemoryStream(File.ReadAllBytes(tempFile)));
        Bitmap template = new Bitmap(Path.Combine(Reporting.BaseDirectory, "Suite", "ImageRecognition", "Baselines", relativePathToBaseline));
        //Find baseline in template image.
        ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(BASE_EXPECTED_MATCH_PERCENT);
        return tm.ProcessImage(sourceImage, template).Length > 0;

    }

}

然后,对工具提示内的文本进行拍照以用作基线。如下所述,我非常犹豫是否将此作为最终解决方案。更优越的选择是找到一种方法来使用Selenium或直接javascript,或者通过比我更好的答案的人,或者在制作此代码的开发人员的帮助下。话虽这么说,如果你现在需要的东西,这应该会给你一些即时的满足感,直到找到更好的解决方案。


1
投票

我之前也遇到过这种类型的页面,当时我与UI开发人员进行了讨论。 UI上显示的错误是本机浏览器支持,如果该字段留空,则每个浏览器默认显示此错误消息。

这是在HTML5中引入的,如果在元素的html结构中有一个属性required="required",那么浏览器将默认显示您正在获取的错误消息。因此,如果您还检查了元素,required="required"也会出现在元素的html中。

通常,网站不使用此功能,因为他们在页面上使用自定义的错误消息,但在您的情况下使用它。因此,无法使用selenium检测此错误消息,因为UI上或代码中的任何位置都不存在错误消息。因此,要么您的开发人员要求更改实现,要么您需要从测试套件中跳过这些验证。

© www.soinside.com 2019 - 2024. All rights reserved.