Как обработать всплывающее окно проверки ограничений html5 с помощью Selenium? - PullRequest
2 голосов
/ 18 марта 2019

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

P.S. Когда появляется всплывающее сообщение, рядом с полем электронной почты html отображается индикация «события» в инструментах разработчика браузера enter image description here

Ответы [ 3 ]

2 голосов
/ 19 марта 2019

Всплывающее окно , на которое вы ссылаетесь, является результатом использования метода Constraint API element.setCustomValidity () .

Примечание : проверка ограничений HTML5 не устраняет необходимость проверки на стороне сервера. Несмотря на то, что следует ожидать гораздо меньше недопустимых запросов форм, они могут отправлять некорректные браузеры (например, браузеры без HTML5 и JavaScript) или плохие парни, пытающиеся обмануть ваше веб-приложение. Поэтому, как и в HTML4, вам также необходимо проверить входные ограничения на стороне сервера таким образом, чтобы это соответствовало тому, что делается на стороне клиента.

Решение

Чтобы извлечь текст, полученный в результате использования метода element.setCustomValidity(), вы можете использовать одну из следующих Стратегий локаторов :

  • Использование 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 голос
/ 19 марта 2019

Я также встречался с этим типом страницы ранее, и у меня была дискуссия с разработчиками пользовательского интерфейса в то время.Ошибки, отображаемые в пользовательском интерфейсе, - это встроенная поддержка браузера, и каждый браузер по умолчанию отображает это сообщение об ошибке, если поле оставлено пустым.

Это было введено в HTML5, и если в структуре html элемента есть атрибут required="required", браузер по умолчанию покажет сообщение об ошибке, которое вы получаете.Так что, если вы также проверите свой элемент, required="required" также присутствует в html вашего элемента.

Как правило, веб-сайты не используют эту функцию, потому что они используют свои настраиваемые сообщения об ошибках на странице, но в вашем случае она используется.Следовательно, невозможно обнаружить это сообщение об ошибке, используя селен, поскольку сообщение об ошибке отсутствует в пользовательском интерфейсе или где-либо в коде.Поэтому вы либо просите своих разработчиков изменить реализацию, либо вам нужно пропустить эти проверки из вашего набора тестов.

1 голос
/ 18 марта 2019

Не видя HTML, я не могу сказать вам с полной уверенностью.

Однако, это должно быть чрезвычайно легко (редактировать: известные последние слова).Это одна из двух вещей:

1) Атрибут title поля ввода.Если навести указатель мыши на что-либо или (если оно предназначено для этого) навести фокус на элемент с атрибутом заголовка, этот текст заголовка отображается в поле, подобном этому.Хотя коробка, безусловно, была стилизована.

2) Это пользовательский HTML-код div / other, который подключается к событию, которое включает в себя событие «focus» этого поля ввода.

ОбаТребуются разные способы получения текста.Поскольку они разные, мне нужно знать html.Пожалуйста, откройте Инструменты разработчика вашего браузера и проверьте поле электронной почты.Затем скопируйте html вокруг этого элемента, включая все, что содержит текст всплывающей подсказки, показанный выше.

Как только вы вставите этот html, ответ будет простым.

Редактировать: Я абсолютно в тупике.Я просмотрел html, просмотрел список событий и файлы javascript.Там нет ссылки на текст, показанный в этой подсказке.

Кроме того, он отображается как всплывающая подсказка на основе атрибутов «title».Это не div.Тем не менее, название не просто существует в DOM для элемента.Я не знаю, какое волшебство разработчики сделали для этой страницы, чтобы все это произошло.Я веб-разработчик, а также инженер по автоматизации, и это вне меня.Возможно, это не то, с чем я сталкивался раньше, или я просто упускаю что-то, что заставляет меня чувствовать себя глупо, когда я это тоже вижу.

В связи с этим я настоятельно рекомендую вам спросить разработчиковпрямо на этой странице то, что они сделали, чтобы этот заголовок выглядел так, как он есть (без существующего в html и без ссылок в javascript где-либо).

Edit # 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, либо с помощью кого-то с лучшим ответом, чем у меня, либо с помощью разработчиков, которые создали этот код.При этом, если вам нужно что-то, что работает прямо сейчас, это должно дать вам некоторое мгновенное удовлетворение, пока не будет найдено лучшее решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...