Продолжение загрузки страницы, после закрытия диалогового окна в двустороннем TLS

Есть задача: проверка двустороннего TLS на сайте, которая почти сформирована методом ниже. Код запускается несколько раз последовательно с передачей разных параметров, т.е. проверка на разных серверах.

        [TestMethod]
        override public void testMain(String[] arguments)
        {
            String host = arguments[0];
            //Задание опций для драйвера(хотя на всех машинах настроил все в соответствии с Required Configuration тут:
            //https://code.google.com/p/selenium/wiki/InternetExplorerDriver
            var options = new InternetExplorerOptions();
            options.EnsureCleanSession = true;
            options.IgnoreZoomLevel = true;
            options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;

            Logger.info("Start test");
            try
            {
                //Запуск браузера и переход на страничку
                driver = new InternetExplorerDriver();
                driver.Manage().Window.Maximize();
                driver.Manage().Cookies.DeleteAllCookies();
                driver.Url = "https://" + host + "/";
                Logger.info("Webdriver started..");

                //Спим 5 сек и надимаем на Ok в окне безопасности, т.е. выбираем сертификат клиента для TLS-сессии
                Thread.Sleep(5000);
                if (SecurityWindows().exists())
                {
                    SecurityWindowsOk().click();
                }

                //Таймаут поместил сюда, поскольку, если он будет выше предыдущих 5 строчек кода,
                //то тест фейлится по указанному таймауту
                driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromMinutes(5));
                WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromMinutes(5));
                wait.Until(ExpectedConditions.ElementExists(By.CssSelector("h1")));
                wait.Until(ExpectedConditions.TitleContains("Title"));

Выше представлен кусок кода, который работает, но с периодическими падениями по таймауту в 60 секунд, хотя я задавал в 5 минут.
Если задавать имплицитные ожидания, то тест сразу фейлится, как появляется диалоговое окно с ошибкой “modal dialog present”, если код с ожиданием wait перенести до нажатия, то код нажатия на кнопку не срабатывает.

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

Совсем забыл:
Проверяется на IE 11 на 7(32) - Server 2012R2
Версия InternetExplorer Driver 2.45
Версия библиотек та же, что и драйвера.

  • У вас нет валидного SSL сертификата
  • Вы поставили опцию IntroduceInstabilityByIgnoringProtectedModeSettings в true

Таки да, тесты будут гарантированно не стабильными.

Кстати, проблемы с сертификатом можно обойти если поставить Fiddler на тестовую машину и поиграться с его SSL настройками

Но, это, конечно же, небезопасно и понимать такое решение можно только на свой страх и риск

[quote=“dzhariy, post:3, topic:7237, full:true”]

По поводу валидности сертификата - он действителен, т.е. при проверке осуществляются следующие предустановки:

  1. Создается сертификат(закрытый ключ) как для клиента, так и для сервера с соответствующими аттрибутами
  2. Сертификаты устанавливаются в соответствующие места(хранилища). Клиентский в личное текущего пользователя, а серверный в личное локального компьютера.
  3. Устанавливаются корневые и СОС удостоверяющего центра.
  4. и др. действия по настройке IIS для TLS и настройки на клиентской стороне…
  5. Собственно тестируется функция криптопровайдера. Т.е. загвоздка не может таиться в настройках стендов, т.к. при ручной проверке все отрабатывает на ура.

По поводу IntroduceInstabilityByIgnoringProtectedModeSettings в true скажу следующее:
На самом деле во всех стендах начиная от 7(x86) - 2012R2 в настройках IE во всех зонах включен защищенный режим. А ключом воспользовался, на всякий случай, может забыл где поставить.
P.S. на всех машинах настроил все в соответствии с Required Configuration отсюдыва:

