Могут ли методы расширения использовать нестати c поля? - PullRequest
1 голос
/ 31 января 2020

Я не уверен, нужна ли эта преамбула (полностью или вообще), но я думаю, что она передает мой сценарий использования для необходимости использования нестатического поля c внутри метода расширения stati c .

У меня есть набор тестов, реализованный с помощью Selenium / C # / NUnit.

Я использовал PageFactory для определения элементов моей страницы. PageFactory устарела, поэтому было логично перейти к определению моих элементов как IWebElements:

HomePage.cs ...

IWebElement UsernameTextBox = driver.FindElement(By.Id("username"));
IWebElement PasswordTextBox = driver.FindElement(By.Id("password"));
IWebElement LoginButton = driver.FindElement(By.Id("login"));

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

Чтобы решить эту проблему, Я изменил тип элементов на By:

HomePage.cs ...

By UsernameTextBox = By.Id("username");
By PasswordTextBox = By.Id("password");
By LoginButton = By.Id("login");

Это позволяет мне определять элементы, а затем запрашивать DOM в нужное время. Отлично, проблема решена. За исключением того, что теперь у меня есть другая проблема. Мне понравилось иметь возможность связывать методы с IWebElements для удобства чтения:

LoginButton.Click();

Но тип «By» не содержит методы, которые есть у IWebElement. Итак, следующий логический шаг: создать метод расширения.

public static class ByExtensionMethods {
    public static void Click(this By elementLocator) {
        driver.FindElement(elementLocator);
    }
}

Отлично, проблема решена. За исключением того, что теперь у меня есть другая проблема. Мой набор тестов не может использовать stati c IWebDriver, потому что я хочу выполнять свои тесты параллельно. К сожалению, подход метода расширения требует, чтобы драйвер был stati c.

Так что, если я не могу каким-то образом использовать свой не-stati c IWebDriver внутри метода расширения, похоже, что я не могу достичь своей цели методы сцепления от элементов 'By' ...

Ответы [ 3 ]

2 голосов
/ 31 января 2020

Мне также пришлось найти замену Page Factory. К счастью, C# имеет удобную функцию, называемую членами с выражением тела .

. В случае вашей домашней страницы элементы будут:

IWebElement UsernameTextBox => driver.FindElement(By.Id("username"));
IWebElement PasswordTextBox => driver.FindElement(By.Id("password"));
IWebElement LoginButton => driver.FindElement(By.Id("login"));

Selenium будет искать эти элементы во время выполнения, а не в начале, поэтому исключения не будут выброшены.

1 голос
/ 31 января 2020

Могут ли методы расширения использовать нестатические c поля?

Нет.

Так что, если я не смогу каким-либо образом использовать свои нестатические c IWebDriver внутри метода расширения. Похоже, я не могу достичь своей цели - объединить методы из элементов «By» ...

Просто передайте объект драйвера в метод расширения и используйте его.

Пример:

public static class ByExtensionMethods {
    public static void Click(this By elementLocator, IWebDriver driver) {
        driver.FindElement(elementLocator);
    }
}
0 голосов
/ 03 февраля 2020

Я также отвечаю на это, чтобы расширить уже предоставленные ответы (я упомянул методы сцепления типа «По»).

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

    public static By Click(this By elementLocator, IWebDriver driver) 
    {
        driver.FindElement(elementLocator).Click();
        return elementLocator;
    }

    public static By Click2(this By elementLocator, IWebDriver driver) 
    {
        driver.FindElement(elementLocator).Click();
        return elementLocator;
    }

Это позволяет мне делать следующее:

            HomePage homePage = new HomePage(_driver);

            homePage
            .PrivacyPolicyLink
            .Click(_driver)
            .Click2(_driver);

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

...