Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ cache:

before_install:
- if [[ $lint = '1' ]]; then wget https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v2.15.1/php-cs-fixer.phar; fi
- if [[ $lint = '1' ]]; then wget https://github.com/phpstan/phpstan/releases/download/0.10.3/phpstan.phar; fi
- if [[ $lint = '1' ]]; then wget https://github.com/phpstan/phpstan/releases/download/0.11.15/phpstan.phar; fi

before_script:
- phpenv config-rm xdebug.ini
Expand Down
14 changes: 14 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
parameters:
inferPrivatePropertyTypeFromConstructor: true
ignoreErrors:
# https://github.com/symfony/symfony/pull/33289
- '#Parameter \#1 \$value of method Symfony\\Component\\Panther\\DomCrawler\\Field\\FileFormField::setValue\(\) expects string, null given\.#'
- '#Call to function is_bool\(\) with string will always evaluate to false\.#'
# https://github.com/symfony/symfony/pull/33278
- '#KernelBrowser#'
# False positive
- '#Else branch is unreachable because ternary operator condition is always true\.#'
- '#Call to private static method getClient\(\) of class Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase\.#'
- '#Call to an undefined static method Symfony\\Component\\Panther\\PantherTestCase::baseAssertPageTitleContains\(\)\.#'
- '#Call to an undefined static method Symfony\\Component\\Panther\\PantherTestCase::baseAssertPageTitleSame\(\)\.#'
# To fix in PHP WebDriver
- '#Parameter \#2 \$desired_capabilities of static method Facebook\\WebDriver\\Remote\\RemoteWebDriver::create\(\) expects array\|Facebook\\WebDriver\\Remote\\DesiredCapabilities\|null, Facebook\\WebDriver\\WebDriverCapabilities given\.#'
# Require a redesign of the underlying Symfony components
- '#Panther\\[a-zA-Z\\]+::__construct\(\) does not call parent constructor from Symfony\\Component\\(BrowserKit|DomCrawler)\\[a-zA-Z]+\.#'
- '#Return type \(void\) of method Symfony\\Component\\Panther\\DomCrawler\\Crawler::clear\(\) should be compatible with return type \(Facebook\\WebDriver\\WebDriverElement\) of method Facebook\\WebDriver\\WebDriverElement::clear\(\)#'
8 changes: 7 additions & 1 deletion src/DomCrawler/Field/FormFieldTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ private function setTextValue($value): void
{
// Ensure to clean field before sending keys.
// Unable to use $this->element->clear(); because it triggers a change event on it's own which is unexpected behavior.
$existingValueLength = \strlen($this->getValue());

$v = $this->getValue();
if (\is_array($v)) {
throw new \InvalidArgumentException('The value must not be an array');
}

$existingValueLength = \strlen($v);
$deleteKeys = \str_repeat(WebDriverKeys::BACKSPACE.WebDriverKeys::DELETE, $existingValueLength);
$this->element->sendKeys($deleteKeys.$value);
}
Expand Down
52 changes: 49 additions & 3 deletions src/PantherTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,58 @@
namespace Symfony\Component\Panther;

use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Test\WebTestAssertionsTrait;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\AbstractBrowser;
use Symfony\Component\Panther\Client as PantherClient;

