2

在此处输入图像描述

图片说明了一切。单击“登录”按钮后,“请填写此字段”。出现弹出消息。它看起来像一些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">

PS 当弹出消息出现时,浏览器开发工具中的“事件”指示会显示在电子邮件字段 html 附近。 在此处输入图像描述

4

3 回答 3

2

您所指的弹出窗口是约束 APIelement.setCustomValidity()方法的结果。

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

解决方案

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

  • 使用PythonMozillaCssSelector

    • 代码块:

      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.
      
  • 使用JavaChromeXpath

    • 代码块:

      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.
      
于 2019-03-19T06:54:00.420 回答
1

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

这是在 HTML5 中引入的,如果元素的 html 结构中有一个属性required="required",那么浏览器将默认显示您收到的错误消息。因此,如果您还检查您的元素,required="required"它也存在于您元素的 html 中。

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

于 2019-03-19T06:28:46.020 回答
1

没有看到 html,我不能完全自信地告诉你。

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

1)输入字段的title属性。将鼠标悬停在某物上,或者(如果设计为)将焦点放在具有标题属性的元素上会在这样的框中显示标题文本。虽然盒子肯定是程式化的。

2) 这是一个自定义 div/other 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 的方法,或者通过比我有更好答案的人,或者在编写此代码的开发人员的帮助下。话虽如此,如果您现在需要一些可以工作的东西,这应该会给您一些即时的满足感,直到找到更好的解决方案。

于 2019-03-18T14:48:54.167 回答