2016-05-27 2 views
1

Я должен протестировать логин на сервере, а не под моим контролем, который является HTTPS, используя драйвер Mink и Zombie на PHP. Проблема в том, что я в основном получаю код статуса 0 всякий раз, когда я посещаю страницу входа, и поэтому я не могу работать с каким-либо из элементов. Я пробовал использовать Wireshark для проверки сетевого трафика, но поскольку это HTTPS, он зашифрован, и я понятия не имею, что происходит в захватах Wireshark; Я могу видеть только, что некоторые данные были обменены с сервером.PHP Mink/Zombie - просмотр страницы возвращает код состояния 0?

Я не могу поделиться URL-адресом с фактической страницей, к которой я пытаюсь получить доступ, но я обнаружил, что могу продемонстрировать ее публичной демонстрацией Centreon (подробнее о https://www.centreon.com/en/centreon-demo/; заранее извинитесь за Centreon). Так вот пример, который дублирует эту проблему (моя установка как на nodejs cannot find module 'zombie' with PHP mink):

<?php 
$nodeModPath = "/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules"; 

# composer autoload: 
require_once __DIR__ . '/vendor/autoload.php'; 

$URL = "http://demo.centreon.com/centreon"; 
$USERNAME = "admin"; 
$PASSWORD = "centreon"; 
$LFID = "useralias"; 
$PFID = "password"; 
$BFID = "submitLogin"; 


$zsrv = new \Behat\Mink\Driver\NodeJS\Server\ZombieServer(); 
$zsrv->setNodeModulesPath($nodeModPath . "/"); # needs to end with a trailing '/' 
$driver = new \Behat\Mink\Driver\ZombieDriver($zsrv); 
$session = new \Behat\Mink\Session($driver); 

// start the session 
$session->start(); 
$session->setRequestHeader('User-Agent', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36'); 

//~ $session->visit($URL); 

$statcode = 0; 
while ($statcode != 200) { 
    $isleep = rand(2, 7); echo "sleeping $isleep sec...\n"; 
    sleep($isleep); 
    $session->visit($URL); 
    $statcode = $session->getStatusCode(); 
    echo " current URL: " . $session->getCurrentUrl() ."\n"; 
    echo " status code: " . $statcode ."\n"; 
} 


$page = $session->getPage(); 
$el_login = $page->findField($LFID); 
$el_password = $page->findField($PFID); 
$el_button = $page->find('xpath', '//*[@name="'.$BFID.'"]');//findById($BFID);//findField($BFID); 
//~ var_dump($el_button); 

$el_login->setValue($USERNAME); 
$el_password->setValue($PASSWORD); 

echo " pressing/clicking login button\n"; 
$el_button->click(); 

echo "Page URL after click: ". $session->getCurrentUrl() . "\n"; 
$page = $session->getPage(); 
?> 

Теперь, когда я запускаю этот сценарий, я обычно получаю:

$ php test_php_mink.php 
sleeping 4 sec... 
    current URL: https://demo.centreon.com/centreon/ 
    status code: 0 
sleeping 4 sec... 
    current URL: https://demo.centreon.com/centreon/ 
    status code: 0 
sleeping 5 sec... 
    current URL: https://demo.centreon.com/centreon/ 
    status code: 0 
... 

Следует отметить, что в то время как это происходит если я обновил один и тот же URL-адрес в браузере, он вернет страницу правильно (так что статус 200).

Очень, очень редко, я могу получить это, чтобы получить статус 200 и полную загрузку страницы в скрипте; но как только я попробовать еще раз после этого, я снова получить статус 0 - вот фрагмент того, что (с дополнительной ошибкой JavaScript, который, как представляется, связанным с сайтом):

$ php test_php_mink.php 
sleeping 7 sec... 
    current URL: https://demo.centreon.com/centreon/ 
    status code: 0 
sleeping 4 sec... 
    current URL: https://demo.centreon.com/centreon/ 
    status code: 200 
    pressing/clicking login button 
PHP Fatal error: Uncaught exception 'Behat\Mink\Exception\DriverException' with message 'Error while processing event 'click': "ReferenceError: Effect is not defined\n at https://demo.centreon.com/centreon/include/common/javascript/modalbox.js:517:1\n at Object.exports.runInContext (vm.js:44:17)\n ... 

Может кто-нибудь объяснить, что может быть причина этого поведения - и есть ли что-нибудь, что я мог бы правильно восстановить страницу в сценарии?

ответ

0

Ну, я что-то нашел, но я действительно не уверен, как все должно работать - так что более узнаваемый ответ будет очень оценен.

В любом случае, я экспериментировал немного, и в конце концов я обнаружил, что $session->getStatusCode() есть (скорее всего), определенный в ./vendor/behat/mink-zombie-driver/src/ZombieDriver.php как:

public function getStatusCode() 
{ 
    return (int) $this->server->evalJS('browser.statusCode', 'json'); 
} 

Таким образом, в основном, он читает свойство JavaScript browser.statusCode. Оказывается, если мы подождем достаточно долго, чтобы этот код состояния изменился, то загрузка страницы продолжается, и в конце я получаю код состояния 200 (опять же, это для случая, когда обычный браузер всегда правильно читает страницу, тем самым подтверждая, что сеть в порядке). Это изменение, которое я сделал:

$statcode = 0; 
while ($statcode != 200) { 
    $isleep = rand(2, 7); echo "sleeping $isleep sec...\n"; 
    sleep($isleep); 
    $session->visit($URL); 
    // $session->wait(20000, '(0 === jQuery.active)'); # Uncaught exception 'RuntimeException' with message 'Could not establish connection: Connection refused (111)' 
    $session->wait(20000, '(browser.statusCode > 0)'); ### THIS makes things work?! 
    $statcode = $session->getStatusCode(); 
    echo " current URL: " . $session->getCurrentUrl() ."\n"; 
    echo " status code: " . $statcode ."\n"; 
} 

Примечание:

  • Я нашел состояние ожидания (0 === jQuery.active) на How to make Behat wait for an AJAX call?; здесь, однако, кажется, вызывает 'RuntimeException' with message 'Could not establish connection: Connection refused (111)'
  • Даже с условием (browser.statusCode > 0) ожидания, он не как в ОП, если я просто использовал случайную задержку сна т.е. wait($isleep, '(browser.statusCode > 0)'); - то, скорее всего, потому что $isleep в секундах, в то время как wait() ожидает миллисекунды; скрипт начал работать после того, как я явно установил ожидание до 20000 (миллисекунды = 20 секунд, скрипт завершается раньше, чем это).

Сейчас, в последние 10-15 раз я запустить сценарий, я получаю это:

$ php test_php_mink_timeout.php 
sleeping 6 sec... 
    current URL: https://demo.centreon.com/centreon/ 
    status code: 200 
    pressing/clicking login button 
PHP Fatal error: Uncaught exception 'Behat\Mink\Exception\DriverException' with message 'Error while processing event 'click': "ReferenceError: Effect is not defined\n at https://demo.centreon.com/centreon/include/common/javascript/modalbox.js:517:1\n at Object.exports.runInContext (vm.js:44:17)\n at window._evaluate (/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/zombie/lib/document.js:253:75)\n ... 

...что делает вид, что проблема с соединением/кодом состояния 0 решена с помощью этого wait(). Однако есть еще одна проблема: один из классов JavaScript, который использует страница, не может быть найден, а программа выйдет из строя - и что еще хуже, в фоновом режиме происходят процессы mink, и до тех пор, пока я не kill их, я не смогу снова запустить сценарий , Но я отправлю еще один вопрос для этого ... и сделал это, здесь: PHP Mink/Zombie - handling hanging processes after a fatal exception?

Смежные вопросы