t.me/atinfo_chat Telegram группа по автоматизации тестирования

C# Webdriver, Page Factory + Page Object, - Тест проходит при запуске нормально, а при дебаге пропускает клики. Кто с таким стикался ?

Теги: #<Tag:0x00007f7487ea14f8> #<Tag:0x00007f7487ea1430> #<Tag:0x00007f7487ea1368> #<Tag:0x00007f7487ea12a0>

Написали небольшое демо заказчику, что б показать приемущевства Page Object + Page Factory, у них било много threed.sleep-ов итд итп. Наш пример работает - тест проходит. Но когда ми ставим брейкпоинт перед каким то кликом на кнопку, то step into при дебаге кликает ету кнопку и клик не проходит, просто не осуществляеться, но при тесте все работает. Если добавить element.click() 2 раза, тоесть 2 клика подряд, то в дебаге работает тоже. Что за магия ? Кто то стикался ?
Пример где не работает при дебаге: на ReportsMenuItem.Click();

public class PortfolioTab : BasePage
    {

        [FindsBy(How = How.Id, Using = "NavPortfolioReports")]
        private IWebElement ReportsMenuItem;

        public PortfolioTab(IWebDriver driver) : base(driver)
        {
            PageFactory.InitElements(driver, this);
        }

        public ReportTab OpenReportTab()
        {
            ReportsMenuItem.Click();
            return new ReportTab(Driver);
        }

        public override Func<IWebDriver, object> LoadedCondition()
        {
            return ExpectedConditions.ElementIsVisible(By.Id("NavPortfolioReports"));
        }

    }


public class ReportTab : BasePage
    {
        public ReportTab(IWebDriver driver) : base(driver)
        {
            PageFactory.InitElements(driver, this);
        }
        public AllocationHoldings AllocationHoldingsMenu { get { return new AllocationHoldings(Driver); } }

        public override Func<IWebDriver, object> LoadedCondition()
        {
            return ExpectedConditions.ElementIsVisible(By.LinkText("Accounts by Asset Class"));
        }
    }

public abstract class BasePage
    {
        public IWebDriver Driver;
        public BasePage(IWebDriver driver)
        {
            Driver = driver;
            //WaitUntilAvailable(LoadedCondition());
        }

        public abstract Func<IWebDriver, object> LoadedCondition();  
        
        public string GetTitle()
        {
            return Driver.Title;
        }

        public void WaitUntilAvailable(Func<IWebDriver,object> condition)
        {
            IWait<IWebDriver> wait = new WebDriverWait(Driver,
                TimeSpan.FromSeconds(30));
            wait.Timeout = TimeSpan.FromSeconds(60);
            wait.PollingInterval = TimeSpan.FromSeconds(1);
            wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
            wait.Until(condition);
        }
    }

С отформатированным кодом информация будет восприниматься гораздо лучше.

А чем плохо ставить в коде теста Thread.sleep() ?

Ну во-первых, это не красиво, т.к. есть для ожиданий свои методы, во-вторых, вы не можете угадать хватит ли вам времени которое вы выставили, и либо тест упадёт не найдя элемента, либо будет идти долго.

А вот, например, в случае если выполняется операция с дропдаунами: первый дропдаун не успевает закрытся, а вебдрайвер уже кликает на второй, и с помощью Thread.sleep(2000) я выжидаю, пока закончится операция с первым дропом. В таком случае уместно применение?

Это уже такой бородатый баян. Нужно привязываться к конкретным событиям и ждать нужного состояния конкретных элементов либо приложения в целом, а не истечения каких-то абстрактных секунд. Сегодня операция с первым дропдауном занимает меньше 2 секунд, а завтра больше 2 секунд. Результат - все падает. Каждый день будете лезть в код и подправлять?
Второй момент. Когда у вас не 20 тестов, а 200, или 2000, и каждый будет тупить по две секунды ожидая чего-то, как это отразится на общем времени прогона?