Skip to content

Commit 00c250d

Browse files
committed
feat: remove ChromeDriver and geckodriver from the repo, use native installations instead
1 parent ddce715 commit 00c250d

File tree

5 files changed

+119
-86
lines changed

5 files changed

+119
-86
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
/composer.lock
66
/phpunit.xml
77
/vendor/
8+
/drivers/
9+
/screen.png

README.md

Lines changed: 79 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ all the features you need to test your apps. It will sound familiar if you have
1515
as the API is exactly the same!
1616
Keep in mind that Panther can be used in every PHP project, as it is a standalone library.
1717

18-
Panther automatically finds your local installation of Chrome or Firefox and launches them (thanks to [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) and [GeckoDriver](https://github.com/mozilla/geckodriver)),
19-
so you don't need to install anything on your computer, neither Selenium server nor any other obscure driver.
18+
Panther automatically finds your local installation of Chrome or Firefox and launches them,
19+
so you don't need to install anything else on your computer, a Selenium server is not needed!
2020

2121
In test mode, Panther automatically starts your application using [the PHP built-in web-server](http://php.net/manual/en/features.commandline.webserver.php).
2222
You can focus on writing your tests or web-scraping scenario and Panther will take care of everything else.
@@ -27,28 +27,57 @@ Unlike testing and web scraping libraries you're used to, Panther:
2727

2828
* executes the JavaScript code contained in webpages
2929
* supports everything that Chrome (or Firefox) implements
30-
* allows screenshots taking
30+
* allows taking screenshots
3131
* can wait for asynchronously loaded elements to show up
3232
* lets you run your own JS code or XPath queries in the context of the loaded page
3333
* supports custom [Selenium server](https://www.seleniumhq.org) installations
3434
* supports remote browser testing services including [SauceLabs](https://saucelabs.com/) and [BrowserStack](https://www.browserstack.com/)
3535

3636
## Documentation
3737

38-
### Install
38+
### Installing Panther
3939

4040
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 in a production environment:
4141

4242
composer req symfony/panther
4343

4444
composer req --dev symfony/panther
4545

46-
**Warning:** On \*nix systems, the `unzip` command must be installed or you will encounter an error similar to `RuntimeException: sh: 1: exec: /app/vendor/symfony/panther/src/ProcessManager/../../chromedriver-bin/chromedriver_linux64: Permission denied` (or `chromedriver_linux64: not found`).
46+
**Warning:** On \*nix systems, the `unzip` command must be installed, or you will encounter an error similar to `RuntimeException: sh: 1: exec: /app/vendor/symfony/panther/src/ProcessManager/../../chromedriver-bin/chromedriver_linux64: Permission denied` (or `chromedriver_linux64: not found`).
4747
The underlying reason is that PHP's `ZipArchive` doesn't preserve UNIX executable permissions.
4848

49+
### Installing ChromeDriver and geckodriver
50+
51+
Panther uses the WebDriver protocol to control the browser used to crawl websites.
52+
53+
On all systems, you can use `dbrekelmans/browser-driver-installer` to install ChromeDriver and geckodriver locally:
54+
55+
composer require --dev dbrekelmans/bdi
56+
vendor/bin/bdi detect drivers
57+
58+
Panther will detect and use automatically drivers stored in the `drivers/` directory.
59+
60+
Alternatively, you can use the package manager of your operating system to install them.
61+
62+
On Ubuntu, run:
63+
64+
apt-get install chromium-chromedriver firefox-geckodriver
65+
66+
On Mac, using [Homebrew](https://brew.sh):
67+
68+
brew install chromedriver geckodriver
69+
70+
On Windows, using [chocolatey](https://chocolatey.org):
71+
72+
choco install chromedriver selenium-gecko-driver
73+
74+
Finally, you can download manually [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) (for Chromium or Chrome)
75+
and [GeckoDriver](https://github.com/mozilla/geckodriver) (for Firefox) and put them anywhere in your `PATH`
76+
or in the `drivers/` directory of your project.
77+
4978
#### Registering the PHPUnit Extension
5079

51-
If you intend to use Panther to test your application, we strongly recommended to register the Panther PHPUnit extension.
80+
If you intend to use Panther to test your application, we strongly recommend registering the Panther PHPUnit extension.
5281
While not strictly mandatory, this extension dramatically improves the testing experience by boosting the performance and
5382
allowing to use the [interactive debugging mode](#interactive-mode).
5483

@@ -81,11 +110,13 @@ This listener will start the web server on demand like previously, but it will s
81110
```php
82111
<?php
83112

113+
use Symfony\Component\Panther\Client;
114+
84115
require __DIR__.'/vendor/autoload.php'; // Composer's autoloader
85116

86-
$client = \Symfony\Component\Panther\Client::createChromeClient();
117+
$client = Client::createChromeClient();
87118
// Or, if you care about the open web and prefer to use Firefox
88-
$client = \Symfony\Component\Panther\Client::createFirefoxClient();
119+
$client = Client::createFirefoxClient();
89120

90121
$client->request('GET', 'https://api-platform.com'); // Yes, this website is 100% written in JavaScript
91122
$client->clickLink('Get started');
@@ -103,7 +134,7 @@ $client->takeScreenshot('screen.png'); // Yeah, screenshot!
103134

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

108139
If you are testing a Symfony application, `PantherTestCase` automatically extends [the `WebTestCase` class](https://symfony.com/doc/current/testing.html#functional-tests).
109140
It means you can easily create functional tests, which can directly execute the kernel of your application and access all
@@ -243,11 +274,11 @@ class ChatTest extends PantherTestCase
243274

244275
### Checking the State of the WebDriver Connection
245276

246-
Use the `Client::ping()` method to check if the WebDriver connection is still active (useful for long running tasks).
277+
Use the `Client::ping()` method to check if the WebDriver connection is still active (useful for long-running tasks).
247278

248279
## Additional Documentation
249280

250-
Since Panther implements the API of popular libraries, it already has extensive documentation:
281+
Since Panther implements the API of popular libraries, it already has an extensive documentation:
251282

252283
* For the `Client` class, read [the BrowserKit documentation](https://symfony.com/doc/current/components/browser_kit.html)
253284
* For the `Crawler` class, read [the DomCrawler documentation](https://symfony.com/doc/current/components/dom_crawler.html)
@@ -257,7 +288,7 @@ Since Panther implements the API of popular libraries, it already has extensive
257288

258289
The following environment variables can be set to change some Panther's behaviour:
259290

260-
* `PANTHER_NO_HEADLESS`: to disable browser's headless mode (will display the testing window, useful to debug)
291+
* `PANTHER_NO_HEADLESS`: to disable the browser's headless mode (will display the testing window, useful to debug)
261292
* `PANTHER_WEB_SERVER_DIR`: to change the project's document root (default to `./public/`, relative paths **must start** by `./`)
262293
* `PANTHER_WEB_SERVER_PORT`: to change the web server's port (default to `9080`)
263294
* `PANTHER_WEB_SERVER_ROUTER`: to use a web server router script which is run at the start of each HTTP request
@@ -267,13 +298,11 @@ The following environment variables can be set to change some Panther's behaviou
267298
#### Chrome-specific Environment Variables
268299

269300
* `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)
270-
* `PANTHER_CHROME_DRIVER_BINARY`: to use another `chromedriver` binary, instead of relying on the ones already provided by Panther
271301
* `PANTHER_CHROME_ARGUMENTS`: to customize Chrome arguments. You need to set `PANTHER_NO_HEADLESS` to fully customize.
272302
* `PANTHER_CHROME_BINARY`: to use another `google-chrome` binary
273303

274304
#### Firefox-specific Environment Variables
275305

276-
* `PANTHER_GECKO_DRIVER_BINARY`: to use another `geckodriver` binary, instead of relying on the ones already provided by Panther
277306
* `PANTHER_FIREFOX_ARGUMENTS`: to customize Firefox arguments. You need to set `PANTHER_NO_HEADLESS` to fully customize.
278307
* `PANTHER_FIREFOX_BINARY`: to use another `firefox` binary
279308

@@ -332,29 +361,29 @@ To force Chrome to accept invalid and self-signed certificates, set the followin
332361

333362
### Docker Integration
334363

335-
Here is a minimal Docker image that can run Panther:
364+
Here is a minimal Docker image that can run Panther with both Chrome and Firefox:
336365

337-
```
338-
FROM php:latest
366+
```Dockerfile
367+
FROM php:alpine
339368

340-
RUN apt-get update && apt-get install -y libzip-dev zlib1g-dev chromium && docker-php-ext-install zip
369+
# Chromium and ChromeDriver
341370
ENV PANTHER_NO_SANDBOX 1
342371
# Not mandatory, but recommended
343372
ENV PANTHER_CHROME_ARGUMENTS='--disable-dev-shm-usage'
373+
RUN apk add --no-cache chromium chromium-chromedriver
374+
375+
# Firefox and GeckoDriver (optional)
376+
ARG GECKODRIVER_VERSION=0.28.0
377+
RUN apk add --no-cache firefox libzip-dev; \
378+
docker-php-ext-install zip
379+
RUN wget -q https://github.com/mozilla/geckodriver/releases/download/v$GECKODRIVER_VERSION/geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz; \
380+
tar -zxf geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz -C /usr/bin; \
381+
rm geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz
344382
```
345383

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

349-
If you are using **Alpine Linux**, you may need to use another `chromedriver` binary.
350-
351-
```
352-
RUN apk add --no-cache \
353-
chromium \
354-
chromium-chromedriver
355-
ENV PANTHER_CHROME_DRIVER_BINARY /usr/lib/chromium/chromedriver
356-
```
357-
358387
### GitHub Actions Integration
359388

360389
Panther works out of the box with [GitHub Actions](https://help.github.com/en/actions).
@@ -374,7 +403,7 @@ jobs:
374403
- uses: actions/checkout@v2
375404

376405
- name: Install dependencies
377-
run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
406+
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
378407

379408
- name: Run test suite
380409
run: vendor/bin/phpunit
@@ -393,53 +422,34 @@ addons:
393422
firefox: latest
394423
395424
php:
396-
- 7.4
425+
- 8.0
397426
398427
script:
399-
- phpunit
428+
- vendor/bin/phpunit
400429
```
401430

402431
### Gitlab CI Integration
403432

404433
Here is a minimal `.gitlab-ci.yml` file to run Panther tests with [Gitlab CI](https://docs.gitlab.com/ee/ci/):
405434

406435
```yaml
407-
image: ubuntu:bionic
408-
409-
services:
410-
- postgres:11
411-
412-
variables:
413-
POSTGRES_PASSWORD: root
414-
POSTGRES_USER: root
415-
POSTGRES_DB: db
436+
image: ubuntu
416437
417438
before_script:
418-
- apt-get update
419-
- apt-get install software-properties-common -y
420-
- ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
421-
- apt-get install curl wget php php-cli php7.2 php7.2-common php7.2-curl php7.2-pgsql php7.2-mysql php7.2-intl php7.2-gd php7.2-xml php7.2-opcache php7.2-mbstring php7.2-zip libfontconfig1 fontconfig libxrender-dev libfreetype6 libxrender1 zlib1g-dev xvfb chromium-browser chromium-chromedriver -y -qq
422-
- export PANTHER_CHROME_DRIVER_BINARY="/usr/lib/chromium-browser/chromedriver"
423-
- export PANTHER_NO_SANDBOX=1
424-
- export PANTHER_WEB_SERVER_PORT=9080
425-
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
426-
- php composer-setup.php --install-dir=/usr/local/bin --filename=composer
427-
- php -r "unlink('composer-setup.php');"
428-
- composer
429-
- chromedriver --version
430-
- php -v
431-
- php -m
432-
- composer install --ignore-platform-reqs
433-
- bin/console doctrine:schema:update --force
434-
- bin/console doctrine:schema:validate
435-
- bin/console doctrine:fixtures:load
436-
437-
stages:
438-
- test
439+
- apt-get update
440+
- apt-get install software-properties-common -y
441+
- ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
442+
- apt-get install curl wget php php-cli php7.4 php7.4-common php7.4-curl php7.4-intl php7.4-xml php7.4-opcache php7.4-mbstring php7.4-zip libfontconfig1 fontconfig libxrender-dev libfreetype6 libxrender1 zlib1g-dev xvfb chromium-chromedriver firefox-geckodriver -y -qq
443+
- export PANTHER_NO_SANDBOX=1
444+
- export PANTHER_WEB_SERVER_PORT=9080
445+
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
446+
- php composer-setup.php --install-dir=/usr/local/bin --filename=composer
447+
- php -r "unlink('composer-setup.php');"
448+
- composer install
439449
440450
test:
441451
script:
442-
- vendor/bin/simple-phpunit tests/Controller/E2eTest.php
452+
- vendor/bin/phpunit
443453
```
444454

445455
### AppVeyor Integration
@@ -457,9 +467,9 @@ cache:
457467
458468
install:
459469
- ps: Set-Service wuauserv -StartupType Manual
460-
- cinst -y php composer googlechrome
470+
- cinst -y php composer googlechrome chromedriver firfox selenium-gecko-driver
461471
- refreshenv
462-
- cd c:\tools\php74
472+
- cd c:\tools\php80
463473
- copy php.ini-production php.ini /Y
464474
- echo date.timezone="UTC" >> php.ini
465475
- echo extension_dir=ext >> php.ini
@@ -477,7 +487,10 @@ test_script:
477487

478488
### Usage with Other Testing Tools
479489

480-
If you want to use Panther with other testing tools like [LiipFunctionalTestBundle](https://github.com/liip/LiipFunctionalTestBundle) or if you just need to use a different base class, Panther has got you covered. It provides you with the `Symfony\Component\Panther\PantherTestCaseTrait` and you can use it to enhance your existing test-infrastructure with some Panther awesomeness:
490+
If you want to use Panther with other testing tools like [LiipFunctionalTestBundle](https://github.com/liip/LiipFunctionalTestBundle)
491+
or if you just need to use a different base class, Panther has got you covered.
492+
It provides you with the `Symfony\Component\Panther\PantherTestCaseTrait` and you can use it to enhance your existing
493+
test-infrastructure with some Panther awesomeness:
481494

482495
```php
483496
<?php
@@ -522,4 +535,5 @@ If you like this software, help save the (real) panthers by [donating to the Pan
522535

523536
Created by [Kévin Dunglas](https://dunglas.fr). Sponsored by [Les-Tilleuls.coop](https://les-tilleuls.coop).
524537

525-
Panther is built on top of [PHP WebDriver](https://github.com/php-webdriver/php-webdriver) and [several other FOSS libraries](https://symfony.com/blog/introducing-symfony-panther-a-browser-testing-and-web-scrapping-library-for-php#thank-you-open-source). It has been inspired by [Nightwatch.js](http://nightwatchjs.org/), a WebDriver-based testing tool for JavaScript.
538+
Panther is built on top of [PHP WebDriver](https://github.com/php-webdriver/php-webdriver) and [several other FOSS libraries](https://symfony.com/blog/introducing-symfony-panther-a-browser-testing-and-web-scrapping-library-for-php#thank-you-open-source).
539+
It has been inspired by [Nightwatch.js](http://nightwatchjs.org/), a WebDriver-based testing tool for JavaScript.

examples/basic.php

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,21 @@
1111

1212
declare(strict_types=1);
1313

14+
use Symfony\Component\Panther\Client;
15+
1416
require __DIR__.'/../vendor/autoload.php'; // Composer's autoloader
1517

16-
$client = \Symfony\Component\Panther\Client::createChromeClient();
17-
$crawler = $client->request('GET', 'http://api-platform.com'); // Yes, this website is 100% in JavaScript
18+
$client = Client::createChromeClient();
19+
// Or, if you care about the open web and prefer to use Firefox
20+
//$client = Client::createFirefoxClient();
1821

19-
$link = $crawler->selectLink('Support')->link();
20-
$crawler = $client->click($link);
22+
$client->request('GET', 'https://api-platform.com'); // Yes, this website is 100% written in JavaScript
23+
$client->clickLink('Get started');
2124

22-
// Wait for an element to be rendered
23-
$client->waitFor('.support');
25+
// Wait for an element to be present in the DOM (even if hidden)
26+
$crawler = $client->waitFor('#installing-the-framework');
27+
// Alternatively, wait for an element to be visible
28+
$crawler = $client->waitForVisibility('#installing-the-framework');
2429

25-
echo $crawler->filter('.support')->text();
30+
echo $crawler->filter('#installing-the-framework')->text();
2631
$client->takeScreenshot('screen.png'); // Yeah, screenshot!

src/ProcessManager/ChromeManager.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Facebook\WebDriver\Remote\DesiredCapabilities;
1818
use Facebook\WebDriver\Remote\RemoteWebDriver;
1919
use Facebook\WebDriver\WebDriver;
20+
use Symfony\Component\Process\ExecutableFinder;
2021
use Symfony\Component\Process\Process;
2122

2223
/**
@@ -30,6 +31,9 @@ final class ChromeManager implements BrowserManagerInterface
3031
private $arguments;
3132
private $options;
3233

34+
/**
35+
* @throws \RuntimeException
36+
*/
3337
public function __construct(?string $chromeDriverBinary = null, ?array $arguments = null, array $options = [])
3438
{
3539
$this->options = array_merge($this->getDefaultOptions(), $options);
@@ -72,20 +76,22 @@ public function quit(): void
7276
$this->process->stop();
7377
}
7478

79+
/**
80+
* @throws \RuntimeException
81+
*/
7582
private function findChromeDriverBinary(): string
7683
{
7784
if ($binary = $_SERVER['PANTHER_CHROME_DRIVER_BINARY'] ?? null) {
85+
@trigger_error('The "PANTHER_CHROME_DRIVER_BINARY" environment variable is deprecated since Panther 0.9, add ChromeDriver to your PATH instead.', E_USER_DEPRECATED);
86+
7887
return $binary;
7988
}
8089

81-
switch (PHP_OS_FAMILY) {
82-
case 'Windows':
83-
return __DIR__.'/../../chromedriver-bin/chromedriver.exe';
84-
case 'Darwin':
85-
return __DIR__.'/../../chromedriver-bin/chromedriver_mac64';
86-
default:
87-
return __DIR__.'/../../chromedriver-bin/chromedriver_linux64';
90+
if ($binary = (new ExecutableFinder())->find('chromedriver', null, ['./drivers'])) {
91+
return $binary;
8892
}
93+
94+
throw new \RuntimeException('"chromedriver" binary not found. Install it using the package manager of your operating system or by running "composer require --dev dbrekelmans/bdi && vendor/bin/bdi detect drivers".');
8995
}
9096

9197
private function getDefaultArguments(): array

0 commit comments

Comments
 (0)