I'm experience an issue which seems similar to #1846552: Login doesn't seem work properly due to bug in Goutte but a little different. I tried the suggestions on comments #5 and #7 of that issue and that didn't resolve it for me. Here is output of my behat run:

Feature: Authentication
  In order to make sure Behaviour testing is working
  As a behat test user
  I want to make sure I can log in

  Scenario: Anonymous access   
    Given I am on the homepage 
    Then I should see "Login"  

  @api
  Scenario: Log in as an admin                                   
    Given I am logged in as a user with the "administrator" role 
    Then I should not see "Login"                                
      The text "Login" appears in the text of this page, but it should not.

  @api
  Scenario: Log in as a regular user                                  
    Given I am logged in as a user with the "authenticated user" role 
      Failed to log in as user '6BN7RdfK' with role 'authenticated user'
    Then I should not see "Login"                                     

  @api @javascript
  Scenario: Log in via selenium                                       
    Given I am logged in as a user with the "administrator" role      
    Then I should not see "Login"                                     

4 scenarios (2 passed, 2 failed)
8 steps (5 passed, 1 skipped, 2 failed)

The 1st and the 4th scenarios pass as expected. The 2nd and 3rd fail but should not. Identified issues:

  • The difference between 2 and 4 (just the @javascript) suggest there could be a problem with the goutte driver as in the #1846552 issue.
  • The difference between 2 and 3 is also puzzling. I have tried authenticating with other roles and only "administrator" works. If the role is a typo it fails saying role doesn't exist, so how is it that it can find the role and fail to log in?
  • Scenario 2 appears to log in but still finds "Login" text, which contradict with sc1 and sc4.

Not sure if this is a bug or a support request. I feel like I'm understanding enough of the behat system now to say this is a bug, and it appears to be different from others in the issue queue. I could be missing something so suggestions very welcome.

Comments

daven’s picture

I should add that my workaround for these issues is to use @javascript and run all tests with roles through selenium. Not my preference but a workable situation.

eliza411’s picture

Status: Active » Postponed (maintainer needs more info)

HI Daven,

I'll need more information to look into this.

Scenario 2:
What are you seeing on the page, either when you follow the steps with a text-based browser (like lynx or elinks) or by using the "Then print last response" step?

Scenario 3:
What version of Drupal are you running these against?

daven’s picture

I'm running this on Drupal Commons 7.x-3.2. If I have time this week, I'll try on a plain Drupal 7 to see if i have different results.

As for scenario 2, when I do it manually and log as as an administrator, I search for Login in the source and it is not there. I just tried the print last response step and it's showing lots of errors, which i don't see when I log in manually. One of them is this:
<a href="http://drupal.org/project/issues/r4032login?version=7.x">Redirect 403 to User Login issue queue</a>
So that explains why it's failing and it found other unrelated issues for me. :(
Thanks for the 'print last response' idea.

Scenario 3 is still a mystery though. Perhaps trying it on a fresh Drupal7 and comparing I'll find something.

christophernies’s picture

I am seeing something similar as well on a local installation of Drupal 7.23.

When I run this test:

@api
Scenario: Creating a course as a course admin # features/Creating a course and chaging settings.feature:5
Given I am logged in as a user with the "course admin" role # FeatureContext::assertAuthenticatedByRole()
Failed to log in as user 'iYQleZrK' with role 'course admin'
And I create a course # FeatureContext::iCreateACourse()
And I set the course's start date to "Nov 9 2013" # FeatureContext::iSetTheCourseSStartDateTo()
And I set the course's end date to "Nov 11 2013" # FeatureContext::iSetTheCourseSEndDateTo()
When I edit the course # FeatureContext::iEditTheCourse()
Then print last response # FeatureContext::printLastResponse()
And I click "node_course_form_group_location" # FeatureContext::assertClick()
Then print last response # FeatureContext::printLastResponse()
Then I should see "Nov 9 2013" # FeatureContext::assertPageContainsText()

I AM successfully logged in (I see it in the Firefox window), but the test is still saying I'm not logged in (see above.

My behat.yml looks like this:

default:
extensions:
Behat\MinkExtension\Extension:
base_url: 'http://localhost/app/'
default_session: selenium2
browser_name: 'firefox'
selenium2:
capabilities: { "browser": "firefox", "version": "14"}
Drupal\DrupalExtension\Extension:
blackbox: ~
drush:
root: /Users/cnies/Sites/app/
text:
log_out: "Sign out"
log_in: "Log in"