if (\class_exists(WebTestCase::class)) {
abstract class PantherTestCase extends WebTestCase
{
use PantherTestCaseTrait;
// Compatibility with buggy 4.3 versions, see https://github.com/symfony/symfony/pull/33278
$canUseAssertions = false;
try {
$canUseAssertions = AbstractBrowser::class === (new \ReflectionMethod(WebTestCase::class, 'getClient'))->getReturnType()->getName();
} catch (\ReflectionException $e) {
// Old version of WebTestCase
}

if ($canUseAssertions) {
abstract class PantherTestCase extends WebTestCase
{
use PantherTestCaseTrait;
use WebTestAssertionsTrait {
assertPageTitleSame as private baseAssertPageTitleSame;
assertPageTitleContains as private baseAssertPageTitleContains;
}

public static function assertPageTitleSame(string $expectedTitle, string $message = ''): void
{
$client = self::getClient();
if ($client instanceof PantherClient) {
self::assertSame($expectedTitle, $client->getTitle());

return;
}

self::baseAssertPageTitleSame($expectedTitle, $message);
}

public static function assertPageTitleContains(string $expectedTitle, string $message = ''): void
{
$client = self::getClient();
if ($client instanceof PantherClient) {
self::assertStringContainsString($expectedTitle, $client->getTitle());

return;
}

self::baseAssertPageTitleContains($expectedTitle, $message);
}
}
} else {
abstract class PantherTestCase extends WebTestCase
{
use PantherTestCaseTrait;
}
}
} else {
abstract class PantherTestCase extends TestCase
Expand Down
5 changes: 5 additions & 0 deletions src/PantherTestCaseTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ protected static function createPantherClient(array $options = [], array $kernel
static::bootKernel($kernelOptions);
}

if (\is_callable([self::class, 'getClient'])) {
return self::getClient(self::$pantherClient);
}

return self::$pantherClient;
}

Expand All @@ -168,6 +172,7 @@ protected static function createGoutteClient(array $options = [], array $kernelO
static::bootKernel($kernelOptions);
}

// It's not possible to use assertions with Goutte yet, https://github.com/FriendsOfPHP/Goutte/pull/382 needed
return self::$goutteClient;
}

Expand Down
42 changes: 42 additions & 0 deletions tests/AssertionsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

/*
* This file is part of the Panther project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Symfony\Component\Panther\Tests;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\AbstractBrowser;

class AssertionsTest extends TestCase
{
public function testDomCrawlerAssertions(): void
{
try {
if (AbstractBrowser::class !== (new \ReflectionMethod(WebTestCase::class, 'getClient'))->getReturnType()->getName()) {
$this->markTestSkipped('Old version of WebTestCase');
}
} catch (\ReflectionException $e) {
$this->markTestSkipped('Old version of WebTestCase');
}

self::createPantherClient()->request('GET', '/basic.html');
$this->assertSelectorExists('.p-1');
$this->assertSelectorNotExists('#notexist');
$this->assertSelectorTextContains('body', 'P1');
$this->assertSelectorTextSame('.p-1', 'P1');
$this->assertSelectorTextNotContains('.p-1', 'not contained');
$this->assertPageTitleSame('A basic page');
$this->assertPageTitleContains('A basic');
$this->assertInputValueNotSame('in', '');
$this->assertInputValueSame('in', 'test');
}
}
2 changes: 1 addition & 1 deletion tests/DomCrawler/CrawlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public function testChildren(callable $clientFactory): void
$names[$i] = $c->nodeName();
});

$this->assertSame(['h1', 'main', 'p', 'p'], $names);
$this->assertSame(['h1', 'main', 'p', 'p', 'input'], $names);
}

/**
Expand Down
32 changes: 30 additions & 2 deletions tests/DummyKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Symfony\Component\Panther\Tests;

use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelInterface;

Expand Down Expand Up @@ -80,15 +81,38 @@ public function getRootDir()

public function getContainer()
{
return new class() implements \Psr\Container\ContainerInterface {
public function get($id)
return new class() implements ContainerInterface {
public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
{
}

public function has($id)
{
return false;
}

public function set($id, $service)
{
}

public function initialized($id)
{
return true;
}

public function getParameter($name)
{
return null;
}

public function hasParameter($name)
{
return false;
}

public function setParameter($name, $value)
{
}
};
}

Expand All @@ -107,4 +131,8 @@ public function getLogDir()
public function getCharset()
{
}

public function getProjectDir()
{
}
}
1 change: 1 addition & 0 deletions tests/fixtures/basic.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ <h1>Main</h1>
</main>
<p class="p-1">P1</p>
<p class="p-2">P2</p>
<input name="in" value="test">
</body>
</html>