Тогда, разъясните пожалуйста несколько следующих вопросов:

  1. С какой ошибкой валится тест? (стек трейс)
  2. Что отображает браузер в момент ошибки? Появляются ли Alert’ты или другие сторонние всплывающие окна?
  3. Как это повлияет на тест, если вы поставите SetPageLoadTimeout(TimeSpan.MinValue)?
  4. Проблема только в Internet Explorer или в других браузерах также?
  5. Не воспроизводится ли случайно вот эта проблема? Issue 8302: After installing Windows Update KB 3025390 IEDriverServer.exe does not execute JavaScript

Объяснения:
1.К сожалению, в тесте выводится только сообщение самого исключения в качестве примечания к падению теста. Исправил вывод трейса при падении, как проявится, я отпишусь.

2.Изначально браузер отображает стартовую страничку(не помню текста), затем по переходу на указанный адрес, всплывает окно безопасности Windows на подобие этого:

Соответственно, тест жмет на кнопку Ok, Средствами CodedUI и продолжается загрузка странички, на которой просто верифицируются данные(текст и тайтл) говорящие о том, что страничка действительно загрузилась. Тем самым осуществляется проверка двустороннего TLS.

3.Насколько я знаю, если указать данный параметр, то драйвер не даст нажать на кнопку Ok у всплывающего окна, сторонними средствами.

4.Да, проблема только в IE 11. Собственно проверяется только данный браузер.

5.Нет, данная проблема не воспроизводится.

Да, теперь мне ясно что кейс очень редкий :smile:

Полный стектрейс может прояснить ситуацию (а может и нет).
Может быть, загвозка где-то внутри самого драйвера, например, таймаут по времени выполнения внутренних скриптов, которые блокируются окном безопасности.

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

А вот и отловленный StackTrace:
Modal dialog present. Stack Trace is: at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse) in RemoteWebDriver.cs:line 1158 at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters) in RemoteWebDriver.cs:line 920 at OpenQA.Selenium.Remote.RemoteTimeouts.ExecuteSetTimeout(String timeoutType, TimeSpan timeToWait) in RemoteTimeouts.cs:line 130 at OpenQA.Selenium.Remote.RemoteTimeouts.SetPageLoadTimeout(TimeSpan timeToWait) in RemoteTimeouts.cs:line 114 at tests.CSP.CheckTwoSideTLSSelenium.testMain(String[] arguments) in CheckTwoSideTLSSelenium.cs:line 67

Пути, на подобие “C:\Program Files” из трейса я удалил, т.к. посчитал их ненужными.

Сам файл CheckTwoSideTLSSelenium.cs залил сюда: DropMeFiles – free one-click file sharing service

Есть один чит: если оставить в списке только 1 сертификат, то он должен аксептиться по-дефолту, без отображения модального окна. Т.е. код для клика из дополнительных тулов вам не пригодится. Другой вопрос - как быть, если вам нужно всегда выбирать определенный сертификат? У нас разработчик писал cmd тулу, которая умеет сетить сертификаты в систему. Можете попросить ваших написать нечто подобное, или самому попробовать. Т.е. перед запуском теста будете чистить сертификаты и устанавливать единственный нужный.

В свое время отказался от доп. тулов для выбора сертификата, ибо некоторые драйверы вешали браузер на данном степе. Т.е. по сути, клик на элемент, порождающий модальное окно, был фейковый (безо всяких респонсов), что приводило к тому, что драйвер уходил в состояние “спячки”, пока юзер не выбирал нужную опцию. Пришлось оставлять всего один сертификат.

Можете конечно еще попробовать запускать событие, приводящее к появлению сертификатов, в отдельном потоке, с механизмом таймаута. Т.е., к примеру, поток будет самоубиваться по истечении 5 сек. В итоге, вы кликните на элемент, браузер повиснет с модальным диалогом. Но ввиду того, что зависнет не main thread, по таймауту приложение отвиснет и вы сможете кликнуть на элемент модального окна. Но не уверен, что такое сработает с Remote вариантом.

