panther
panther copied to clipboard
Run multiple instances in parallel?
Hello,
Is it possible to run multiple Panther (using headless chrome) in parallel?
If I try to run same script from the second terminal i get this error:
"PHP Fatal error: Uncaught RuntimeException: The port 9515 is already in use"
What are the ways to run multiple instances at once?
The browser manager accept a port
option to configure the port on which it will communicate. 9515 is the default value. If you want to run multiple instance in parallel on the same machine, you will need to use different ports for each instance of the browser manager.
The browser manager accept a
port
option to configure the port on which it will communicate. 9515 is the default value. If you want to run multiple instance in parallel on the same machine, you will need to use different ports for each instance of the browser manager.
Thanks. Is there an example somwhere how to set custom port?
I see 'PANTHER_WEB_SERVER_PORT' environment variable. Should this one be used? How one sets it within php script?
I've looked into this and unfortunately, there are no ways to provide options when creating the chrome client to override the port.
https://github.com/symfony/panther/blob/master/src/PantherTestCaseTrait.php#L137
From looking at the source of ChromeManager
, there's also no environment variable to override the port:
https://github.com/symfony/panther/blob/master/src/ProcessManager/ChromeManager.php
The only option that would work at the moment, that I can think of, would be to override createPantherClient
either in your own existing base TestCase class, or create one to do just that.
It would be nice to find a fix to be able to test apps using Mercure.
Please read the file: vendor/symfony/panther/src/ProcessManager/ChromeManager.php You can assign the port by assign the $options.
public function __construct(?string $chromeDriverBinary = null, ?array $arguments = null, array $options = [])
{
$this->options = array_merge($this->getDefaultOptions(), $options);
$this->process = new Process([$chromeDriverBinary ?: $this->findChromeDriverBinary(), '--port='.$this->options['port']], null, null, null, null);
$this->arguments = $arguments ?? $this->getDefaultArguments();
}
private function getDefaultOptions(): array
{
return [
'scheme' => 'http',
'host' => '127.0.0.1',
'port' => 9515,
'path' => '/status',
'capabilities' => [],
];
}
You just assign a new array to overwrite the $options. For example,
$options = [
'port' => get_unused_tcp_port()
];
and assign the $options to the constructor and it works. Ps. You need to write the get_unused_tcp_port() function by yourself.
function get_unused_tcp_port() {
$address = '127.0.0.1';
// Create a new socket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
// Bind the source address
socket_bind($sock, $address);
socket_getsockname($sock, $address, $port);
#echo $port;
socket_close($sock);
return $port;
}