Skip to content

Commit 91c723e

Browse files
committed
fix #38 - destroyed target trying to initialize
1 parent 7c51a03 commit 91c723e

File tree

6 files changed

+136
-21
lines changed

6 files changed

+136
-21
lines changed

src/Browser.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,8 @@ public function __construct(Connection $connection)
3838
// listen for target created
3939
$this->connection->on(Connection::EVENT_TARGET_CREATED, function (array $params) {
4040

41-
// create a session for the target
42-
$session = $this->connection->createSession($params['targetInfo']['targetId']);
43-
4441
// create and store the target
45-
$this->targets[$params['targetInfo']['targetId']] = new Target(
46-
$params['targetInfo'],
47-
$session
48-
);
42+
$this->targets[$params['targetInfo']['targetId']] = new Target($params['targetInfo'], $this->connection);
4943
});
5044

5145
// listen for target info changed
@@ -168,4 +162,12 @@ public function getTarget($targetId)
168162
}
169163
return $this->targets[$targetId];
170164
}
165+
166+
/**
167+
* @return Target[]
168+
*/
169+
public function getTargets()
170+
{
171+
return array_values($this->targets);
172+
}
171173
}

src/Communication/Target.php

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,25 @@ class Target
1919
*/
2020
protected $session;
2121

22+
/**
23+
* @var Connection
24+
*/
25+
private $connection;
26+
27+
/**
28+
* @var bool
29+
*/
2230
protected $destroyed = false;
2331

2432
/**
2533
* Target constructor.
2634
* @param array $targetInfo
2735
* @param Session $session
2836
*/
29-
public function __construct(array $targetInfo, Session $session)
37+
public function __construct(array $targetInfo, Connection $connection)
3038
{
3139
$this->targetInfo = $targetInfo;
32-
$this->session = $session;
40+
$this->connection = $connection;
3341
}
3442

3543
/**
@@ -40,6 +48,12 @@ public function getSession(): Session
4048
if ($this->destroyed) {
4149
throw new TargetDestroyed('The target was destroyed.');
4250
}
51+
52+
// if not already done, create a session for the target
53+
if (!$this->session) {
54+
$this->session = $session = $this->connection->createSession($this->getTargetInfo('targetId'));
55+
}
56+
4357
return $this->session;
4458
}
4559

@@ -52,8 +66,12 @@ public function destroy()
5266
if ($this->destroyed) {
5367
throw new TargetDestroyed('The target was already destroyed.');
5468
}
55-
$this->session->destroy();
56-
$this->session = null;
69+
70+
if ($this->session) {
71+
$this->session->destroy();
72+
$this->session = null;
73+
}
74+
5775
$this->destroyed = true;
5876
}
5977

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<html>
2+
<body>
3+
<h1>Hello world</h1>
4+
<script>
5+
navigator.serviceWorker.register('./empty.js');
6+
</script>
7+
8+
</body>
9+
</html>

test/resources/static-web/empty.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(function() {
2+
var a = 'a';
3+
})();

test/suites/HttpBrowsingTest.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
/**
3+
* @license see LICENSE
4+
*/
5+
6+
namespace HeadlessChromium\Test;
7+
8+
use HeadlessChromium\Browser;
9+
use HeadlessChromium\BrowserFactory;
10+
use HeadlessChromium\Communication\Connection;
11+
12+
/**
13+
* @covers \HeadlessChromium\Browser
14+
* @covers \HeadlessChromium\PageUtils\CookiesGetter
15+
* @covers \HeadlessChromium\Page
16+
*/
17+
class HttpBrowsingTest extends HttpEnabledTestCase
18+
{
19+
20+
/**
21+
* @var Browser\ProcessAwareBrowser
22+
*/
23+
public static $browser;
24+
25+
public function setUp()
26+
{
27+
parent::setUp();
28+
$factory = new BrowserFactory();
29+
self::$browser = $factory->createBrowser();
30+
}
31+
32+
public function tearDown()
33+
{
34+
parent::tearDown();
35+
self::$browser->close();
36+
}
37+
38+
private function openSitePage($file)
39+
{
40+
$page = self::$browser->createPage();
41+
$page->navigate($this->sitePath($file))->waitForNavigation();
42+
43+
return $page;
44+
}
45+
46+
47+
/**
48+
* @link https://github.com/chrome-php/headless-chromium-php/issues/38
49+
*/
50+
public function testServiceWorkerInstantlyDestroying()
51+
{
52+
$factory = new BrowserFactory();
53+
$browser = $factory->createBrowser();
54+
55+
$page = $browser->createPage();
56+
$page->navigate($this->sitePath('create-and-destroy-target.html'))->waitForNavigation();
57+
58+
$page = $browser->createPage();
59+
$page->navigate($this->sitePath('create-and-destroy-target.html'))->waitForNavigation();
60+
61+
// helper to track that service worker was created
62+
$helper = new \stdClass();
63+
$helper->created = false;
64+
$helper->targetId = null;
65+
$helper->destroyed = false;
66+
67+
// track created
68+
$page->getSession()->getConnection()->on(Connection::EVENT_TARGET_CREATED, function ($e) use ($helper) {
69+
if (isset($e['targetInfo']['type']) && $e['targetInfo']['type'] == 'service_worker') {
70+
$helper->created = true;
71+
$helper->targetId = $e['targetInfo']['targetId'];
72+
}
73+
});
74+
75+
// track destroyed
76+
$page->getSession()->getConnection()->on(Connection::EVENT_TARGET_DESTROYED, function ($e) use ($helper) {
77+
if ($e['targetId'] == $helper->targetId) {
78+
$helper->destroyed = true;
79+
}
80+
});
81+
82+
sleep(1);
83+
84+
// do something to trigger service worker create/destroy
85+
$page->evaluate('document.language')->getReturnValue();
86+
87+
// assert created/destroyed
88+
$this->assertTrue($helper->created);
89+
$this->assertTrue($helper->destroyed);
90+
// Note: if that stops to assert, it could mean that chrome changed the way it works and that this test is
91+
// no longer required
92+
}
93+
}

test/suites/PageTest.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,6 @@
1818
class PageTest extends BaseTestCase
1919
{
2020

21-
public function testPage()
22-
{
23-
$connection = new Connection(new MockSocket());
24-
$session = new Session('foo', 'bar', $connection);
25-
$target = new Target([], $session);
26-
$page = new Page($target, []);
27-
28-
$this->assertSame($session, $page->getSession());
29-
}
30-
3121
public function testSetViewport()
3222
{
3323
$factory = new BrowserFactory();

0 commit comments

Comments
 (0)