C#+NUnit + Selenium Grid - параллельный запуск на одном ноде нескольких браузеров

Использую:
C#+WebDriver+NUnit+Grid
Реализация с использованием Page Object+Page Factory
WebDriver 3.4.0
Nunit 3.5.0
Google Chrome Driver 2.36
Mozilla GeckoDriver 0.20.0
Обновления браузеров Chrome и FF последние

Пытаюсь научиться реализовывать параллельные запуски тестов. Сейчас задача следующая, одновременно запустить на ноде один TestFixture в двух разных браузерах. Нашел одну реализацию и после запуска на ноде одновременно запускаются 2 браузера, но в FF тест полностью проходит, а в chrome выполняется только Navigate().GoToUrl(baseUrl) (даже Manage().Window.Maximize() не выполняется), потом выдает ошибку:

Имя теста: LoginOnMailru
Полное имя теста: SendingMailTestForLQ.Tests.LoginTests(“chrome”).LoginOnMailru
Результат Сообщение: OpenQA.Selenium.NoSuchElementException : Could not find element by: By.Id: mailbox:submit

Не могу понять почему не находит данный элемент. Если запустить тест в одном браузере chrome, то тест проходит.

Запускаемый тест простой, нужно залогиниться на мыле.

[TestFixture("chrome")]
[TestFixture("firefox")]
[Parallelizable(ParallelScope.Fixtures)]
public class LoginTests : BaseObject
{
    public LoginTests(string browser)
    {
        DesiredCapabilities capability = new DesiredCapabilities();
        capability.SetCapability("browserName", browser);
        driver = new RemoteWebDriver(new Uri("http://192.168.1.63:5555/wd/hub"), capability);
        driver.Navigate().GoToUrl(baseUrl);
        driver.Manage().Window.Maximize();
    }
    private static LoginPageHelper LoginPageHelper = new LoginPageHelper();

    [Test]
    public static void LoginOnMailru()
    {
        string email = "test.account.damir@mail.ru";
        string password = "q123123a";

        LoginPageHelper.
            DoLogin(email, password);
    }
}

Буду премного благодарен если кто наведет на путь истинный.

НИКОГДА не используйте слово static, если планируете запускать что-либо паралельно))
Уберите static, создавайте объект, перед использованием его методов и все должно заработать

4 лайка

Большое спасибо, помогло! Не могли бы вы еще подсказать. Так как WebDriver 3.11 не поддерживает больше DesiredCapabilities приходится использовать ToCapabilities. Мне удалось реализовать параллельный запуск используя данный подход, но код получается громоздким вроде этого:

[Parallelizable(ParallelScope.Fixtures)]
public class TestChrome
    {
        public IWebDriver driver;
public TestChrome()
        {
            ChromeOptions options = new ChromeOptions();
            driver = new RemoteWebDriver(new Uri("http://192.168.1.30:5555/wd/hub"), options.ToCapabilities());
            driver.Navigate().GoToUrl("https://mail.ru/");
            driver.Manage().Window.Maximize();
        }
        [Test]
        public void Test1()
        { 
          //test
        }
    }
[Parallelizable(ParallelScope.Fixtures)]
 public class TestFF
    {
        public IWebDriver driver;
        public TestFF()
        {
            FirefoxOptions options = new FirefoxOptions();
            driver = new RemoteWebDriver(new Uri("http://192.168.1.30:5555/wd/hub"), options.ToCapabilities());
            driver.Navigate().GoToUrl("https://mail.ru/");
            driver.Manage().Window.Maximize();
        }
        [Test]
        public void Test3()
        {
           //test
      [/details]  }
    }

Как можно реализовать, используя 1 конструктор с входящими параметрами браузеров, а не создавать отдельный класс с конструктором (т.е. реализовать как моем первом коде), учитывая, что уже используется реализация через экземпляр класса конкретного браузера(в коде выше), а не экземпляра класса OpenQA.Selenium.Remote.DesiredCapabilities ?

я бы не рекомендовал этого делать, потому что каждый браузер использует свои опции
“192.168.1.30:5555” - это в app.config

            ChromeOptions options = new ChromeOptions();
            driver = new RemoteWebDriver(new Uri("http://192.168.1.30:5555/wd/hub"), options.ToCapabilities());
            driver.Manage().Window.Maximize();

это в отдельный файл, например Browser и в результате код должен выглядеть как-то так:
Browser browser = new Browser(type);

driver.Navigate().GoToUrl(“https://mail.ru/”) - это к логике инициализации браузера никакого отношения не имеет

1 лайк

Спасибо, это я понял:

“192.168.1.30:5555” - это в app.config
driver.Navigate().GoToUrl(“https://mail.ru/”) - это к логике инициализации браузера никакого отношения не имеет

А здесь не затруднит по подробней описать?

это в отдельный файл, например Browser и в результате код должен выглядеть как-то так:
Browser browser = new Browser(type);

Если вы находитесь в самом начале пути, я рекомендую вникнуть в цикл из этих статей:

Это обертка над селениумом. Очень грамотно описано построение тестового фреймворка с нуля. Там тоже есть класс static, но я от него сразу избавился. Использую больше двух лет. По необходимости дописываю необходимый функционал. Всякие wait-ы не использую(в этой обертке другой подход), тем кто пытается дописывать Thread.Sleep(), сразу бью по рукам))
Сверху использую не NUnit, а Specflow.

1 лайк

Ок, спасибо!