jhedstrom / drupalextension

An integration layer between Behat, Mink Extension, and Drupal.
GNU General Public License v2.0
209 stars 192 forks source link

Accessing drupal/module functions in @beforefeature possible? #219

Open natgateway opened 9 years ago

natgateway commented 9 years ago

Hi, I was wondering if it was possible to access drupal API & module functions from the @beforeFeature hook. I have a CustomDrupalContext.php file that extends DrupalContex but can't seem to run functions from it in a beforeFeature static function. I'm trying to get some data from my drupal installation (I need to test some dynamic items) to set up a scenario outline. Since I'm new to Behat and the Drupal Behat exension, it's not clear to me if there's a way around this that I'm missing, or if it's not possible with the methods available for $scope. $environment->getContext doesn't seem to be available in the UninitializedContextEnvironment so I can't cross reference contexts in that hook. I had seen some documentation in behat 2.5 for using "getContextParameters()" in a beforeFeature hook, but don't know what the equivalent would be for version 3.

jhedstrom commented 9 years ago

A scope object (in the case of before hooks, Behat\Behat\Hook\Scope\BeforeFeatureScope) is passed into any hook methods. You can call ::getEnvironment() on that which should return details on any active contexts being used.

natgateway commented 9 years ago

Hi, thanks for answering,you provided me a clue on how to get to that context. I don't have a lot of background knowledge, so I'm still having a difficult time figuring out what to do. Whenever I try to use a function/method from the context I'm trying to reference in the @beforeFeature hook, I get a " "Call to a member function myFunction() on a non-object"

$scope->getEnvironment()->getContextClassesWithArguments() gives me the following:

│ Array │ ( │ [OGFeatureContext] => Array │ ( │ ) │
│ [CustomDrupalContext] => Array │ ( │ ) │
│ [Drupal\DrupalExtension\Context\MinkContext] => Array │ ( │ ) │
│ [Drupal\DrupalExtension\Context\MessageContext] => Array │ ( │ ) │
│ [Drupal\DrupalExtension\Context\DrushContext] => Array │ ( │ ) │
│ )

This is what I used to reference the context: /* @var bfCustomDrupalContext / private $bfCustomDrupalContext;

/** @BeforeFeature */
public static function preFeatureContexts(BeforeFeatureScope $scope)
{
    $envcon = $scope->getEnvironment()->getContextClassesWithArguments();
    $scope->bfCustomDrupalContext = $envcon['CustomDrupalContext'];
    }

And later in another function I tried using a function/method (we'll call it myFunction) in the CustomDrupalContext with:

$ogbypasstypes = $bfCustomDrupalContext->myFunction();

and I got the following error: "Call to a member function getOgBypassContentTypes() on a non-object"

That function pulls an array with data on certain content types. I'm not sure how to get this working in the @beforeFeature stage. I'm hoping to create an exampleTablenode in this hook with data from that function. It's turning out to be a bit ambitious for a newbie like me :)

jhedstrom commented 9 years ago

I think perhaps you need to call

$scope->getEnvironment()->getContext('CustomDrupalContext')

instead of the other method above. See the gatherContexts function in these docs for an example.

natgateway commented 9 years ago

Hi Jhedstrom, I'm sorry, I guess I didn't make it clear that the getContext method was not working when used with the the @beforeFeature hook (not beforeScenario), and I was wondering if someone knew of a workaround. I get the following error when I use "$scope->getEnvironment()->getContext('CustomDrupalContext')" in the beforeFeature hook:

PHP Fatal error: Call to undefined method Behat\Behat\Context\Environment\UninitializedContextEnvironment::getContext()

This works in beforeScenario hook, but not in beforeFeature hook which is where I'd like to call some of my module functions earlier up in the event chain to gather data to use to set up some of the tests.

The uninitialized environment does have the getContextClassesWithArguments() method, I tried to use that instead of getContext() and it didn't give me error while setting up the context reference with, but when calling a method from 'CustomDrupalContext' I will get an error "Call to a member function myFunction() on a non-object" in the beforeFeature hook.

If would really help a great deal if I could access some data and function from my modules at the beforeFeature stage. But since the examples for cross referencing contexts don't seem to work for me in this case I'm wondering if I'm trying to do something that is not possible or if I'm not experienced enough to know what I'm doing wrong at this point.

aronbeal commented 8 years ago

Hey @natgateway,

Did you ever figure out a working solution to this for your tests? Out of curiosity, what are you trying to access that you need before the @beforeScenario hook runs?

natgateway commented 8 years ago

Hi @aronbeal ,

I was hoping to get a list of certain content types & nodes that meet specific criteria to create a background table node with. Our content types do change from time to time, and I was hoping to create a more dynamic behat test for content types that I didn't have to continuously update. We have other aspects of our site that are somewhat dynamic in nature and we use OG + workbench moderation heavily along with other custom modules that make testing with behat somewhat challenging. Add my newbie-ness to the mix and it makes for quite a fun time.

I was hoping to access some of the OG module's methods to get lists of content types, group content, group administrators and such, and custom permission sets for certain groups to populate some table node data.

Sadly it seems that I can't run any module methods in the @beforeFeature hook (my newbie guess is that drupal isn't bootstrapped at that point), which unless I am mistaken is where you'd have to generate the background table node if you wanted to do so programmatically, but I did eventually figure out that I can query the database in that hook to get the same data I was trying to use the OG methods to retrieve. Unfortunately I haven't had time to circle back to that, my boss has me working on other things for the immediate future.