EDIT: Turns out the problem is that log_out in my behat.yml should have said "Log out" instead of "Sign out" because DrupalExtension determines if you're logged in by the presence of the log_out text.

VenDG’s picture

Running Drupal 7.23

Trying the drush test from http://dspeak.com/drupalextension/drush.html. The first test should fail while the second should pass.

I am using selenium and can see the user login and view their history in the Firefox browser window but the terminal reports that the second scenario fails.

Feature: Drush test
  In order to demonstrate the Drush driver
  As a trainer
  I need to show how to tag scenarios

  Scenario: Untagged scenario uses blackbox driver and fails          # features \drupalcontext.feature:10
    Given I am logged in as a user with the "authenticated user" role # FeatureContext::assertAuthenticatedByRole()
      No ability to create users in Drupal\Driver\BlackboxDriver. Put `@api` into your feature and add an api driver (ex: `api_driver: drupal`) in behat.yml.
    When I click "My account"                                         # FeatureContext::assertClick()
    Then I should see the heading "History"                           # FeatureContext::assertHeading()

  @api @javascript
  Scenario: Tagged scenario uses Drush driver and succeeds            # features \drupalcontext.feature:16
    Given I am logged in as a user with the "authenticated user" role # FeatureContext::assertAuthenticatedByRole()
      Failed to log in as user 'pTcosn6u' with role 'authenticated user'
    When I click "My account"                                         # FeatureContext::assertClick()
    Then I should see the heading "History"                           # FeatureContext::assertHeading()

2 scenarios (2 failed)
6 steps (4 skipped, 2 failed)

This is behat.yml

# behat.yml
default:
  paths:
    features: 'features'
  extensions:
    Behat\MinkExtension\Extension:
      goutte: ~
      selenium2: ~
      base_url: http://localhost/demosite
    Drupal\DrupalExtension\Extension:
      blackbox: ~
      api_driver: "drush"
      drush:
        root: "c:/intranet/htdocs/demosite"
      text:
        log_out: "Log out"
        log_in: "Log in"
      region_map:
        footer: "#footer"
        content: "#content"
        header: "#header"
manumilou’s picture

As christophernies said, drupalextension looks for the log_out text in the page to determine if the user is logged in. So you should check if the log_out string in your behat.yml is properly set.

VenDG’s picture

This is the html code for the log out link after a user is logged in:

<li class="menu-15 last">
<a href="/Demosite/user/logout">Log out</a>
</li>

Unless I am supposed to be putting something other than the text between the opening and closing a tags, into log_out, I believe I do have the correct information in the string.

grasmash’s picture

Status: Postponed (maintainer needs more info) » Active

I'm experiencing a similar issue.

Essentially, the loggedIn() assertion fails when using Selenium2, but works when using Goutte for the exact same scenario.

Adding a simple line to debug loggedIn() reveals that the "Log out" link is not being found in the markup when the Selenium2 session driver is used:

  /**
   * Determine if the a user is already logged in.
   */
  public function loggedIn() {
    $session = $this->getSession();
    $session->visit($this->locatePath('/'));

    // If a logout link is found, we are logged in. While not perfect, this is
    // how Drupal SimpleTests currently work as well.
    $element = $session->getPage();

    print_r($element->getHtml());

    return $element->findLink($this->getDrupalText('log_out'));
  }

However, simply changing the session driver to "Goutte" actually changes the markup that is output by the debugging statement. The "Log out" link is in the markup when using Goutte.

Here's another twist. Given that I'm using Selenium2 locally, I can actually see the scenario as it is tested, and I can see the "Log out" link rendered in the browser, despite the fact that getHtml() does not contain the markup. It's odd that Behat would be unable to see the markup via loggedIn(), but I am able to see the markup in the browser when the scenario is run.

Some background: I am using admin_menu to output the login link.

grasmash’s picture

Well, I solved my issue. If you're using admin_menu, take note that when JS is enabled, admin_menu will render the menu via JS. For selenium2, this may not happen in time for the loggedIn() assertion to return TRUE. One solution is to set the admin_menu_cache_client variable to FALSE.

VenDG’s picture

