WatiN зависает "about: blank" для нескольких одновременных экземпляров IE8 - PullRequest
4 голосов
/ 18 мая 2011

Я пытаюсь протестировать несколько веб-сайтов с использованием последней версии WatiN.

Если попытаться запустить несколько тестов одновременно, WatiN в конечном итоге выдаст исключение « Тайм-аут, когда Internet Explorer занят * ».Это происходит из-за того, что Internet Explorer в конечном итоге «зависает» при попытке подключиться к « about: blank ».

Среда выполнения:

  • Windows 7 Professional
  • Internet Explorer 8 (версия 8.0.7600.16385)
  • WatiN (версия 2.1.0.1196)

Я переместил проблему в следующую простую консольную программу c #.Чтобы воссоздать проблему, создайте новую консольную программу c # .NET 3.5 из Visual Studio, добавьте ссылку на WatiN.Core.dll, скомпилируйте и запустите.После примерно 10 секунд на моей машине IE зависает "about: blank", и в конце концов WatiN останавливается и генерирует исключение.

Увеличение тайм-аутов WatiN только задерживает проблему.

Есть кто-нибудьеще видел эту проблему?Можете ли вы воспроизвести проблему, используя мой пример программы?Любые решения?

[Код]

namespace IEBugUsingWatiN
{
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using WatiN.Core;

    class Program
    {
        const int MAX_THREADS = 7;
        volatile static bool _stopAll = false;

        static void Main( string[] args )
        {
            Console.WriteLine( "Initializing WatiN." );

            var watinSettings = WatiN.Core.Settings.Instance;

            watinSettings.AutoCloseDialogs = false;
            watinSettings.AutoMoveMousePointerToTopLeft = false;
            watinSettings.AutoStartDialogWatcher = false;
            watinSettings.HighLightElement = false;
            watinSettings.SleepTime = 200;
            watinSettings.WaitUntilExistsTimeOut = 15;

            Console.WriteLine( "Creating threads." );

            List<Thread> threads = new List<Thread>();

            for ( int numThreads = 0 ; numThreads < MAX_THREADS ; ++numThreads )
            {
                var thread = new Thread( ThreadFunc );
                thread.IsBackground = true;
                thread.SetApartmentState( ApartmentState.STA );
                thread.Start();
                threads.Add( thread );
            }

            Console.WriteLine( "Press Enter key to end tests..." );
            Console.ReadLine();

            _stopAll = true;

            Console.WriteLine( "Waiting for all threads to end..." );

            foreach ( var thread in threads )
            {
                thread.Join();
            }

            Console.WriteLine( "Done." );
        }

        static void ThreadFunc()
        {
            while ( !_stopAll )
            {
                WatiN.Core.IE ie = null;

                try
                {
                    ie = new WatiN.Core.IE();
                    ie.GoTo( "http://www.hertz.com" );
                }
                catch ( System.Exception ex )
                {
                    _stopAll = true;
                    Console.WriteLine( "EXCEPTION: {0}", ex.Message );
                }

                if ( null != ie )
                {
                    ie.Close();
                    ie = null;
                }

                Thread.Sleep( TimeSpan.FromSeconds( 1 ) );
            }
        }
    }
}

[Обновить]

Microsoft подтвердила, что это известнаяошибка.Короче говоря, IE (в частности, wininet.dll ) при определенных обстоятельствах пропускает соединения.Единственный предложенный обходной путь - это явное уничтожение всех экземпляров процесса Internet Explorer после выполнения теста.«Исправление» маловероятно, поскольку это было проблемой для ГОДОВ, и они боятся нарушить совместимость с существующими приложениями.

К вашему сведению, вот что Microsoft должна сказать:

Лучший обходной путь - это, вероятно, убить и перезапустить IE через некоторый интервал во время автоматизации вашего тестового запуска.Вы можете перезапускать IE через определенные промежутки времени или иметь какую-то логику обнаружения в вашем коде.Когда вы попадаете в эту ситуацию, IE не сможет выполнить какой-либо запрос, поэтому я ожидаю, что приложение получит событие BeforeNavigate (если вы обработаете это событие), настроит таймер и к тому времени, когдатаймер запускает проверку, чтобы увидеть, если вы когда-нибудь получите событие DocumentComplete для URL (что вы, вероятно, не будете).Это хороший признак того, что вы столкнулись с проблемой, поэтому вы можете приступить к уничтожению и перезапуску процесса IE на этом этапе.

... этот подход не устраняет основную причину потери соединения wininet, а нав то же время нет никакого практического подхода под вашим контролем, чтобы сделать это.Просто чтобы дать представление о том, как вы попадаете в эту ситуацию…

Всякий раз, когда есть компоненты ActiveX (например, msxml делает запрос AJAX), выполняющий HTTP-запрос, и окно вкладок, в котором размещается этот компонент, закрывается до того, как ответПолученный, есть вероятность, что IE потеряет это соединение wininet, если ActiveX не прервет вызов.Это именно то, что произошло в сценарии Герца.На странице запущен скрипт для выдачи AJAX-запроса.Окно IE закрывается, прежде чем ответ возвращается.После частичного срыва страницы IE вызывает ActiveX (в данном случае MSXML), чтобы уведомить элемент управления о завершении работы.Контроль может затем прервать это соединение после уничтожения.MSXML не прерывает соединение, что приводит к утечке.Проблема глубоко укоренилась в архитектуре дизайна IE и в том, как он взаимодействует со сторонними компонентами.Из-за этого вы, скорее всего, столкнетесь с этой проблемой на веб-сайтах, где есть запросы AJAX.За эти годы было открыто несколько ошибок по этой проблеме, но все эти ошибки были отклонены из-за высокого риска совместимости приложений.Частично трудность в предоставлении исправления заключается в том, что IE не всегда знает, что ActiveX - это тот, кто устанавливает соединение.

Wininet не предоставляет никакого механизма для стороннего элемента управления для сброса или очистки wininet cпотеря связи.По умолчанию IE6 / 7 имеет 2 соединения на сервер, а IE8 - 6, поэтому такое поведение, вероятно, менее заметно в IE8.Здесь задокументирован раздел реестра http://support.microsoft.com/kb/183110, вы можете попытаться увеличить количество доступных подключений.Однако это только задерживает проблему.Вот почему я упомянул единственный поддерживаемый способ сброса состояния wininet - перезапустить процесс IE.

...