我应该使用PHP中的Mink和Zombie驱动程序在服务器上测试登录,而不是在我的控制下,这是HTTPS。问题是我每次访问登录页面时都会获得状态代码0,因此我无法使用任何元素。我曾尝试使用Wireshark检查网络流量 - 但由于它是HTTPS,它是加密的,我不知道Wireshark捕获中发生了什么;我只能看到一些数据已经与服务器交换过。
我无法分享我正在尝试访问的实际页面的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 :(得分: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)
;但是这似乎导致了'RuntimeException' with message 'Could not establish connection: Connection refused (111)'
(browser.statusCode > 0)
等待条件,如果我刚使用随机睡眠延迟即wait($isleep, '(browser.statusCode > 0)');
,它也会失败,因为$isleep
可能是因为wait()
是以秒为单位,而{ {1}}预计毫秒;在我明确地将等待设置为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 ...
...这似乎使用此wait()
解决了连接/状态代码0问题。但是,还有另一个问题 - 无法找到页面使用的其中一个JavaScript类,程序崩溃 - 更糟糕的是,有mink
个进程挂在后台,直到我kill
他们,我不能再次运行脚本了。但我会发布另一个问题......并且这样做了,PHP Mink/Zombie - handling hanging processes after a fatal exception?