jmoo / chrome-react
Async, low-level client for the Chrome DevTools Protocol using ReactPHP
dev-master
2018-12-09 16:41 UTC
Requires
- php: ^7.1
- clue/block-react: ^1.3
- clue/buzz-react: ^2.3
- ratchet/pawl: ^0.3.2
- react/event-loop: ^0.4.3||^0.5.2||^1.0
- react/promise: ^2.7
Requires (Dev)
- amphp/amp: ^2.0
- amphp/react-adapter: ^1.1
- monolog/monolog: ^1.23
- phpunit/phpunit: ^6.3
This package is auto-updated.
Last update: 2025-03-19 22:41:32 UTC
README
Fully async, low-level client for the Chrome DevTools Protocol using ReactPHP
Warning: Experimental! Expect large breaking changes, instability, and lack of documentation until there is a tagged version
Installation
$ composer require jmoo/chrome-react
Getting Started
Running Chrome
$ chrome --headless --disable-gpu --remote-debugging-port=9222
Navigate to a page (synchronously)
The blocking client runs the event loop while awaiting completion of each task. This allows you to write normal synchronous code while still responding to asynchronous events.
$chrome = new \Jmoo\React\Chrome\Blocking\Client; $url = $chrome->new()->webSocketDebuggerUrl; $tab = $chrome->connect($url); $tab->Page->enable(); $tab->Page->navigate(['url' => 'https://www.chromium.org/']); $tab->disconnect();
Navigate to a page (asynchronously)
The async client returns Promises for each command.
$loop = \React\EventLoop\Factory::create(); $chrome = new \Jmoo\React\Chrome\Async\Client($loop); $chrome ->new() ->then(function ($page) use ($chrome) { return $chrome->connect($page->webSocketDebuggerUrl); }) ->then(function ($c) { return \React\Promise\all([ $c, $c->Page->enable(), $c->Page->navigate(['url' => 'https://www.google.com']) ]); }) ->then(function ($result) { list($c) = $result; $c->disconnect(); }); $loop->run();
Navigate to a page (coroutines)
The async client can be used with amphp coroutines using amphp/react-adapter
\Amp\Loop::run(function() { $chrome = new \Jmoo\React\Chrome\Async\Client(ReactAdapter::get()); $tabInfo = yield $chrome->new(); $tab = yield $chrome->connect($tabInfo->webSocketDebuggerUrl); yield $tab->Page->enable(); yield $tab->Page->navigate(['url' => 'https://news.ycombinator.com/']); $tab->disconnect(); });
Using an existing event loop with the blocking client
// any existing event loop $loop = \React\EventLoop\Factory::create(); // create a new async client with event loop $async = new \Jmoo\React\Chrome\Async\Client($loop); // create a new blocking client using async client $chrome = new \Jmoo\React\Chrome\Blocking\Client($async);
Usage
Configuration
# Default options $client = (new Client)->withOptions([ 'host' => '127.0.0.1', 'port' => 9222, 'ssl' => false, 'timeout' => 30 // blocking client only ]); # Using a custom event-loop and connector $asyncClient = new \Jmoo\React\Chrome\Async\Client($loop, $connector); $blockingClient = new \Jmoo\React\Chrome\Blocking\Client($asyncClient);
Domains
$client = new \Jmoo\React\Chrome\Blocking\Client; $c = $client->connect($client->new()->webSocketDebuggerUrl); // getting a domain accessor $page = $c->Page; // with magic method $page = $c->getDomain('Page'); // directly // enable events and retrieve multiple domain accessors at the same time list($page, $network, $log) = $c->enable(['Page', 'Network', 'Log']);
Methods
$client = new \Jmoo\React\Chrome\Blocking\Client; $c = $client->connect($client->new()->webSocketDebuggerUrl); // executing a method using the domain accessor $c->Page->navigate(['url' => 'http://jmoo.io']); // with magic method $c->Page->send('navigate', ['url' => 'http://jmoo.io']); // directly // without using domain accessor $c->send('Page.navigate', ['url' => 'http://jmoo.io']);
Events
$client = new \Jmoo\React\Chrome\Blocking\Client; $c = $client->connect($client->new()->webSocketDebuggerUrl); // events must be enabled $c->Page->enable(); $c->Page->on('domContentEventFired', function() use ($c) { $c->disconnect(); }); // pause execution until disconnect (blocking client only) $c->waitForDisconnect();
Sessions
$client = new \Jmoo\React\Chrome\Blocking\Client; $c = $client->connect($client->version()->webSocketDebuggerUrl); $target = $c->send('Target.createTarget', ['url' => 'about:blank']); $session = $c->createSession($target->targetId); $session->Page->enable();