drupalextension
drupalextension copied to clipboard
Big pipe compatibility follow-up
#259 doesn't test messages for authenticated users. This follow-up PR should prove that messages work only for anonymous users.
In next commits to branch I will suggest how can we fix it (based on workaround proposed here: https://github.com/jhedstrom/drupalextension/issues/258#issuecomment-193357483)
The command "vendor/bin/behat -fprogress --strict" exited with 1.
103.19s$ vendor/bin/behat -fprogress --profile=drupal${DRUPAL_VERSION} --strict
...................................................................... 70
...................................................................... 140
...................................................................... 210
.............F.....F
--- Failed steps:
Then I should see the message "The configuration options have been saved." # features/messages.feature:27
The page 'http://127.0.0.1:8888/admin/config/development/maintenance?q=admin/config/development/maintenance' does not contain any messages (Exception)
Then I should see the message "The configuration options have been saved." # features/messages.feature:36
The page 'http://127.0.0.1:8888/admin/config/development/maintenance?q=admin/config/development/maintenance' does not contain any messages (Exception)
44 scenarios (42 passed, 2 failed)
230 steps (228 passed, 2 failed)
1m42.51s (94.91Mb)
The command "vendor/bin/behat -fprogress --profile=drupal${DRUPAL_VERSION} --strict" exited with 1.
0.00s$ test ${DRUPAL_VERSION} -ne 7 || vendor/bin/behat -fprogress --profile=drush --strict
Extra test scenarios proved DrupalExtension doesn't work well for Authenticated user and BigPipe enabled.
In next commit I will suggest how can we fix it.
The command "vendor/bin/behat -fprogress --strict" exited with 1.
92.04s$ vendor/bin/behat -fprogress --profile=drupal${DRUPAL_VERSION} --strict
...................................................................... 70
...................................................................... 140
...................................................................... 210
..................F
--- Failed steps:
Then I should see the message "The configuration options have been saved." # features/messages.feature:35
The page 'http://127.0.0.1:8888/admin/config/development/maintenance?q=admin/config/development/maintenance' does not contain any messages (Exception)
44 scenarios (43 passed, 1 failed)
229 steps (228 passed, 1 failed)
1m31.47s (95.28Mb)
As you can see first failing step (Non-JS messages for authenticated
) has been fixed.
In the same time extra scenarios have revealed that [email protected] doesn't work well with BigPipe. I tested that scenario locally with PhantomJS and it works perfect. Did you consider switching from zombiejs to phantomjs?
I copied the BigPipeContext
into my project and it solved my woes. My project also uses PhantomJS vs zombiejs
Sorry for the long delay in getting to this. It looks like a great start! It needs to be rebased/merged with the latest master
, and from the looks of it, there were some JS failures too. Thanks for working on this!
Is there no official way to check if a driver supports JS or not?
Using a try/catch for that is not exactly a clean way. Also wondering if this really should be an optional context, everyone will have to figure out then that this exists and add it to this project, should at least be documented then somehere.
I'll also ping Wim Leers about this.
Is there no official way to check if a driver supports JS or not?
From what I can tell, no. The JS drivers don't implement any additional interfaces or anything to differentiate themselves from the non-JS drivers...
That's pretty unfortunate then, in my project I could obviously just check the actual driver class since I know what it is.
Could we maybe somehow store this on a property or so so we don't have to throw and catch an exception for every single scenario? I guess it won't make a measurable difference
The thing is that big pipe should be compatible with non-JS clients by redirecting them through a meta tag and then sets that cookie itself IIRC. But it looks like the driver doesn't support that.
Is there no official way to check if a driver supports JS or not?
That'd be great!
But I think catching UnsupportedDriverActionException
and then setting the no-JS cookie is a pretty clever hack.
The thing is that big pipe should be compatible with non-JS clients by redirecting them through a meta tag and then sets that cookie itself IIRC. But it looks like the driver doesn't support that.
Correct. But if the driver doesn't support that, then it's violating one of the foundational features of web browsers: it doesn't respect <noscript><meta http-equiv="Refresh" content="0; URL=http://example.com/somewhere"></noscript>
. Which means that this driver doesn't support graceful degradation for non-JS clients. Which sounds like a huge oversight.
Finally: when does Behat run the assertions? Does it wait for the load
event to complete? I'm asking because otherwise tests using BigPipe could run into random failures depending on how fast the server responded, and depending on how fast the JS was executed.
I've merged the latest master
for this over in #445.
I opened https://github.com/FriendsOfPHP/Goutte/issues/329 for the Goutte browser.
In local testing, it would appear that the attempt to just set the cookie in a @BeforeScenario
hook won't work, since when a user logs in, they get a new session that loses this cookie for some reason.
We are definitely experiencing this a lot recently:
Finally: when does Behat run the assertions? Does it wait for the load event to complete? I'm asking because otherwise tests using BigPipe could run into random failures depending on how fast the server responded, and depending on how fast the JS was executed.
After applying the patch it solved a pretty mean issue for me. https://github.com/jhedstrom/drupalextension/issues/258#issuecomment-448001156
Previously this didn't seem to resolve the issue (see my comments above regarding losing cookies on login), but if it's working for others, and we can get the tests passing, I'm all for this workaround until the fix in browserkit above makes its way into Mink, etc.
Worth mentioning the patch results in an exception to be thrown on @api
tagged scenarios when the BigPipe module is not enabled.
┌─ @BeforeScenario # Drupal\DrupalExtension\Context\BigPipeContext::prepareBigPipeNoJsCookie()
│
╳ Fatal error: Class 'Drupal\big_pipe\Render\Placeholder\BigPipeStrategy' not found (Behat\Testwork\Call\Exception\FatalThrowableError)
I'm actually quite surprised by that behavior. How smart this extension is that it won't load the class of a disabled module?!
After re-enabling BigPipe it works just fine again.
Thanks for this example @Berdir
On my side, using v4.0.1 and v4.1.0 it didn't work with a BeforeScenario
.
I have overridden the login
method and set the cookie there, which seems to work for now.
@vever001 can you post how you overrode the login
method?
Sure, this is the context I added to the behat.yml
in default.suites.default.contexts
section:
<?php
declare(strict_types = 1);
namespace Drupal\Tests\my_namespace\Behat;
use Behat\Mink\Exception\UnsupportedDriverActionException;
use Drupal\big_pipe\Render\Placeholder\BigPipeStrategy;
use Drupal\DrupalExtension\Context\DrupalContext as DrupalExtensionDrupalContext;
/**
* Provides step definitions for interacting with Drupal.
*/
class DrupalContext extends DrupalExtensionDrupalContext {
/**
* {@inheritdoc}
*/
public function login(\stdClass $user) {
parent::login($user);
$this->disableBigPipe();
}
/**
* Disables Big Pipe.
*
* Workaround for issue with drupalextension and big_pipe.
* See https://github.com/jhedstrom/drupalextension/issues/258
*/
protected function disableBigPipe() {
try {
// Check if JavaScript can be executed by Driver.
$this->getSession()->getDriver()->executeScript('true');
}
catch (UnsupportedDriverActionException $e) {
// Set NOJS cookie.
$this
->getSession()
->setCookie(BigPipeStrategy::NOJS_COOKIE, TRUE);
}
catch (\Exception $e) {
// Mute exceptions.
}
}
}
@vever001 thanks, it's working!
Hello,
Edit:
- drupal/drupal-extension: 4.1.0
- drupal/core-recommended: 9.1.5
- drupal/core-dev: 9.1.5
I am writting (my almost first) Behat tests on a comment form for anonymous users and I wanted to test that after submitting the form, the approbation message is displayed and the admin receives an email.
So I encountered this issue.
I have not tested the code of this PR yet.
https://github.com/jhedstrom/drupalextension/pull/325#issuecomment-799804471 is not working for me because in my case, I am with an anonymous user. So I guess the @BeforeScenario
of the conext in the PR will be better.
And I have another problem, if I write a context in a module, either in src
or tests/src
with proper namespace then referencing it in my behat.yml, the context is not detected. Is there something special to do?
I find out that for example Search API has a search_api.behat.inc file but I would really like to avoid .inc files. And no problem for a custom context inside a features/bootstrap
folder from wher the behat.yml file is located.
I can't find anything about that in the documentation.
Thanks for any help.
Hello,
I add manually tested the new context. It fixed my usage. Thanks!
Waiting for the PR to be merged when possible.