Возможно под читом вы подразумевали проверку одностороннего TLS, т.е. когда в IIS в настройках SSL не установлен флажок “требовать SSL”. Поскольку этот сценарий у нас тоже проверяется(без галки) и в этом случае окно с запросом сертификата не появляется.
По счет сертификатов хочу сказать, что при проверке двустороннего TLS(с галкой и требованием сертификатов) независимо от того, 1 или 2 или более сертификатов установлено в системе, окно будет выводиться.
У нас всегда проверятся только с одним сертификатом. Указанный выше скриншот был показан только для примера самого окна.

По поводу многопоточной(2х) я тоже думал, но никак руки не доходят поэкспериментировать. Только я не понял, почему вы упомянули использование Remote-варианта?
Да тесты выполняются на удаленной виртуальной машине, но вебдрайверы для каждой тестируемой системы являются исключительно локальными.

Вот еще один пример ошибки при выполнении этого же кода:

Exception.message:

The HTTP request to the remote WebDriver server for URL http://localhost:1570/session/caed9787-139d-43ce-b0eb-7a9b4aa150ba/element timed out after 60 seconds.. 

Stack Trace is:

в OpenQA.Selenium.Remote.HttpCommandExecutor.CreateResponse(WebRequest request) в HttpCommandExecutor.cs:строка 150 в OpenQA.Selenium.Remote.HttpCommandExecutor.Execute(Command commandToExecute) в HttpCommandExecutor.cs:строка 114 в OpenQA.Selenium.Remote.DriverServiceCommandExecutor.Execute(Command commandToExecute) в DriverServiceCommandExecutor.cs:строка 78 в OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters) в RemoteWebDriver.cs:строка 910 в OpenQA.Selenium.Remote.RemoteWebDriver.FindElement(String mechanism, String value) в RemoteWebDriver.cs:строка 954 в OpenQA.Selenium.Remote.RemoteWebDriver.FindElementByCssSelector(String cssSelector) в RemoteWebDriver.cs:строка 728 в OpenQA.Selenium.By.<>c__DisplayClass1e.b__1c(ISearchContext context) в By.cs:строка 260 в OpenQA.Selenium.By.FindElement(ISearchContext context) в By.cs:строка 309 в OpenQA.Selenium.Remote.RemoteWebDriver.FindElement(By by) в RemoteWebDriver.cs:строка 330 в OpenQA.Selenium.Support.UI.ExpectedConditions.<>c__DisplayClass10.b__f(IWebDriver driver) в ExpectedConditions.cs:строка 109 в OpenQA.Selenium.Support.UI.DefaultWait`1.Until[TResult](Func`2 condition) в DefaultWait.cs:строка 183 в tests.CSP.CheckTwoSideTLSSelenium.testMain(String[] arguments) в CheckTwoSideTLSSelenium.cs:строка 68

Из скриншота в логах видно, что сайт не успел догрузиться =(

Ну тогда попробуйте изобрести отложенный поиск кнопки Ok средствами вашей доп. тулы. Я когда-то для SikuliX писал observer, который ждал бы картинку в течении заданного таймаута. Т.е. скрипт поиска можно было бы запустить до непосредственного редиректа. Затем грузили бы URL, и не смотря на зависший браузер с модальным окном, клик все равно отработал бы, что в последствии отвесило бы селениумовские процессы.

П.С. И уберите, ради Бога, вызовы GC из кода.

Сам в недоумении был, когда перестало нормально отрабатывать следующее:

driver.Quit();
driver.Dispose();

Поэтому пришлось добавить эти заветные строки c GC =D

По поводу отложенного поиска, уже начал обдумывать решение.

А зачем звать Dispose после Quit? Разве Quit не делает всю грязную работу? Или в .Net какая-то своя магия?

На всякий случай)

Ситуация сама собой разрешилась, после обновления драйвера IE и самих библиотек Selenium до 2.47