I did what grasmash did to get the HTML and can confirm that the HTML is different from what I see in the selenium browser window. The menu that has the link to 'my account' and 'log out' is not rendered in the HTML.
This happens when testing with just goutte and also with selenium. I am not using admin menu.

Update:
I have tested several themes. The main menu is rendered in the HTML, the secondary menu is not rendered in the HTML.

djdevin’s picture

I had the very same issue but only when running selenium2 (specifically over saucelabs). Users would get created but the login routine would fail. The problem was the browser used, I changed it from FF 20 something to 31 and all is magically working now. So for anyone else with this problem it could also be an issue with the connection between selenium server and Firefox.

Vanille’s picture

I have the issue regardless of which version of FF I use. What about changing this step definition to something more robust? Seems like a bad decision to make the step depend on whether the log out link is visible or not.

cboyden’s picture

A few possibilities:

  1. Check for the logged-in body class. This will fail if the theme does not render body classes.
  2. Use the Drupal API to check if the user is logged in. See https://api.drupal.org/api/drupal/modules!user!user.module/function/user.... Or check for an active session ID for the specified user by running a user_load: https://api.drupal.org/api/drupal/modules!user!user.module/function/user.... Either might work OK for cases where you're using the Drupal API, but not the drush API. Unfortunately since the "Given I am logged in..." step only requires the drush API, this is not enough.
  3. drush? I don't see an existing drush function that checks if a user is logged in. It might be possible to write one based on user_load.
tanc’s picture

Just encountered a similar issue where checking for the log_out link was failing on a development site in goutte. The link was not available anywhere on the page so the loggedIn method was failing to assert the link existed. As cboyden suggests, it would be good to have a more robust method of checking if the user is logged in. Eventually a log out link would be displayed somewhere on this development sites home page I imagine but whilst building it out we still need to run tests that check if the user is logged in, or more accurately run tests as authenticated users.

YesCT’s picture

Here is my behat.tml

default:
  paths:
    features: 'features'
  extensions:
    Behat\MinkExtension\Extension:
      goutte: ~
      selenium2: ~
      base_url: http://live-mysite.gotpantheon.com/
    Drupal\DrupalExtension\Extension:
      blackbox: ~
      api_driver: 'drush'
      drush:
        alias: 'pantheon.mysite.live'

and this feature:

Feature: Member Navigation
 In order to navigate the site
  As a website member
  I need to be able to see all the members-only links

  @api
  Scenario: See a link
    Given I am logged in as a user with the "authenticated user" role
    And I go to "/members"
    Then I should see "Members"

The bit after the given is not important, because the given is what errors out.

with behat -v ...
behat -v features/UserRole.feature

where UserRole.feature is:

