-
Notifications
You must be signed in to change notification settings - Fork 209
waitForNavigation is never resolved #4
Comments
Without a code example, the only thing I can think of is to increase the navigation timeout: $puppeteer = new Puppeteer([
'read_timeout' => 65, // In seconds
]);
$puppeteer->launch()->newPage()->goto($url, [
'timeout' => 60000, // In milliseconds
]); Please, provide a reproducible example if your issue is not solved by this code. |
@nesk could you please provide an example of working
This snippet always throws the same error as reported above |
Ooh, thanks @eldair, and sorry @qnoox, there is a real issue here. I don't know how I didn't see it before… Here's what's happening internally: when an instruction is sent to Node, it is executed with the It's working for the majority of the cases, but here the Maybe I should provide a modifier allowing to execute an instruction without $page = (new Puppeteer)->launch()->newPage();
// The promise is returned instead of being awaited, due to the "lazy" modifier.
$navigationPromise = $page->lazy->waitForNavigation();
$page->goto('https://google.com');
$navigationPromise->then(function() {
var_dump('Navigation done!');
}); What do you think of this? Until it's fixed, you can use the options of the |
Did this ever get solved @nesk |
I'm starting to run into this problem a lot now too. |
any workaround for this? I click on a button which opens a new page in a new tab but browser pages doesnt update with this new one |
I'm starting to run into this problem, too |
For those looking for a workaround, I came out with this little jerry-rig with the help of Symfonys DomCrawler and CSS Selector, works for me at least. Just wrap $page = new WaitPageDecorator($browser->newPage()); Then you can: $page->waitContext()
->waitFor('selector.in-the[new=page]')
->tap('selector.in-the[new=page]'); class WaitPageDecorator
{
private Page $page;
private int $throttleThreshold;
private string $lastExecContextId;
public function __construct(Page $page, int $throttleThreshold = 2222500)
{
$this->page = $page;
$this->throttleThreshold = $throttleThreshold;
}
public function __call($name, $arguments)
{
if (substr($name, 0, 4) === 'wait') {
return call_user_func_array([$this, $name], $arguments);
}
return call_user_func_array([$this->page, $name], $arguments);
}
public function waitContext(): self
{
$execContextId = $this->waitExecContextId();
if (!isset($this->lastExecContextId)) {
$this->lastExecContextId = $execContextId;
}
while ($execContextId === $this->lastExecContextId) {
$this->waitThrottle();
$execContextId = $this->waitExecContextId();
}
return $this;
}
public function waitFor(string $selector, int $timeout = 30): self
{
// TODO: Implement timeout
while (!$this->waitContains($selector)) {
$this->waitThrottle();
}
return $this;
}
public function waitEval(string $selector, string $jsFuncBody): string
{
return $this->page->querySelectorEval($selector, JsFunction::createWithParameters(['elem'])->body($jsFuncBody));
}
public function waitContains(string $selector): bool
{
$bodyHtml = $this->waitEval('body', 'return elem.innerHTML');
$crawler = new Crawler($bodyHtml);
return $crawler->filter($selector)->count() > 0;
}
private function waitExecContextId(): string
{
/** @var ExecutionContext $context */
$context = $this->page->mainFrame()->executionContext();
return $context->getResourceIdentity()->uniqueIdentifier();
}
private function waitThrottle(): void
{
usleep($this->throttleThreshold);
}
} Maybe you will need to adjust the throttling threshold. |
@leocavalcante, thank you but your example is not working |
Any ETA for a fix? |
That would be great. We could use the Amp's event loop and write code like this: public function testExample()
{
$puppeteer = new Puppeteer();
$browser = yield $puppeteer->launch();
$page = yield $browser->newPage();
$page->click('html form button');
yield $page->waitForNavigation();
yield $browser->close();
}); |
I also get this when I click on something and then wait for the new page to load. In puppeteer you can wrap several commands in an await (see https://stackoverflow.com/a/52212395) - could we have a function that takes a closure and then that becomes a promise in JS? |
I solved this by some trick.
|
Hello,
Issue:
Tried passing a waitUntil option after a while there is an error.
Error Message:
Uncaught ExtractrIo\Rialto\Exceptions\Node\FatalException: Navigation Timeout Exceeded: 30000ms exceeded.
Code:
$page->waitForNavigation([ 'waitUntil' => 'networkidle0', ]);
Why was the waitUntil used:
Wanted to add in a wait as i am taking screenshots of a lot of pages and some screenshot does not
return the data for that page as it does not have time to load 100%.
Might be related not sure:
puppeteer/puppeteer#257
Might you have any other solutions to this issue?
Thank you in advance.
The text was updated successfully, but these errors were encountered: