PHP Mink / Zombie: ¿manejo de procesos de bloqueo después de una excepción fatal?
Estoy usando el script PHP con el controlador Mink + Zombie (instalar como ennodejs no puede encontrar el módulo 'zombie' con PHP visón) de aquí:PHP Mink / Zombie: ¿la visita de la página devuelve el código de estado 0? ; re-publicación para completar:
<?php
$nodeModPath = "/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules";
# composer autoload:
require_once __DIR__ . '/vendor/autoload.php';
$URL = "https://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');
$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";
}
$page = $session->getPage();
$el_login = $page->findField($LFID);
$el_password = $page->findField($PFID);
$el_button = $page->find('xpath', '//*[@name="'.$BFID.'"]');//findById($BFID);//findField($BFID);
$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();
?>
El problema es que, cuando se ejecuta el script y hace un clic de inicio de sesión, Mink no puede detectar algunas bibliotecas de JavaScript que utiliza la página, y se genera una excepción:
$ php test_php_mink.php
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 at window._evaluate (/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/zombie/lib/document.js:253:75)\n at Object.DOM.languageProcessors.javascript (/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/zombie/lib/dom/scripts.js:26:12)\n at define.proto._eval (/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/zombie/node_modules/jsdom/lib/jsdom/level2/html.js:1477:47)\n at /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/zombie/node_modules/jsdom/lib/jsdom/browser/resource-loader.js:32:22\n at Object.item.check (/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/zombie/node_modules/jsdom/lib/jsdom/level2/html.js:188:11)\n at Object.item.check (/home in /path/to/test_php_mink/vendor/behat/mink-zombie-driver/src/ZombieDriver.php on line 880
La excepción esReferenceError: Effect is not defined
, y se debe a que la página usa este javascript:
<script type="text/javascript" src="./include/common/javascript/scriptaculous/scriptaculous.js?load=effects,dragdrop"></script>
...
new Effect.toggle('header', 'appear', { afterFinish: function() {
Sin embargo, el problema aún mayor es que después de que ocurre este bloqueo, cuando ejecuto el script por segunda vez, se bloquea casi de inmediato, esta vez conError: listen EADDRINUSE 127.0.0.1:8124
:
$ php test_php_mink.php
PHP Fatal error: Uncaught exception 'RuntimeException' with message 'Server process has been terminated: (1) [events.js:141
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE 127.0.0.1:8124
at Object.exports._errnoException (util.js:837:11)
at exports._exceptionWithHostPort (util.js:860:20)
at Server._listen2 (net.js:1231:14)
at listen (net.js:1267:10)
at net.js:1376:9
at doNTCallback3 (node.js:440:9)
at process._tickCallback (node.js:346:17)
at Function.Module.runMain (module.js:473:11)
at startup (node.js:117:18)
at node.js:951:3
]' in /path/to/test_php_mink/vendor/behat/mink-zombie-driver/src/NodeJS/Server.php:413
Stack trace:
#0 /path/to/test_php_mink/vendor/behat/mink-zombie-driver/src/NodeJS/Server.php(306): Behat\Mink\Driver\NodeJS\Server->checkAvailability()
#1 /path/to/test_php_mink/vendor/behat/mink-zombie-driver/src/ZombieDriver. in /path/to/test_php_mink/vendor/behat/mink-zombie-driver/src/NodeJS/Server.php on line 413
Parece que después del primer accidente, todavía haymink
procesos dando vueltas, y de hecho, hay:
$ pgrep -fl mink
7659 sh
7660 node
$ ps axf | grep mink
7687 pts/0 S+ 0:00 | \_ grep --color=tty mink
7659 pts/0 S 0:00 sh -c 'node' '/path/to/test_php_mink/vendor/behat/mink-zombie-driver/bin/mink-zombie-server.js'
7660 pts/0 Sl 0:03 \_ node /path/to/test_php_mink/vendor/behat/mink-zombie-driver/bin/mink-zombie-server.js
En este punto, si elimino estos procesos, digamos, conpkill -f mink
- luego desaparecen del árbol de procesos, y luego puedo ejecutar el script nuevamente, con los mismos resultados que la primera llamada en el OP (y luego tengo que matar los procesos nuevamente, etc.).
¿Cuál sería la mejor / recomendada forma de manejar esto, para que no tenga que matar procesos manualmente, cada vez que el script alcanza una excepción fatal? ¿Hay algo en la biblioteca Mink que permita esto?