Feature: Member Navigation
  In order to navigate the site
  As a website member
  I need to be able to see all the members-only links

  @api
  Scenario: See a link                                                # features/UserRole.feature:7
    Given I am logged in as a user with the "authenticated user" role # FeatureContext::assertAuthenticatedByRole()
      exception 'RuntimeException' in vendor/drupal/drupal-extension/src/Drupal/Driver/DrushDriver.php:167
      Stack trace:
      #0 vendor/drupal/drupal-extension/src/Drupal/Driver/DrushDriver.php(93): Drupal\Driver\DrushDriver->drush('user-create', Array, Array)
      #1 vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/DrupalContext.php(846): Drupal\Driver\DrushDriver->userCreate(Object(stdClass))
      #2 [internal function]: Drupal\DrupalExtension\Context\DrupalContext->assertAuthenticatedByRole('authenticated u...')
      #3 vendor/behat/behat/src/Behat/Behat/Definition/Annotation/Definition.php(155): call_user_func_array(Array, Array)
      #4 vendor/behat/behat/src/Behat/Behat/Tester/StepTester.php(157): Behat\Behat\Definition\Annotation\Definition->run(Object(FeatureContext))
      #5 vendor/behat/behat/src/Behat/Behat/Tester/StepTester.php(126): Behat\Behat\Tester\StepTester->executeStepDefinition(Object(Behat\Gherkin\Node\StepNode), Object(Behat\Behat\Definition\Annotation\Given))
      #6 vendor/behat/behat/src/Behat/Behat/Tester/StepTester.php(95): Behat\Behat\Tester\StepTester->executeStep(Object(Behat\Gherkin\Node\StepNode))
      #7 vendor/behat/gherkin/src/Behat/Gherkin/Node/AbstractNode.php(42): Behat\Behat\Tester\StepTester->visit(Object(Behat\Gherkin\Node\StepNode))
      #8 vendor/behat/behat/src/Behat/Behat/Tester/ScenarioTester.php(148): Behat\Gherkin\Node\AbstractNode->accept(Object(Behat\Behat\Tester\StepTester))
      #9 vendor/behat/behat/src/Behat/Behat/Tester/ScenarioTester.php(87): Behat\Behat\Tester\ScenarioTester->visitStep(Object(Behat\Gherkin\Node\StepNode), Object(Behat\Gherkin\Node\ScenarioNode), Object(FeatureContext), Array, false)
      #10 vendor/behat/gherkin/src/Behat/Gherkin/Node/AbstractNode.php(42): Behat\Behat\Tester\ScenarioTester->visit(Object(Behat\Gherkin\Node\ScenarioNode))
      #11 vendor/behat/behat/src/Behat/Behat/Tester/FeatureTester.php(88): Behat\Gherkin\Node\AbstractNode->accept(Object(Behat\Behat\Tester\ScenarioTester))
      #12 vendor/behat/gherkin/src/Behat/Gherkin/Node/AbstractNode.php(42): Behat\Behat\Tester\FeatureTester->visit(Object(Behat\Gherkin\Node\FeatureNode))
      #13 vendor/behat/behat/src/Behat/Behat/Console/Command/BehatCommand.php(150): Behat\Gherkin\Node\AbstractNode->accept(Object(Behat\Behat\Tester\FeatureTester))
      #14 vendor/behat/behat/src/Behat/Behat/Console/Command/BehatCommand.php(128): Behat\Behat\Console\Command\BehatCommand->runFeatures(Object(Behat\Gherkin\Gherkin))
      #15 vendor/symfony/console/Symfony/Component/Console/Command/Command.php(252): Behat\Behat\Console\Command\BehatCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      #16 vendor/symfony/console/Symfony/Component/Console/Application.php(889): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      #17 vendor/symfony/console/Symfony/Component/Console/Application.php(193): Symfony\Component\Console\Application->doRunCommand(Object(Behat\Behat\Console\Command\BehatCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      #18 vendor/behat/behat/src/Behat/Behat/Console/BehatApplication.php(68): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      #19 vendor/symfony/console/Symfony/Component/Console/Application.php(124): Behat\Behat\Console\BehatApplication->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      #20 vendor/behat/behat/bin/behat(32): Symfony\Component\Console\Application->run()
      #21 {main}

I'm not sure how to get this to work with drupal 7 (or if it is a pantheon problem).

It works ok on a d6 site.

jhedstrom’s picture

Looking into where that exception is thrown, this appears to be an issue with running the actual Drush command against the site. Are you able to manually run drush commands against the d7 site?

jhedstrom’s picture

Turns out pantheon requires --strict=0 for Drush 6 and beyond. See https://github.com/jhedstrom/drupalextension/issues/88

nielsonm’s picture

@daven: You still having this issue? If not can we mark this issue as fixed?

Thanks,
Mike

daven’s picture

Status: Active » Fixed

I am no longer having this issue. Thanks all for the valuable comments!

YesCT’s picture

the strict option was my problem. To get it working, I had to remove the extention and then run composer install to get it to recognize the new fix. Also, I had to make an additional entry in the behat.yml for:
global_options: '--strict=0'
under the drush alias (as it mentions in the github issue)

thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

zuernBernhard’s picture

Status: Closed (fixed) » Needs review

I have a quite similar issue here. But i use local drupalapi-driver and not drush. In the feature I have

Given I am logged in as a user with the "authenticated user" role

In my custom module I implement hook_node_access and have a var_dump like this:

var_dump($account->roles);

The output (by running behat) offers:

array(1) {
│ [1] =>
│ string(14) "anonymous user"
│ }

jhedstrom’s picture

Status: Needs review » Closed (duplicate)

There's an open pull request to improve how this works. If somebody can take that up (tests are failing, some changes are needed) we can get this in.

https://github.com/jhedstrom/drupalextension/pull/131

andyg5000’s picture

I had this issue because Warning: strtotime(): It is not safe to rely on the system's timezone settings. on the CI server. Setting the timezone obviously fixes this :)

Moral of the story is, make sure other unrelated warnings are not being thrown that will trip up behat.