Перейти к содержимому

Фотография

C# - NUnit - WebDriver. Внедрение Page Object. Типовой пример

C# NUnit WebDriver Page Object

  • Авторизуйтесь для ответа в теме
Сообщений в теме: 21

#21 Ivis

Ivis

    Новый участник

  • Members
  • Pip
  • 53 сообщений
  • Город:Одесса


Отправлено 23 августа 2017 - 09:04

 

 

А зачем везде передавать ApplicationManager, если он реализует Singleton?

 

 

Эмм... не совсем понял.
Непосредственно ApplicationManager я передаю в PageManager, а для страниц я уже использую PageManager с драйвером от ApplicationManager. По крайней мере такая была задумка...

Можете привести конкретный пример кода, или что необходимо исправить, если где-то у меня есть "излишек"?
 

 

Не передавайте ApplicationManager как параметр нигде. Вы всегда можете получить к нему доступ через ApplicationManager.GetInstance(). Потому нет смысла его везде передавать почем зря. Иначе у вас получается масло маслянное, PageManager имеет поле ApplicationManager, а ApplicationManager имеет поле PageManager. Зачем PageManager-у это поле.

 

 

PageManager использует драйвер от ApplicationManager (для инициализации фабрики).

 

И, например, в классе AnyPage.cs, я также использую драйвер в методах проверки наличия элемента на странице и ожидания появления элемента.

    public class AnyPage
    {
        private PageManager pageManager;


        public AnyPage(PageManager pageManager)
        {
            this.pageManager = pageManager;
        }




        public bool IsElementPresentAndVisible(By locator)
        {
            var driver = ApplicationManager.GetInstance().Driver;


            try
            {
                return driver.FindElement(locator).Displayed;
            }
            catch (Exception ex)
            {
                if (ex is NoSuchElementException || ex is ElementNotVisibleException || ex is StaleElementReferenceException)
                {
                    return false;
                }
                else if (ex.InnerException != null && ex.InnerException is StaleElementReferenceException)
                {
                    return false;
                }


                throw ex;
            }
        }


        public IWebElement WaitForElement(By locator)
        {
            var driver = ApplicationManager.GetInstance().Driver;
            bool isFound = false;


            for (int i = 0; i < 30; i++)
            {
                if (IsElementPresentAndVisible(locator))
                {
                    isFound = true;
                    break;
                }
                else
                {
                    System.Threading.Thread.Sleep(1000);
                }
            }


            if (isFound)
            {
                return driver.FindElement(locator); ;
            }
            else
            {
                Assert.Fail("ERROR! It's impossible to detect web-element.");
                return null;
            }
        }


    }

Тут, чтобы всё заработало, мне пришлось прописывать несколько раз 

var driver = ApplicationManager.GetInstance().Driver;

Т.е. дублирование кода налицо.

Но если прописать 

protected IWebdriver driver = ApplicationManager.GetInstance().Driver;

в самом классе, то у меня открывается множество экземпляров браузера.

Как можно решить эту проблему без дублирования кода?


  • 0

#22 Alex

Alex

    Постоянный участник

  • Members
  • PipPipPip
  • 237 сообщений
  • ФИО:Алексей

Отправлено 24 августа 2017 - 06:09

 

 

 

А зачем везде передавать ApplicationManager, если он реализует Singleton?

 

 

Эмм... не совсем понял.
Непосредственно ApplicationManager я передаю в PageManager, а для страниц я уже использую PageManager с драйвером от ApplicationManager. По крайней мере такая была задумка...

Можете привести конкретный пример кода, или что необходимо исправить, если где-то у меня есть "излишек"?
 

 

Не передавайте ApplicationManager как параметр нигде. Вы всегда можете получить к нему доступ через ApplicationManager.GetInstance(). Потому нет смысла его везде передавать почем зря. Иначе у вас получается масло маслянное, PageManager имеет поле ApplicationManager, а ApplicationManager имеет поле PageManager. Зачем PageManager-у это поле.

 

 

PageManager использует драйвер от ApplicationManager (для инициализации фабрики).

 

И, например, в классе AnyPage.cs, я также использую драйвер в методах проверки наличия элемента на странице и ожидания появления элемента.

    public class AnyPage
    {
        private PageManager pageManager;


        public AnyPage(PageManager pageManager)
        {
            this.pageManager = pageManager;
        }




        public bool IsElementPresentAndVisible(By locator)
        {
            var driver = ApplicationManager.GetInstance().Driver;


            try
            {
                return driver.FindElement(locator).Displayed;
            }
            catch (Exception ex)
            {
                if (ex is NoSuchElementException || ex is ElementNotVisibleException || ex is StaleElementReferenceException)
                {
                    return false;
                }
                else if (ex.InnerException != null && ex.InnerException is StaleElementReferenceException)
                {
                    return false;
                }


                throw ex;
            }
        }


        public IWebElement WaitForElement(By locator)
        {
            var driver = ApplicationManager.GetInstance().Driver;
            bool isFound = false;


            for (int i = 0; i < 30; i++)
            {
                if (IsElementPresentAndVisible(locator))
                {
                    isFound = true;
                    break;
                }
                else
                {
                    System.Threading.Thread.Sleep(1000);
                }
            }


            if (isFound)
            {
                return driver.FindElement(locator); ;
            }
            else
            {
                Assert.Fail("ERROR! It's impossible to detect web-element.");
                return null;
            }
        }


    }

Тут, чтобы всё заработало, мне пришлось прописывать несколько раз 

var driver = ApplicationManager.GetInstance().Driver;

Т.е. дублирование кода налицо.

Но если прописать 

protected IWebdriver driver = ApplicationManager.GetInstance().Driver;

в самом классе, то у меня открывается множество экземпляров браузера.

Как можно решить эту проблему без дублирования кода?

 

Очевидно, что ApplicationManager оказался не таким уж и Singleton. Я посмотрел, у вас он скорее ThreadLocal<>. А это точно то, что вам нужно (для каждого потока свой экземпляр)? Если да, то лучше откатить как было. Иначе уберите зависимость от потока и  тогда будет обычный Singleton и не будет нескольких инстансов


  • 0



Темы с аналогичным тегами C#, NUnit, WebDriver, Page Object

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных