Skip to content

Commit de1d8c9

Browse files
authored
Compatibility with Symfony 5 (#254)
* Compatibility with Symfony 5 * Remove useless var * CS * Compat with PHPUnit 7 * Fix tests
1 parent 9c6b6fa commit de1d8c9

File tree

14 files changed

+222
-112
lines changed

14 files changed

+222
-112
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/.php_cs.cache
22
/.php_cs
3+
/.phpunit.result.cache
34
/composer.phar
45
/composer.lock
56
/phpunit.xml

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
[![Build Status](https://travis-ci.org/symfony/panther.svg?branch=master)](https://travis-ci.org/symfony/panther)
66
[![Build status](https://ci.appveyor.com/api/projects/status/bunoc4ufud4oie45?svg=true)](https://ci.appveyor.com/project/fabpot/panther)
7-
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/9ea7e78c-998a-4489-9815-7449ce8291ef/mini.png)](https://insight.sensiolabs.com/projects/9ea7e78c-998a-4489-9815-7449ce8291ef)
7+
[![SymfonyInsight](https://insight.symfony.com/projects/9ea7e78c-998a-4489-9815-7449ce8291ef/mini.png)](https://insight.symfony.com/projects/9ea7e78c-998a-4489-9815-7449ce8291ef)
88

99
*Panther* is a convenient standalone library to scrape websites and to run end-to-end tests **using real browsers**.
1010

src/DomCrawler/Crawler.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,20 @@ public function nodeName(): string
181181
return $this->getElementOrThrow()->getTagName();
182182
}
183183

184-
public function text($default = null): string
184+
public function text(string $default = null, bool $normalizeWhitespace = true): string
185185
{
186+
if (!$normalizeWhitespace) {
187+
throw new \InvalidArgumentException('Panther only supports getting normalized text.');
188+
}
189+
186190
try {
187191
return $this->getElementOrThrow()->getText();
188192
} catch (\InvalidArgumentException $e) {
189193
if (null === $default) {
190194
throw $e;
191195
}
192196

193-
return (string) $default;
197+
return $default;
194198
}
195199
}
196200

src/PantherTestCase.php

Lines changed: 20 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -14,98 +14,46 @@
1414
namespace Symfony\Component\Panther;
1515

1616
use PHPUnit\Framework\TestCase;
17-
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
1817
use Symfony\Bundle\FrameworkBundle\Test\ForwardCompatTestTrait;
19-
use Symfony\Bundle\FrameworkBundle\Test\WebTestAssertionsTrait;
2018
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
21-
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
22-
use Symfony\Component\Panther\Client as PantherClient;
2319

2420
if (\class_exists(WebTestCase::class)) {
25-
if (trait_exists('Symfony\Bundle\FrameworkBundle\Test\WebTestAssertionsTrait') && trait_exists('Symfony\Bundle\FrameworkBundle\Test\ForwardCompatTestTrait')) {
26-
abstract class PantherTestCase extends WebTestCase
27-
{
28-
use ForwardCompatTestTrait;
29-
use PantherTestCaseTrait;
30-
use WebTestAssertionsTrait {
31-
assertPageTitleSame as private baseAssertPageTitleSame;
32-
assertPageTitleContains as private baseAssertPageTitleContains;
33-
}
34-
35-
public static function assertPageTitleSame(string $expectedTitle, string $message = ''): void
21+
if (trait_exists('Symfony\Bundle\FrameworkBundle\Test\WebTestAssertionsTrait')) {
22+
if (trait_exists('Symfony\Bundle\FrameworkBundle\Test\ForwardCompatTestTrait')) {
23+
// Symfony 4.3
24+
abstract class PantherTestCase extends WebTestCase
3625
{
37-
$client = self::getClient();
38-
if ($client instanceof PantherClient) {
39-
self::assertSame($expectedTitle, $client->getTitle());
26+
use ForwardCompatTestTrait;
27+
use WebTestAssertionsTrait;
4028

41-
return;
29+
private function doTearDown()
30+
{
31+
parent::tearDown();
32+
self::getClient(null);
4233
}
43-
44-
self::baseAssertPageTitleSame($expectedTitle, $message);
4534
}
46-
47-
public static function assertPageTitleContains(string $expectedTitle, string $message = ''): void
35+
} else {
36+
// Symfony 5
37+
abstract class PantherTestCase extends WebTestCase
4838
{
49-
$client = self::getClient();
50-
if ($client instanceof PantherClient) {
51-
if (method_exists(self::class, 'assertStringContainsString')) {
52-
self::assertStringContainsString($expectedTitle, $client->getTitle());
53-
54-
return;
55-
}
56-
57-
self::assertContains($expectedTitle, $client->getTitle());
39+
use WebTestAssertionsTrait;
5840

59-
return;
41+
protected function tearDown(): void
42+
{
43+
parent::tearDown();
44+
self::getClient(null);
6045
}
61-
62-
self::baseAssertPageTitleContains($expectedTitle, $message);
63-
}
64-
65-
private function doTearDown()
66-
{
67-
parent::tearDown();
68-
self::getClient(null);
69-
}
70-
71-
// Copied from WebTestCase to allow assertions to work with createClient
72-
73-
/**
74-
* Creates a KernelBrowser.
75-
*
76-
* @param array $options An array of options to pass to the createKernel method
77-
* @param array $server An array of server parameters
78-
*
79-
* @return KernelBrowser A KernelBrowser instance
80-
*/
81-
protected static function createClient(array $options = [], array $server = [])
82-
{
83-
$kernel = static::bootKernel($options);
84-
85-
try {
86-
/**
87-
* @var KernelBrowser
88-
*/
89-
$client = $kernel->getContainer()->get('test.client');
90-
} catch (ServiceNotFoundException $e) {
91-
if (class_exists(KernelBrowser::class)) {
92-
throw new \LogicException('You cannot create the client used in functional tests if the "framework.test" config is not set to true.');
93-
}
94-
throw new \LogicException('You cannot create the client used in functional tests if the BrowserKit component is not available. Try running "composer require symfony/browser-kit"');
95-
}
96-
97-
$client->setServerParameters($server);
98-
99-
return self::getClient($client);
10046
}
10147
}
10248
} else {
49+
// Symfony 4.3 and inferior
10350
abstract class PantherTestCase extends WebTestCase
10451
{
10552
use PantherTestCaseTrait;
10653
}
10754
}
10855
} else {
56+
// Without Symfony
10957
abstract class PantherTestCase extends TestCase
11058
{
11159
use PantherTestCaseTrait;

src/ServerListener.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
use PHPUnit\Framework\TestListenerDefaultImplementation;
2020
use PHPUnit\Framework\TestSuite;
2121

22+
@trigger_error(sprintf('The "%s" class is deprecated since Panther 0.5.3, use "%s" instead.', ServerListener::class, ServerExtension::class), E_USER_DEPRECATED);
23+
24+
/**
25+
* @deprecated since Panther 0.5.3, use Symfony\Component\Panther\ServerExtension instead.
26+
*/
2227
final class ServerListener implements TestListener
2328
{
2429
use TestListenerDefaultImplementation;

src/WebTestAssertionsTrait.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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 Symfony\Bundle\FrameworkBundle\KernelBrowser;
17+
use Symfony\Bundle\FrameworkBundle\Test\WebTestAssertionsTrait as BaseWebTestAssertionsTrait;
18+
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
19+
use Symfony\Component\Panther\Client as PantherClient;
20+
21+
/**
22+
* Tweaks Symfony's WebTestAssertionsTrait to be compatible with Panther.
23+
*
24+
* @author Kévin Dunglas <[email protected]>
25+
*/
26+
trait WebTestAssertionsTrait
27+
{
28+
use PantherTestCaseTrait;
29+
use BaseWebTestAssertionsTrait {
30+
assertPageTitleSame as private baseAssertPageTitleSame;
31+
assertPageTitleContains as private baseAssertPageTitleContains;
32+
}
33+
34+
public static function assertPageTitleSame(string $expectedTitle, string $message = ''): void
35+
{
36+
$client = self::getClient();
37+
if ($client instanceof PantherClient) {
38+
self::assertSame($expectedTitle, $client->getTitle());
39+
40+
return;
41+
}
42+
43+
self::baseAssertPageTitleSame($expectedTitle, $message);
44+
}
45+
46+
public static function assertPageTitleContains(string $expectedTitle, string $message = ''): void
47+
{
48+
$client = self::getClient();
49+
if ($client instanceof PantherClient) {
50+
if (method_exists(self::class, 'assertStringContainsString')) {
51+
self::assertStringContainsString($expectedTitle, $client->getTitle());
52+
53+
return;
54+
}
55+
56+
self::assertContains($expectedTitle, $client->getTitle());
57+
58+
return;
59+
}
60+
61+
self::baseAssertPageTitleContains($expectedTitle, $message);
62+
}
63+
64+
// Copied from WebTestCase to allow assertions to work with createClient
65+
66+
/**
67+
* Creates a KernelBrowser.
68+
*
69+
* @param array $options An array of options to pass to the createKernel method
70+
* @param array $server An array of server parameters
71+
*
72+
* @return KernelBrowser A KernelBrowser instance
73+
*/
74+
protected static function createClient(array $options = [], array $server = [])
75+
{
76+
$kernel = static::bootKernel($options);
77+
78+
try {
79+
/**
80+
* @var KernelBrowser
81+
*/
82+
$client = $kernel->getContainer()->get('test.client');
83+
} catch (ServiceNotFoundException $e) {
84+
if (class_exists(KernelBrowser::class)) {
85+
throw new \LogicException('You cannot create the client used in functional tests if the "framework.test" config is not set to true.');
86+
}
87+
throw new \LogicException('You cannot create the client used in functional tests if the BrowserKit component is not available. Try running "composer require symfony/browser-kit"');
88+
}
89+
90+
$client->setServerParameters($server);
91+
92+
return self::getClient($client);
93+
}
94+
}

tests/DomCrawler/CrawlerTest.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Facebook\WebDriver\WebDriverElement;
1717
use Symfony\Component\DomCrawler\Crawler;
1818
use Symfony\Component\Panther\Client;
19+
use Symfony\Component\Panther\Client as PantherClient;
1920
use Symfony\Component\Panther\DomCrawler\Image;
2021
use Symfony\Component\Panther\DomCrawler\Link;
2122
use Symfony\Component\Panther\Tests\TestCase;
@@ -47,7 +48,7 @@ public function testGetUri(callable $clientFactory): void
4748
public function testHtml(callable $clientFactory): void
4849
{
4950
$crawler = $this->request($clientFactory, '/basic.html');
50-
$this->assertContains('<title>A basic page</title>', $crawler->html());
51+
$this->assertStringContainsString('<title>A basic page</title>', $crawler->html());
5152
}
5253

5354
/**
@@ -314,4 +315,24 @@ public function testHtmlDefault(callable $clientFactory): void
314315
$crawler = $this->request($clientFactory, '/basic.html');
315316
$this->assertSame('default', $crawler->filter('header')->html('default'));
316317
}
318+
319+
/**
320+
* @dataProvider clientFactoryProvider
321+
*/
322+
public function testNormalizeText(callable $clientFactory, string $clientClass): void
323+
{
324+
if (PantherClient::class !== $clientClass) {
325+
$this->markTestSkipped('Need https://github.com/symfony/symfony/pull/34151');
326+
}
327+
328+
$crawler = $this->request($clientFactory, '/normalize.html');
329+
$this->assertSame('Foo Bar Baz', $crawler->filter('#normalize')->text());
330+
}
331+
332+
public function testDoNotNormalizeText()
333+
{
334+
$this->expectException(\InvalidArgumentException::class);
335+
336+
self::createPantherClient()->request('GET', self::$baseUri.'/normalize.html')->filter('#normalize')->text(null, false);
337+
}
317338
}

tests/DomCrawler/Field/FileFormFieldTest.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ class FileFormFieldTest extends TestCase
2323
{
2424
private static $invalidUploadFileName = 'narf.txt';
2525

26+
private function assertValueContains($needle, $haystack): void
27+
{
28+
if (\is_string($haystack)) {
29+
$this->assertStringContainsString($needle, $haystack);
30+
31+
return;
32+
}
33+
34+
$this->assertContains($needle, $haystack);
35+
}
36+
2637
/**
2738
* @dataProvider clientFactoryProvider
2839
*/
@@ -36,7 +47,7 @@ public function testFileUploadWithUpload(callable $clientFactory)
3647
$this->assertInstanceOf(FileFormField::class, $fileFormField);
3748
$fileFormField->upload($this->getUploadFilePath(self::$uploadFileName));
3849

39-
$this->assertContains(self::$uploadFileName, $form['file_upload']->getValue());
50+
$this->assertValueContains(self::$uploadFileName, $form['file_upload']->getValue());
4051
}
4152

4253
/**
@@ -52,13 +63,15 @@ public function testFileUploadWithSetValue(callable $clientFactory)
5263
$this->assertInstanceOf(FileFormField::class, $fileFormField);
5364
$fileFormField->setValue($this->getUploadFilePath(self::$uploadFileName));
5465

55-
$this->assertContains(self::$uploadFileName, $form['file_upload']->getValue());
66+
$this->assertValueContains(self::$uploadFileName, $form['file_upload']->getValue());
5667
}
5768

5869
/**
5970
* @dataProvider clientFactoryProvider
71+
*
72+
* @param mixed $class
6073
*/
61-
public function testFileUploadWithSetFilePath(callable $clientFactory)
74+
public function testFileUploadWithSetFilePath(callable $clientFactory, $class)
6275
{
6376
$crawler = $this->request($clientFactory, '/file-form-field.html');
6477
$form = $crawler->filter('form')->form();
@@ -68,10 +81,10 @@ public function testFileUploadWithSetFilePath(callable $clientFactory)
6881
$this->assertInstanceOf(FileFormField::class, $fileFormField);
6982

7083
$fileFormField->setFilePath($this->getUploadFilePath(self::$uploadFileName));
71-
$this->assertContains(self::$uploadFileName, $form['file_upload']->getValue());
84+
$this->assertValueContains(self::$uploadFileName, $form['file_upload']->getValue());
7285

7386
$fileFormField->setFilePath($this->getUploadFilePath(self::$anotherUploadFileName));
74-
$this->assertContains(self::$anotherUploadFileName, $form['file_upload']->getValue());
87+
$this->assertValueContains(self::$anotherUploadFileName, $form['file_upload']->getValue());
7588
}
7689

7790
/**

tests/ProcessManager/ChromeManagerTest.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,11 @@ public function testRun()
2929
$manager->quit();
3030
}
3131

32-
/**
33-
* @expectedException \RuntimeException
34-
* @expectedExceptionMessage The port 9515 is already in use.
35-
*/
3632
public function testAlreadyRunning()
3733
{
34+
$this->expectException(\RuntimeException::class);
35+
$this->expectExceptionMessage('The port 9515 is already in use.');
36+
3837
$driver1 = new ChromeManager();
3938
$driver1->start();
4039

0 commit comments

Comments
 (0)