2016-05-27 1 views
0

J'utilise le script PHP avec le pilote Mink + Zombie (installez comme sur nodejs cannot find module 'zombie' with PHP mink) à partir d'ici: PHP Mink/Zombie - page visit returns status code 0?; Réaffectation complet:PHP Mink/Zombie - gérer les processus suspendus après une exception fatale?

<?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(); 
?> 

Le problème est, lorsque le script est exécuté, et fait un clic de connexion, des bibliothèques JavaScript que les utilisations de page ne peuvent pas être détectés par Mink, et une exception est levée:

$ 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 

l'exception est ReferenceError: Effect is not defined, et il est dû à la page en utilisant ce javascript:

<script type="text/javascript" src="./include/common/javascript/scriptaculous/scriptaculous.js?load=effects,dragdrop"></script> 
... 
    new Effect.toggle('header', 'appear', { afterFinish: function() { 

Cependant, le problème est encore plus grand que, après cet accident se produit, wh en je lance le script pour la deuxième fois, il se bloque presque tout de suite, cette fois-ci Error: 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 

Il semble que, après le premier accident, il y a encore mink processus qui traînent - et en effet, il y a:

$ 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 

à ce stade, si je tue ces processus - disons, avec pkill -f mink - puis ils disparaissent de l'arborescence des processus, puis je peux courir à nouveau le script, avec les mêmes résultats que le premier appel dans l'OP (et puis je dois encore tuer les processus, etc).

Quelle serait la meilleure façon de gérer cela, donc je ne dois pas tuer manuellement les processus, chaque fois que le script atteint une exception fatale? Y at-il quelque chose dans la bibliothèque Mink qui permettrait cela?

+0

Remarque, j'ai testé cela avec v4.2.1 zombie avec les versions NodeJS iojs-v3.3.1, 4.0.0, 4.4.5, 6.2.0 - et ils échouent tous avec ce script de la même manière. – sdbbs

Répondre

1

La première chose à faire pour éviter les exceptions fatales est de mettre en œuvre/utiliser des méthodes avec une gestion correcte des erreurs. Vous pouvez créer une méthode pour vérifier si l'élément n'est pas nul et s'il doit lancer une exception personnalisée.

Par exemple, dans votre cas méthode FindField renvoie null si l'élément ne se trouve pas, dans ce cas setValue vous enverrons un e utilisé sur un non-objet qui en résulte en une erreur fatale.

+0

Merci pour cela, @lauda - Je ne suis toujours pas clair sur la façon exacte d'implémenter une méthode avec une gestion correcte des erreurs, mais je vais chercher ... Cheers! – sdbbs

+0

OK, j'ai fait un peu plus de tests, et j'ai fait 'echo" Check: el_l: ". gettype ($ el_login). "el_p:". gettype ($ el_password). "el_b". gettype ($ el_button). "\ n"; 'après les commandes' findField', et aucun des objets n'est null: 'Check: el_l: objet el_p: objet el_b object'. Donc, l'exception ne se produit pas ** parce que 'setValue()' ou 'click()' est appelé sur un non-objet - comme indiqué dans l'OP, l'exception se produit quelque part dans la méthode 'click', en raison de une classe JS externe n'étant pas trouvée. Donc, la question est toujours ouverte ... – sdbbs

+1

Comment définissez-vous $ BFID? Avez-vous besoin de cliquer ou vous avez un curseur ou quelque chose comme ça? S'il s'agit d'un cas particulier et que l'action de clic fonctionne dans d'autres cas, avez-vous essayé d'utiliser executeScript dans ce cas? – lauda

0

Un exemple de la gestion des exceptions est:

public function fillWith($locator, $text){ 
 
     $element = $this->getSession()->getPage()->find("xpath", $locator); 
 

 
     if($element === null){ 
 
      throw new Exception("Element $locator not found"); 
 
     }else{ 
 
      $element->setValue($text); 
 
     } 
 
    }

+0

Merci @lauda - vous devriez avoir édité votre ancienne réponse pour mettre cette information dans; mais cela ne change pas le fait que la gestion des exceptions non-objet ne soit pas le problème ici ... – sdbbs