Skip to content

Commit 1f7088e

Browse files
Pierstovaldunglas
authored andcommitted
Allow keeping the webserver & client active even after test teardown (symfony#30)
* Add an opt-in listener to launch the server when test starts and stop it when suite stops * Renamed old "Panthere" occurrences to "Panther" * Fix feedback * Added a test for the ServerListener * CS fix & make "$stopServerOnTeardown" public * Fix small typo in Readme
1 parent d53eea5 commit 1f7088e

File tree

4 files changed

+126
-1
lines changed

4 files changed

+126
-1
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,24 @@ Unlike testing and web scraping libraries you're used to, Panther:
166166
* supports custom [Selenium server](https://www.seleniumhq.org) installations
167167
* supports remote browser testing services including [SauceLabs](https://saucelabs.com/) and [BrowserStack](https://www.browserstack.com/)
168168

169+
### Using the `ServerListener` to Always Have a Running Web Server
170+
171+
When you use the Panther client, the web server running in background will be started at runtime and stopped at test's
172+
teardown.
173+
174+
If you want to improve performances and launch the server at PHPUnit startup, you can add the `ServerListener` to
175+
your PHPUnit configuration:
176+
177+
```xml
178+
<!-- phpunit.xml.dist -->
179+
180+
<listeners>
181+
<listener class="Symfony\Component\Panther\ServerListener" />
182+
</listeners>
183+
```
184+
185+
The listener will start the webserver when the test suite is started, and will stop it when all your tests are executed.
186+
169187
## Documentation
170188

171189
Since Panther implements the API of popular libraries, it already has an extensive documentation:

src/PantherTestCaseTrait.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
*/
2727
trait PantherTestCaseTrait
2828
{
29+
/**
30+
* @var bool
31+
*/
32+
public static $stopServerOnTeardown = true;
33+
2934
/**
3035
* @var string|null
3136
*/
@@ -52,6 +57,13 @@ trait PantherTestCaseTrait
5257
protected static $pantherClient;
5358

5459
public static function tearDownAfterClass()
60+
{
61+
if (true === self::$stopServerOnTeardown) {
62+
static::stopWebServer();
63+
}
64+
}
65+
66+
public static function stopWebServer()
5567
{
5668
if (null !== self::$webServerManager) {
5769
self::$webServerManager->quit();
@@ -70,7 +82,7 @@ public static function tearDownAfterClass()
7082
self::$baseUri = null;
7183
}
7284

73-
protected static function startWebServer(?string $webServerDir = null, string $hostname = '127.0.0.1', int $port = 9000): void
85+
public static function startWebServer(?string $webServerDir = null, string $hostname = '127.0.0.1', int $port = 9000): void
7486
{
7587
if (null !== static::$webServerManager) {
7688
return;

src/ServerListener.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Panther project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Symfony\Component\Panther;
15+
16+
use PHPUnit\Framework\TestListener;
17+
use PHPUnit\Framework\TestListenerDefaultImplementation;
18+
use PHPUnit\Framework\TestSuite;
19+
20+
final class ServerListener implements TestListener
21+
{
22+
use TestListenerDefaultImplementation;
23+
24+
public function startTestSuite(TestSuite $suite): void
25+
{
26+
echo "Starting Panther server for test suite {$suite->getName()}...\n";
27+
PantherTestCaseTrait::$stopServerOnTeardown = true;
28+
PantherTestCaseTrait::startWebServer();
29+
}
30+
31+
public function endTestSuite(TestSuite $suite): void
32+
{
33+
echo "\nShutting down Panther server...\n";
34+
PantherTestCaseTrait::stopWebServer();
35+
}
36+
}

tests/ServerListenerTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Panther project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Symfony\Component\Panther\Tests;
15+
16+
use PHPUnit\Framework\TestSuite;
17+
use Symfony\Component\Panther\ServerListener;
18+
19+
class ServerListenerTest extends TestCase
20+
{
21+
private function createTestSuite()
22+
{
23+
$suite = $this->createMock(TestSuite::class);
24+
$suite->expects($this->once())->method('getName')->willReturn('Dummy test suite');
25+
26+
return $suite;
27+
}
28+
29+
public function testStartAndStop(): void
30+
{
31+
$this->expectOutputString("Starting Panther server for test suite Dummy test suite...\n\nShutting down Panther server...\n");
32+
33+
$_SERVER['PANTHER_WEB_SERVER_DIR'] = static::$webServerDir;
34+
35+
$streamContext = stream_context_create(['http' => [
36+
'ignore_errors' => true,
37+
'protocol_version' => '1.1',
38+
'header' => ['Connection: close'],
39+
'timeout' => 1,
40+
]]);
41+
42+
$healthCheck = function () use ($streamContext) {
43+
return @file_get_contents('http://127.0.0.1:9000', false, $streamContext);
44+
};
45+
46+
$testSuite = $this->createTestSuite();
47+
48+
$listener = new ServerListener();
49+
$listener->startTestSuite($testSuite);
50+
51+
// Means the server rendered a 404, so server is running.
52+
static::assertContains('<title>404 Not Found</title>', $healthCheck());
53+
54+
$listener->endTestSuite($testSuite);
55+
56+
// False means that ping failed.
57+
static::assertFalse($healthCheck());
58+
}
59+
}

0 commit comments

Comments
 (0)