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 .php_cs.dist
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

$header = <<<'HEADER'
This file is part of the Panthère project.
This file is part of the Panther project.

(c) Kévin Dunglas <dunglas@gmail.com>

Expand Down
80 changes: 40 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
<h1 align="center"><img src="panthere.png" alt="Panthère"></h1>
<h1 align="center"><img src="panther.png" alt="Panther"></h1>

**A browser testing and web scraping library for [PHP](https://php.net) and [Symfony](https://symfony.com)**

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

*Panthère* is a convenient standalone library to scrape websites and to run end-to-end tests **using real browsers**.
*Panther* is a convenient standalone library to scrape websites and to run end-to-end tests **using real browsers**.

Panthère is super powerful, it leverages [the W3C's WebDriver protocol](https://www.w3.org/TR/webdriver/) to drive native web browsers such as Google Chrome and Firefox.
Panther is super powerful, it leverages [the W3C's WebDriver protocol](https://www.w3.org/TR/webdriver/) to drive native web browsers such as Google Chrome and Firefox.

Panthère is very easy to use, because it implements the popular Symfony's [BrowserKit](https://symfony.com/doc/current/components/browser_kit.html) and
Panther is very easy to use, because it implements the popular Symfony's [BrowserKit](https://symfony.com/doc/current/components/browser_kit.html) and
[DomCrawler](https://symfony.com/doc/current/components/dom_crawler.html) APIs, and contains
all features you need to test your apps. It will sound familiar if you have ever created [a functional test for a Symfony app](https://symfony.com/doc/current/testing.html#functional-tests):
as the API is exactly the same!
Keep in mind that Panthère can be used in every PHP project, it's a standalone library.
Keep in mind that Panther can be used in every PHP project, it's a standalone library.

Panthère automatically finds your local installation of Chrome and launches it (thanks to [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/)),
Panther automatically finds your local installation of Chrome and launches it (thanks to [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/)),
so you don't need to install anything on your computer, neither Selenium server nor obscure driver.

In test mode, Panthère automatically starts your application using [the PHP built-in web-server](http://php.net/manual/en/features.commandline.webserver.php).
You can just focus on writing your tests or web-scraping scenario, Panthère takes care of everything else.
In test mode, Panther automatically starts your application using [the PHP built-in web-server](http://php.net/manual/en/features.commandline.webserver.php).
You can just focus on writing your tests or web-scraping scenario, Panther takes care of everything else.

## Install

Use [Composer](https://getcomposer.org/) to install Panthère in your project. You may want to use the --dev flag if you want to use Panthere for testing only and not for web scraping:
Use [Composer](https://getcomposer.org/) to install Panther in your project. You may want to use the --dev flag if you want to use Panther for testing only and not for web scraping:

composer req symfony/panthere:dev-master
composer req symfony/panther:dev-master

composer req --dev symfony/panthere:dev-master
composer req --dev symfony/panther:dev-master

## Basic Usage

Expand All @@ -37,7 +37,7 @@ Use [Composer](https://getcomposer.org/) to install Panthère in your project. Y

require __DIR__.'/vendor/autoload.php'; // Composer's autoloader

$client = \Symfony\Component\Panthere\Client::createChromeClient();
$client = \Symfony\Component\Panther\Client::createChromeClient();
$crawler = $client->request('GET', 'http://api-platform.com'); // Yes, this website is 100% in JavaScript

$link = $crawler->selectLink('Support')->link();
Expand All @@ -52,20 +52,20 @@ $client->takeScreenshot('screen.png'); // Yeah, screenshot!

## Testing Usage

The `PanthereTestCase` class allows you to easily write E2E tests. It automatically starts your app using the built-in PHP
web server and let you crawl it using Panthère.
The `PantherTestCase` class allows you to easily write E2E tests. It automatically starts your app using the built-in PHP
web server and let you crawl it using Panther.
It extends [PHPUnit](https://phpunit.de/)'s `TestCase` and provide all testing tools you're used to.

```php
<?php

use Symfony\Component\Panthere\PanthereTestCase;
use Symfony\Component\Panther\PantherTestCase;

class E2eTest extends PanthereTestCase
class E2eTest extends PantherTestCase
{
public function testMyApp()
{
$client = static::createPanthereClient(); // Your app is automatically started using the built-in web server
$client = static::createPantherClient(); // Your app is automatically started using the built-in web server
$crawler = $client->request('GET', '/mypage');

$this->assertContains('My Title', $crawler->filter('title')->text()); // You can use any PHPUnit assertion
Expand All @@ -79,13 +79,13 @@ To run this test:

### A Polymorph Feline

If you are testing a Symfony application, `PanthereTestCase` automatically extends the `WebTestCase` class. It means
If you are testing a Symfony application, `PantherTestCase` automatically extends the `WebTestCase` class. It means
you can easily create functional tests, which can directly execute the kernel of your application and access all your existing
services. Unlike the Panthère's client, the Symfony's testing client doesn't support JavaScript and screenshots capturing, but
services. Unlike the Panther's client, the Symfony's testing client doesn't support JavaScript and screenshots capturing, but
it is super-fast!

Alternatively (and even for non-Symfony apps), Panthère can also leverage the [Goutte](https://github.com/FriendsOfPHP/Goutte)
web scraping library, which is an intermediate between the Symfony's and the Panthère's test clients. Goutte sends real HTTP
Alternatively (and even for non-Symfony apps), Panther can also leverage the [Goutte](https://github.com/FriendsOfPHP/Goutte)
web scraping library, which is an intermediate between the Symfony's and the Panther's test clients. Goutte sends real HTTP
requests, it is fast and is able to browse any webpage, not only the ones of the application under test.
But Goutte doesn't support JavaScript and other advanced features because it is entirely written in PHP.

Expand All @@ -96,17 +96,17 @@ to authenticate to an external SSO server, do I want to access the kernel of the
```php
<?php

use Symfony\Component\Panthere\PanthereTestCase;
use Symfony\Component\Panther\PantherTestCase;

class E2eTest extends PanthereTestCase
class E2eTest extends PantherTestCase
{
public function testMyApp()
{
$symfonyClient = static::createClient(); // A cute kitty: the Symfony's functional test too
$goutteClient = static::createGoutteClient(); // An agile lynx: Goutte
$panthereClient = static::createPanthereClient(); // A majestic Panther
$pantherClient = static::createPantherClient(); // A majestic Panther

// Both Goutte and Panthère benefits from the built-in HTTP server
// Both Goutte and Panther benefits from the built-in HTTP server

// enjoy the same API for the 3 felines
// $*client->request('GET', '...')
Expand All @@ -120,7 +120,7 @@ class E2eTest extends PanthereTestCase

## Features

Unlike testing and web scraping libraries you're used to, Panthère:
Unlike testing and web scraping libraries you're used to, Panther:

* executes the JavaScript code contained in webpages
* supports everything that Chrome (or Firefox) implements
Expand All @@ -132,39 +132,39 @@ Unlike testing and web scraping libraries you're used to, Panthère:

## Documentation

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

* For the `Client` class, read [the BrowserKit's documentation](https://symfony.com/doc/current/components/browser_kit.html)
* For the `Crawler` class, read [the DomCrawler's documentation](https://symfony.com/doc/current/components/dom_crawler.html)
* For Webdriver, read [the Facebook's PHP WebDriver documentation](https://github.com/facebook/php-webdriver)

## Environment Variables

The following environment variables can be set to change some Panthère behaviors:
The following environment variables can be set to change some Panther behaviors:

* `PANTHERE_NO_HEADLESS`: to disable browsers's headless mode (will display the testing window, useful to debug)
* `PANTHERE_NO_SANDBOX`: to disable [Chrome's sandboxing](https://chromium.googlesource.com/chromium/src/+/b4730a0c2773d8f6728946013eb812c6d3975bec/docs/design/sandbox.md) (unsafe, but allows to use Panthère in containers)
* `PANTHERE_WEB_SERVER_DIR`: to change the project's document root (default to `public/`)
* `PANTHERE_CHROME_DRIVER_BINARY`: to use another `chromedriver` binary, instead of relying on the ones already provided by Panthère
* `PANTHER_NO_HEADLESS`: to disable browsers's headless mode (will display the testing window, useful to debug)
* `PANTHER_NO_SANDBOX`: to disable [Chrome's sandboxing](https://chromium.googlesource.com/chromium/src/+/b4730a0c2773d8f6728946013eb812c6d3975bec/docs/design/sandbox.md) (unsafe, but allows to use Panther in containers)
* `PANTHER_WEB_SERVER_DIR`: to change the project's document root (default to `public/`)
* `PANTHER_CHROME_DRIVER_BINARY`: to use another `chromedriver` binary, instead of relying on the ones already provided by Panther

## Docker Integration

Here is a minimal Docker image that can run Panthère:
Here is a minimal Docker image that can run Panther:

```
FROM php:latest

RUN apt-get update && apt-get install -y zlib1g-dev chromium && docker-php-ext-install zip
ENV PANTHERE_NO_SANDBOX 1
ENV PANTHER_NO_SANDBOX 1
```

Build it with `docker build . -t myproject`
Run it with `docker run -it -v "$PWD":/srv/myproject -w /srv/myproject myproject bin/phpunit`

## Travis CI Integration

Panthère will work out of the box with Travis if you add the Chrome addon. Here is a minimal `.travis.yml` file to run
Panthère tests:
Panther will work out of the box with Travis if you add the Chrome addon. Here is a minimal `.travis.yml` file to run
Panther tests:

```yaml
language: php
Expand All @@ -179,8 +179,8 @@ script:
```
## AppVeyor Integration

Panthère will work out of the box with AppVeyor as long as Google Chrome is installed. Here is a minimal `appveyor.yml`
file to run Panthère tests:
Panther will work out of the box with AppVeyor as long as Google Chrome is installed. Here is a minimal `appveyor.yml`
file to run Panther tests:

```yaml
build: false
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
build: false
platform: x86
clone_folder: c:\projects\symfony\panthere
clone_folder: c:\projects\symfony\panther

cache:
- '%LOCALAPPDATA%\Composer\files'
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "symfony/panthere",
"name": "symfony/panther",
"type": "library",
"description": "A browser testing and web scrapping library for PHP and Symfony.",
"keywords": ["scrapping", "E2E", "testing", "webdriver", "selenium", "symfony"],
Expand All @@ -26,10 +26,10 @@
"symfony/browser-kit": "4.1.0"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Panthere\\": "src/" }
"psr-4": { "Symfony\\Component\\Panther\\": "src/" }
},
"autoload-dev": {
"psr-4": { "Symfony\\Component\\Panthere\\Tests\\": "tests/" }
"psr-4": { "Symfony\\Component\\Panther\\Tests\\": "tests/" }
},
"extra": {
"branch-alias": {
Expand Down
4 changes: 2 additions & 2 deletions examples/basic.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* This file is part of the Panthère project.
* This file is part of the Panther project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
Expand All @@ -13,7 +13,7 @@

require __DIR__.'/../vendor/autoload.php'; // Composer's autoloader

$client = \Symfony\Component\Panthere\Client::createChromeClient();
$client = \Symfony\Component\Panther\Client::createChromeClient();
$crawler = $client->request('GET', 'http://api-platform.com'); // Yes, this website is 100% in JavaScript

$link = $crawler->selectLink('Support')->link();
Expand Down
Binary file added panther.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed panthere.png
Binary file not shown.
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ parameters:
# https://github.com/symfony/symfony/pull/27849
- '/Parameter #1 \$value of method Symfony\\Component\\DomCrawler\\Field\\ChoiceFormField::select\(\) expects string, array<int, string> given\./'
# Require a redesign of the underlying Symfony components
- '#Panthere\\[a-zA-Z\\]+::__construct\(\) does not call parent constructor from Symfony\\Component\\(BrowserKit|DomCrawler)\\[a-zA-Z]+\.#'
- '#Panther\\[a-zA-Z\\]+::__construct\(\) does not call parent constructor from Symfony\\Component\\(BrowserKit|DomCrawler)\\[a-zA-Z]+\.#'
22 changes: 11 additions & 11 deletions src/Client.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* This file is part of the Panthère project.
* This file is part of the Panther project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
Expand All @@ -11,7 +11,7 @@

declare(strict_types=1);

namespace Symfony\Component\Panthere;
namespace Symfony\Component\Panther;

use Facebook\WebDriver\WebDriver;
use Facebook\WebDriver\WebDriverBy;
Expand All @@ -22,13 +22,13 @@
use Symfony\Component\BrowserKit\Response;
use Symfony\Component\DomCrawler\Form;
use Symfony\Component\DomCrawler\Link;
use Symfony\Component\Panthere\Cookie\CookieJar;
use Symfony\Component\Panthere\DomCrawler\Crawler;
use Symfony\Component\Panthere\DomCrawler\Form as PanthereForm;
use Symfony\Component\Panthere\DomCrawler\Link as PanthereLink;
use Symfony\Component\Panthere\ProcessManager\BrowserManagerInterface;
use Symfony\Component\Panthere\ProcessManager\ChromeManager;
use Symfony\Component\Panthere\ProcessManager\SeleniumManager;
use Symfony\Component\Panther\Cookie\CookieJar;
use Symfony\Component\Panther\DomCrawler\Crawler;
use Symfony\Component\Panther\DomCrawler\Form as PantherForm;
use Symfony\Component\Panther\DomCrawler\Link as PantherLink;
use Symfony\Component\Panther\ProcessManager\BrowserManagerInterface;
use Symfony\Component\Panther\ProcessManager\ChromeManager;
use Symfony\Component\Panther\ProcessManager\SeleniumManager;

/**
* @author Kévin Dunglas <dunglas@gmail.com>
Expand Down Expand Up @@ -123,7 +123,7 @@ public function getServerParameter($key, $default = '')

public function click(Link $link)
{
if ($link instanceof PanthereLink) {
if ($link instanceof PantherLink) {
$link->getElement()->click();

return $this->crawler = $this->createCrawler();
Expand All @@ -134,7 +134,7 @@ public function click(Link $link)

public function submit(Form $form, array $values = [])
{
if ($form instanceof PanthereForm) {
if ($form instanceof PantherForm) {
$button = $form->getButton();
null === $button ? $form->getElement()->submit() : $button->click();

Expand Down
6 changes: 3 additions & 3 deletions src/Cookie/CookieJar.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* This file is part of the Panthère project.
* This file is part of the Panther project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
Expand All @@ -11,14 +11,14 @@

declare(strict_types=1);

namespace Symfony\Component\Panthere\Cookie;
namespace Symfony\Component\Panther\Cookie;

use Facebook\WebDriver\Cookie as WebDriverCookie;
use Facebook\WebDriver\WebDriver;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\BrowserKit\CookieJar as BaseCookieJar;
use Symfony\Component\BrowserKit\Response;
use Symfony\Component\Panthere\ExceptionThrower;
use Symfony\Component\Panther\ExceptionThrower;

/**
* @author Kévin Dunglas <dunglas@gmail.com>
Expand Down
6 changes: 3 additions & 3 deletions src/DomCrawler/Crawler.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* This file is part of the Panthère project.
* This file is part of the Panther project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
Expand All @@ -11,14 +11,14 @@

declare(strict_types=1);

namespace Symfony\Component\Panthere\DomCrawler;
namespace Symfony\Component\Panther\DomCrawler;

use Facebook\WebDriver\Exception\NoSuchElementException;
use Facebook\WebDriver\WebDriver;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverElement;
use Symfony\Component\DomCrawler\Crawler as BaseCrawler;
use Symfony\Component\Panthere\ExceptionThrower;
use Symfony\Component\Panther\ExceptionThrower;

/**
* @author Kévin Dunglas <dunglas@gmail.com>
Expand Down
6 changes: 3 additions & 3 deletions src/DomCrawler/Field/ChoiceFormField.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* This file is part of the Panthère project.
* This file is part of the Panther project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
Expand All @@ -11,12 +11,12 @@

declare(strict_types=1);

namespace Symfony\Component\Panthere\DomCrawler\Field;
namespace Symfony\Component\Panther\DomCrawler\Field;

use Facebook\WebDriver\WebDriverSelect;
use Facebook\WebDriver\WebDriverSelectInterface;
use Symfony\Component\DomCrawler\Field\ChoiceFormField as BaseChoiceFormField;
use Symfony\Component\Panthere\WebDriver\WebDriverCheckbox;
use Symfony\Component\Panther\WebDriver\WebDriverCheckbox;

/**
* @author Kévin Dunglas <dunglas@gmail.com>
Expand Down
Loading