1212use HeadlessChromium \Exception \CommunicationException ;
1313use HeadlessChromium \Exception \NoResponseAvailable ;
1414use HeadlessChromium \Exception \CommunicationException \ResponseHasError ;
15+ use HeadlessChromium \Exception \TargetDestroyed ;
1516use HeadlessChromium \PageUtils \PageEvaluation ;
1617use HeadlessChromium \PageUtils \PageNavigation ;
1718use HeadlessChromium \PageUtils \PageScreenshot ;
@@ -27,18 +28,35 @@ class Page
2728 */
2829 protected $ target ;
2930
31+ /**
32+ * @var FrameManager
33+ */
34+ protected $ frameManager ;
35+
3036 public function __construct (Target $ target , array $ frameTree )
3137 {
3238 $ this ->target = $ target ;
3339 $ this ->frameManager = new FrameManager ($ this , $ frameTree );
3440 }
3541
42+ /**
43+ * @return FrameManager
44+ */
45+ public function getFrameManager (): FrameManager
46+ {
47+ $ this ->assertNotClosed ();
48+
49+ return $ this ->frameManager ;
50+ }
51+
3652 /**
3753 * Get the session this page is attached to
3854 * @return Session
3955 */
4056 public function getSession (): Session
4157 {
58+ $ this ->assertNotClosed ();
59+
4260 return $ this ->target ->getSession ();
4361 }
4462
@@ -51,6 +69,8 @@ public function getSession(): Session
5169 */
5270 public function navigate ($ url )
5371 {
72+ $ this ->assertNotClosed ();
73+
5474 // make sure latest loaderId was pulled
5575 $ this ->getSession ()->getConnection ()->readData ();
5676
@@ -88,6 +108,8 @@ public function navigate($url)
88108 */
89109 public function evaluate (string $ expression )
90110 {
111+ $ this ->assertNotClosed ();
112+
91113 $ currentLoaderId = $ this ->frameManager ->getMainFrame ()->getLatestLoaderId ();
92114 $ reader = $ this ->getSession ()->sendMessage (
93115 new Message (
@@ -113,6 +135,8 @@ public function evaluate(string $expression)
113135 */
114136 public function getCurrentLifecycle ()
115137 {
138+ $ this ->assertNotClosed ();
139+
116140 $ this ->getSession ()->getConnection ()->readData ();
117141 return $ this ->frameManager ->getMainFrame ()->getLifeCycle ();
118142 }
@@ -133,6 +157,8 @@ public function getCurrentLifecycle()
133157 */
134158 public function hasLifecycleEvent (string $ event ): bool
135159 {
160+ $ this ->assertNotClosed ();
161+
136162 return array_key_exists ($ event , $ this ->getCurrentLifecycle ());
137163 }
138164
@@ -146,6 +172,8 @@ public function hasLifecycleEvent(string $event): bool
146172 */
147173 public function waitForReload ($ eventName = Page::LOAD , $ timeout = 30000 , $ loaderId = null )
148174 {
175+ $ this ->assertNotClosed ();
176+
149177 if (!$ loaderId ) {
150178 $ loaderId = $ loader = $ this ->frameManager ->getMainFrame ()->getLatestLoaderId ();
151179 }
@@ -197,6 +225,8 @@ private function waitForReloadGenerator($eventName, $loaderId)
197225 */
198226 public function screenshot (array $ options = []): PageScreenshot
199227 {
228+ $ this ->assertNotClosed ();
229+
200230 $ screenshotOptions = [];
201231
202232 // get format
@@ -265,4 +295,35 @@ public function screenshot(array $options = []): PageScreenshot
265295
266296 return new PageScreenshot ($ responseReader );
267297 }
298+
299+ /**
300+ * Request to close the page
301+ * @throws CommunicationException
302+ */
303+ public function close ()
304+ {
305+
306+ $ this ->assertNotClosed ();
307+
308+ $ this ->getSession ()
309+ ->getConnection ()
310+ ->sendMessage (
311+ new Message (
312+ 'Target.closeTarget ' ,
313+ ['targetId ' => $ this ->getSession ()->getTargetId ()]
314+ )
315+ );
316+
317+ // TODO return close waiter
318+ }
319+
320+ /**
321+ * Throws if the page was closed
322+ */
323+ private function assertNotClosed ()
324+ {
325+ if ($ this ->target ->isDestroyed ()) {
326+ throw new TargetDestroyed ('The page was closed and is not available anymore. ' );
327+ }
328+ }
268329}
0 commit comments