Рефакторинг длинного оператора в функцию многократного использования - PullRequest
1 голос
/ 29 мая 2019

В настоящее время изучая Selenium, используя C # и Visual Studio, часто приходится ждать, пока веб-элемент станет активным, прежде чем с ним можно будет взаимодействовать, и поэтому вы используете оператор ожидания, подобный следующему:

using ec = SeleniumExtras.WaitHelpers.ExpectedConditions;
            IWebElement submitPassword = wait.Until(ec.ElementToBeClickable(By.Id("submitPassword")));
            submitPassword.Click();

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

        private static IWebElement waitById(WebDriverWait wait, String ElementId)
        {
        return wait.Until(ec.ElementToBeClickable(By.Id(ElementId)));
        }

Это позволяет мне сократить вышеупомянутое до:

 IWebElement passwordField= waitById(wait, "submitPassword");
 passwordField.Click();

Метод By. может сопровождаться несколькими типами поиска, например, By.Name, By.ClassName, By.XPath и т. Д.

Я бы хотел, чтобы моя функция принимала тип поиска, чтобы я мог сделать:

IWebElement passwordField= waitById(wait,ClassName, "submitPassword");

И он выполняет поиск по ClassName вместо Id, но я не могу заставить свою функцию принять это в качестве аргумента. Когда я смотрю на определение By, мне кажется, что каждый тип имеет свою собственную подфункцию (извиняюсь, если использую неправильную терминологию), я попытался просто поставить:

        private static IWebElement waitById(WebDriverWait wait,String SearchType, String ElementId)
        {
        return wait.Until(ec.ElementToBeClickable(By.SearchType(ElementId)));
        }

Но я просто получаю сообщение о том, что By не содержит определения для SearchType, поэтому я не понимаю, как передать этот аргумент этому конкретному методу. Googling приблизил меня к этому, но я все еще немного зелен, чтобы полностью разобраться, как решить эту проблему, любая помощь приветствуется.

1 Ответ

0 голосов
/ 29 мая 2019

Вы должны передать By экземпляр вместо строки. При вашем подходе вам нужно будет написать метод для каждого из методов локатора (id, xpath, css selector, name и т. Д.), А затем еще один для каждого типа ожидания (присутствующий, видимый, кликабельный), который будет поворачиваться в много методов. С By вы можете иметь только три метода, по одному для каждого типа ожидания. Вот что я бы использовал ...

public IWebElement WaitForPresence(By locator)
{
    return new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementExists(locator));
}

public IWebElement WaitForVisible(By locator)
{
    return new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(locator));
}

public IWebElement WaitForClickable(By locator)
{
    return new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementToBeClickable(locator));
}

Я удалил ключевое слово static, потому что его следует избегать, если вы планируете запускать автоматизацию параллельно. Если вы не будете осторожны, вы можете столкнуться с неприятностями, и у вас могут возникнуть проблемы.

Я бы не стал передавать экземпляр WebDriverWait, потому что он связан с конкретным экземпляром драйвера и вызовет проблемы, если вы планируете работать параллельно.

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