[Bug]: AwaitableWebpage::click times out when the next page is slow to load
What Happened
When using ->click() or ->press() within a browser test, if the element clicked causes a navigation and the next page takes >5s to load, the action fails (even though the element was successfully clicked)
This is possibly an issue with Playwright but I'm starting here as I'm not as familiar with that side of things.
In my example the test fails at the click line:
FAILED Tests\Browser\WelcomePageTest > clicking on button
Execution context was destroyed, most likely because of a navigation A screenshot of the page has been saved to [Tests/Browser/Screenshots/clicking_on_button].
at tests/Browser/WelcomePageTest.php:4
1▕ <?php
2▕ test('clicking on button', function (): void {
3▕ visit('/')
➜ 4▕ ->click('Click here!')
5▕ ->assertSee('Hello, World!');
6▕ });
However the screenshot produced shows the loaded "Hello, World!" page, so it appears that the test should be successful. I put a dump in the sendMessage method and saw that it was repeatedly sending the click command to Playwright, given the navigation already occurred these later calls likely didn't find the element to click on.
PHPUnit\Framework\ExpectationFailedException^ {#4035
#message: "Timeout 1000ms exceeded."
#code: 0
#file: "/var/www/html/vendor/pestphp/pest-plugin-browser/src/Playwright/Client.php"
#line: 101
#serializableTrace: array:30 [
0 => array:3 [
"function" => "execute"
"class" => "Pest\Browser\Playwright\Client"
"type" => "->"
]
1 => array:3 [
"file" => "/var/www/html/vendor/pestphp/pest-plugin-browser/src/Playwright/Concerns/InteractsWithPlaywright.php"
"line" => 105
"function" => "iterator_to_array"
]
2 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest-plugin-browser/src/Playwright/Locator.php"
"line" => 137
"function" => "processVoidResponse"
"class" => "Pest\Browser\Playwright\Locator"
"type" => "->"
]
3 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest-plugin-browser/src/Api/Concerns/InteractsWithElements.php"
"line" => 169
"function" => "click"
"class" => "Pest\Browser\Playwright\Locator"
"type" => "->"
]
4 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest-plugin-browser/src/Api/AwaitableWebpage.php"
"line" => 55
"function" => "press"
"class" => "Pest\Browser\Api\Webpage"
"type" => "->"
]
5 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest-plugin-browser/src/Playwright/Playwright.php"
"line" => 196
"function" => "Pest\Browser\Api\{closure}"
"class" => "Pest\Browser\Api\AwaitableWebpage"
"type" => "->"
]
6 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest-plugin-browser/src/Execution.php"
"line" => 149
"function" => "usingTimeout"
"class" => "Pest\Browser\Playwright\Playwright"
"type" => "::"
]
7 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest-plugin-browser/src/Api/AwaitableWebpage.php"
"line" => 53
"function" => "waitForExpectation"
"class" => "Pest\Browser\Execution"
"type" => "->"
]
8 => array:5 [
"file" => "/var/www/html/tests/Browser/AdminDashboardBulkActionsTest.php"
"line" => 71
"function" => "__call"
"class" => "Pest\Browser\Api\AwaitableWebpage"
"type" => "->"
]
9 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest/src/Factories/TestCaseMethodFactory.php"
"line" => 168
"function" => "{closure}"
"class" => "P\Tests\Browser\AdminDashboardBulkActionsTest"
"type" => "->"
]
10 => array:3 [
"function" => "Pest\Factories\{closure}"
"class" => "P\Tests\Browser\AdminDashboardBulkActionsTest"
"type" => "->"
]
11 => array:3 [
"file" => "/var/www/html/vendor/pestphp/pest/src/Concerns/Testable.php"
"line" => 429
"function" => "call_user_func_array"
]
12 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest/src/Support/ExceptionTrace.php"
"line" => 26
"function" => "Pest\Concerns\{closure}"
"class" => "P\Tests\Browser\AdminDashboardBulkActionsTest"
"type" => "->"
]
13 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest/src/Concerns/Testable.php"
"line" => 429
"function" => "ensure"
"class" => "Pest\Support\ExceptionTrace"
"type" => "::"
]
14 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest/src/Concerns/Testable.php"
"line" => 331
"function" => "__callClosure"
"class" => "P\Tests\Browser\AdminDashboardBulkActionsTest"
"type" => "->"
]
15 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest/src/Factories/TestCaseFactory.php(169) : eval()'d code"
"line" => 20
"function" => "__runTest"
"class" => "P\Tests\Browser\AdminDashboardBulkActionsTest"
"type" => "->"
]
16 => array:5 [
"file" => "/var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php"
"line" => 1316
"function" => "__pest_evaluable__admin_dashboard_bulk_actions__→_apply_an_action_to_an_application"
"class" => "P\Tests\Browser\AdminDashboardBulkActionsTest"
"type" => "->"
]
17 => array:5 [
"file" => "/var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php"
"line" => 516
"function" => "runTest"
"class" => "PHPUnit\Framework\TestCase"
"type" => "->"
]
18 => array:5 [
"file" => "/var/www/html/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php"
"line" => 99
"function" => "runBare"
"class" => "PHPUnit\Framework\TestCase"
"type" => "->"
]
19 => array:5 [
"file" => "/var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php"
"line" => 357
"function" => "run"
"class" => "PHPUnit\Framework\TestRunner"
"type" => "->"
]
20 => array:5 [
"file" => "/var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php"
"line" => 374
"function" => "run"
"class" => "PHPUnit\Framework\TestCase"
"type" => "->"
]
21 => array:5 [
"file" => "/var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php"
"line" => 374
"function" => "run"
"class" => "PHPUnit\Framework\TestSuite"
"type" => "->"
]
22 => array:5 [
"file" => "/var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php"
"line" => 374
"function" => "run"
"class" => "PHPUnit\Framework\TestSuite"
"type" => "->"
]
23 => array:5 [
"file" => "/var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php"
"line" => 374
"function" => "run"
"class" => "PHPUnit\Framework\TestSuite"
"type" => "->"
]
24 => array:5 [
"file" => "/var/www/html/vendor/phpunit/phpunit/src/TextUI/TestRunner.php"
"line" => 64
"function" => "run"
"class" => "PHPUnit\Framework\TestSuite"
"type" => "->"
]
25 => array:5 [
"file" => "/var/www/html/vendor/phpunit/phpunit/src/TextUI/Application.php"
"line" => 229
"function" => "run"
"class" => "PHPUnit\TextUI\TestRunner"
"type" => "->"
]
26 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest/src/Kernel.php"
"line" => 103
"function" => "run"
"class" => "PHPUnit\TextUI\Application"
"type" => "->"
]
27 => array:5 [
"file" => "/var/www/html/vendor/pestphp/pest/bin/pest"
"line" => 184
"function" => "handle"
"class" => "Pest\Kernel"
"type" => "->"
]
28 => array:3 [
"file" => "/var/www/html/vendor/pestphp/pest/bin/pest"
"line" => 192
"function" => "{closure}"
]
29 => array:3 [
"file" => "/var/www/html/vendor/bin/pest"
"line" => 119
"function" => "include"
]
]
#comparisonFailure: null
trace: {
/var/www/html/vendor/pestphp/pest-plugin-browser/src/Playwright/Client.php:101 { …}
Pest\Browser\Playwright\Client->execute() {}
/var/www/html/vendor/pestphp/pest-plugin-browser/src/Playwright/Concerns/InteractsWithPlaywright.php:105 { …}
/var/www/html/vendor/pestphp/pest-plugin-browser/src/Playwright/Locator.php:137 { …}
/var/www/html/vendor/pestphp/pest-plugin-browser/src/Api/Concerns/InteractsWithElements.php:169 { …}
/var/www/html/vendor/pestphp/pest-plugin-browser/src/Api/AwaitableWebpage.php:55 { …}
/var/www/html/vendor/pestphp/pest-plugin-browser/src/Playwright/Playwright.php:196 { …}
/var/www/html/vendor/pestphp/pest-plugin-browser/src/Execution.php:149 { …}
/var/www/html/vendor/pestphp/pest-plugin-browser/src/Api/AwaitableWebpage.php:53 { …}
/var/www/html/tests/Browser/AdminDashboardBulkActionsTest.php:71 {
P\Tests\Browser\AdminDashboardBulkActionsTest->{closure}^
› ->click('Current stage')\r
› ->press('.action.reinstate')\r
› ->assertSeeIn('.tab-pane h2', 'Application Review');\r
arguments: {
$name: "press"
$arguments: array:1 [ …1]
}
}
/var/www/html/vendor/pestphp/pest/src/Factories/TestCaseMethodFactory.php:168 { …}
P\Tests\Browser\AdminDashboardBulkActionsTest->Pest\Factories\{closure}() {}
/var/www/html/vendor/pestphp/pest/src/Concerns/Testable.php:429 { …}
/var/www/html/vendor/pestphp/pest/src/Support/ExceptionTrace.php:26 { …}
/var/www/html/vendor/pestphp/pest/src/Concerns/Testable.php:429 { …}
/var/www/html/vendor/pestphp/pest/src/Concerns/Testable.php:331 { …}
/var/www/html/vendor/pestphp/pest/src/Factories/TestCaseFactory.php:169 { …}
/var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php:1316 { …}
/var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php:516 { …}
/var/www/html/vendor/phpunit/phpunit/src/Framework/TestRunner/TestRunner.php:99 { …}
/var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php:357 { …}
/var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php:374 { …}
/var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php:374 { …}
/var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php:374 { …}
/var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php:374 { …}
/var/www/html/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:64 { …}
/var/www/html/vendor/phpunit/phpunit/src/TextUI/Application.php:229 { …}
/var/www/html/vendor/pestphp/pest/src/Kernel.php:103 { …}
/var/www/html/vendor/pestphp/pest/bin/pest:184 { …}
/var/www/html/vendor/pestphp/pest/bin/pest:192 { …}
/var/www/html/vendor/bin/pest:119 { …}
}
} // vendor/pestphp/pest-plugin-browser/src/Execution.php:152
How to Reproduce
Checkout https://github.com/mattford/pest-repro composer/npm install Run vendor/bin/pest
Sample Repository
No response
Pest Version
4.1.0
PHP Version
8.4.12
Operation System
Linux
Notes
I am using WSL2 to execute Pest, same occurs within the php8.4-cli docker image
I'm seeing the same thing. The following page is loaded correctly, but it's still hanging on the previous click.
FAILED Tests\Feature\BrowserTest > it verifies login and logout
Timeout 5000ms exceeded. A screenshot of the page has been saved to [Tests/Browser/Screenshots/it_verifies_login_and_logout].
at tests/Feature/BrowserTest.php:20
16▕ ->submit()
17▕ ->type('passwd', 'password')
18▕ ->submit()
19▕ ->check('DontShowAgain')
➜ 20▕ ->click('No')
I am also getting this same error.
Even if I increase the timeout to 60 seconds it still just times out. While watching with the network open I am not seeing any network requests or console errors, it seems like the full page loads successfully.
This is a flakey error though, as sometimes the test passes, and other times it fails with the timeout across Chrome, Safari, and Firefox.
It does seem to be related to using the sync queue driver in tests. If I fake the queue, and then perform the queue work outside of the visit, it does seem to pass more reliably.
Queue::assertPushed(function(UpgradeUser $upgrade_user) {
$upgrade_user->handle();
return true;
});
$user = $this->user->fresh();
$this->assertNotEquals('guest', $user->role);
I've been running into the same thing. I've just PR'd an --attempts api that will reattempt failed tests before marking them as failed. Definitely not fixing the root cause but this would solve most of my pains
https://github.com/pestphp/pest/pull/1558
We are experiencing the same issue. Adding an extra assertSee before the click has seemed to make the occurrence of the issue drop
This is related to https://github.com/microsoft/playwright/issues/36181 which won't be fixed. The timeout just needs to be big enough to allow full loading. Except that Pest\Browser\Execution::waitForExpectation has a hard coded timeout of 1 second (1_000 milliseconds). I don't see any reason to run click through this method anyway?
public function waitForExpectation(callable $callback): mixed
{
$timeout = Playwright::timeout();
$originalCount = Assert::getCount();
$start = microtime(true);
$end = $start + ($timeout / 1_000);
while (microtime(true) < $end) {
try {
return Playwright::usingTimeout(1_000, $callback);
} catch (ExpectationFailedException) {
//
}
$this->resetAssertions($originalCount);
self::instance()->tick();
}
return $callback();
}
I have the same issue.
it('may not login', function () {
$page = visit('http://localhost/login');
$page->assertUrlIs('http://localhost/login')
->assertSee('Connexion')
->fill('username', 'user.name')
->fill('password', 'PasWord123!')
->press('Se connecter')
->assertSee('Invalid credentials');
});
And I got the error :
Execution context was destroyed, most likely because of a navigation
I am getting this same issue. Im submitting a form, and then looking for a success message. In the screenshot I see the success message but it hangs and fails on the click even though the click went through successfully.