@@ -50,16 +50,24 @@ class PageNavigation
5050 */
5151 protected $ page ;
5252
53+ /**
54+ * @var bool
55+ */
56+ protected $ strict ;
57+
5358 /**
5459 * PageNavigation constructor.
5560 * @param Page $page
5661 * @param string $url
62+ * @param bool $strict by default this method will wait for the page to load even if a new navigation occurs
63+ * (ie: a new loader replaced the initial navigation). Passing $string to true will make the navigation to fail
64+ * if a new loader is generated
65+ *
5766 * @throws Exception\CommunicationException
5867 * @throws Exception\CommunicationException\CannotReadResponse
5968 * @throws Exception\CommunicationException\InvalidResponse
60- * @throws Exception\NoResponseAvailable
6169 */
62- public function __construct (Page $ page , string $ url )
70+ public function __construct (Page $ page , string $ url, bool $ strict = false )
6371 {
6472
6573 // make sure latest loaderId was pulled
@@ -76,6 +84,7 @@ public function __construct(Page $page, string $url)
7684 $ this ->page = $ page ;
7785 $ this ->frame = $ page ->getFrameManager ()->getMainFrame ();
7886 $ this ->url = $ url ;
87+ $ this ->strict = $ strict ;
7988 }
8089
8190 /**
@@ -96,7 +105,7 @@ public function __construct(Page $page, string $url)
96105 * ```
97106 *
98107 * @param string $eventName
99- * @param int $timeout
108+ * @param int $timeout time in ms to wait for the navigation to complete. Default 30000 (30 seconds)
100109 * @return mixed|null
101110 * @throws Exception\CommunicationException\CannotReadResponse
102111 * @throws Exception\CommunicationException\InvalidResponse
@@ -105,15 +114,19 @@ public function __construct(Page $page, string $url)
105114 * @throws NavigationExpired
106115 * @throws ResponseHasError
107116 */
108- public function waitForNavigation ($ eventName = Page::LOAD , $ timeout = 30000 )
117+ public function waitForNavigation ($ eventName = Page::LOAD , int $ timeout = null )
109118 {
119+ if (null === $ timeout ) {
120+ $ timeout = 30000 ;
121+ }
110122 return Utils::tryWithTimeout ($ timeout * 1000 , $ this ->navigationComplete ($ eventName ));
111123 }
112124
113125 /**
114126 * To be used with @see Utils::tryWithTimeout
115127 *
116- * @param $eventName
128+ * @param string $eventName
129+ *
117130 * @return bool|\Generator
118131 * @throws Exception\CommunicationException\CannotReadResponse
119132 * @throws Exception\CommunicationException\InvalidResponse
@@ -126,6 +139,7 @@ private function navigationComplete($eventName)
126139 $ delay = 500 ;
127140
128141 while (true ) {
142+ // read the response only if it was not read already
129143 if (!$ this ->navigateResponseReader ->hasResponse ()) {
130144 $ this ->navigateResponseReader ->checkForResponse ();
131145 if ($ this ->navigateResponseReader ->hasResponse ()) {
@@ -163,9 +177,14 @@ private function navigationComplete($eventName)
163177
164178 // else if a new loader is present that means that a new navigation started
165179 } else {
166- throw new NavigationExpired (
167- 'The page has navigated to an other page and this navigation expired '
168- );
180+ // if strict then throw or else replace the old navigation with the new one
181+ if ($ this ->strict ) {
182+ throw new NavigationExpired (
183+ 'The page has navigated to an other page and this navigation expired '
184+ );
185+ } else {
186+ $ this ->currentLoaderId = $ this ->frame ->getLatestLoaderId ();
187+ }
169188 }
170189
171190 $ this ->page ->getSession ()->getConnection ()->readData ();
0 commit comments